Commerce order access checks in Views I realize this is quite a specific Drupal commerce question, but perhaps I can get some insights as I am stuck here.

I need to control access to commerce orders on a per-order basis based on an entity reference field. So users will not have access to view commerce orders, except if they are related to them.

My custom access check requires an operation, and entity and a user.

Looking at all the hooks Drupal commerce executes in order to determine access:


commerce_order_access() calls the generic access helper, commerce_entity_access() for view operations, this constructs an access query based on the entity, which relies on Database API invoking hook_query_TAG_alter(). For orders, this is hook_query_commerce_order_access_alter().
commerce order's implementation of this hook, commerce_order_query_commerce_order_access_alter(), calls a generic implementation back in commerce module, commerce_entity_access_query_alter().
commerce_entity_access_query_alter() checks entity type and user access permissions for the entity and builds an OR conditions array that you can alter for Orders using hook_commerce_entity_access_condition_commerce_order_alter().


All these functions however never get a specific entity to operate on and always check 'global' permissions with user_access().
The committed patch Pass entity to Commerce entity access check contexts changes this so the entity is added to the query metadata in commerce_entity_access() and as such can also be used in hook_commerce_entity_access_condition_commerce_order_alter().

So far so good, this works and I can check access to my order in hook_commerce_entity_access_condition_commerce_order_alter().

The real problem

The problem I run into occurs when loading the orders through Views; 

Views does not load the entity but just adds it to the select query and then performs the above access checks, starting with commerce_order_query_commerce_order_access_alter() (hook_query_TAG_alter()). This way the entity is not set (commerce_entity_access() is never called) and thus not available for access checking and all there is for me to alter is the query.

The thing I came up with

Actually the only thing I could think of was to load all commerce order entities, run them all through my access check and save the id's of the allowed orders. Then in hook_commerce_entity_access_condition_commerce_order_alter() add all these id's to the query in a condition. 
I am however afraid this will be a huge performance drop once there have been made some orders

So is there a way I can fetch entities from a Views select query? Or id's? Or do I need to implement my check elsewhere?
Your thing you came up with is certainly one way of doing it, though you're adding a step. If you can guarantee that your entity reference field will always be on the order, then you could just join your query to the entity reference table and check it against the current user's UID.

Something to the effect of:

INNER JOIN `field_order_user_reference` ON `commerce_order`.order_id = `field_order_user_reference`.entity_id 
...
WHERE
`field_order_user_reference`.user_id = ***CURRENT_USER***


Or something to that effect.

The way you have it implemented now, you will start to see performance degradation since you're adding a lot of overhead. Using pure SQL will help tremendously and you shouldn't see any slowdown.

Alternatively, since your order has an entity/user reference field attached to it, you should be able to just add it as a filter and set the filter user as the current one. Maybe not, but if you haven't tried it, it'd be worth a shot.