Проверка доступа к коммерческому заказу в представлениях
Я понимаю, что это довольно специфический вопрос о торговле на Drupal, но, возможно, я смогу получить некоторое представление, поскольку застрял здесь.
Мне нужно контролировать доступ к коммерческим заказам на основе каждого заказа на основе поля ссылки на сущность. Таким образом, пользователи не будут иметь доступа к просмотру коммерческих заказов, за исключением случаев, когда они связаны с ними.
Для моей пользовательской проверки доступа требуется операция, а также сущность и пользователь.
Глядя на все крючки, которые выполняет Drupal commerce для определения доступа:
commerce_order_access()
вызывает универсальный помощник по доступу,commerce_entity_access()
для операций просмотра это создает запрос доступа на основе сущности, который полагается на API базы данных, вызывающий функцию hook_query_TAG_alter(). Для заказов этоhook_query_commerce_order_access_alter()
.Реализация этого крючка в коммерческом заказе,
commerce_order_query_commerce_order_access_alter
(), вызывает общую реализацию обратно в модуле commerce,commerce_entity_access_query_alter()
.commerce_entity_access_query_alter()
проверяет сущность введите разрешения и права доступа пользователя для сущности и создайте массив условий ИЛИ, который можно изменить для заказов с помощьюhook_commerce_entity_access_condition_commerce_order_alter()
.
Однако все эти функции никогда не получают определенного объекта для работы и всегда проверяют "глобальные" разрешения с помощью user_access()
.
Исправленный патч Передает сущность в контексты проверки доступа к коммерческой сущности изменяет это, поэтому сущность добавляется в метаданные запроса в commerce_entity_access()
и как таковая также может использоваться в hook_commerce_entity_access_condition_commerce_order_alter()
.
Пока все так хорошо, это работает, и я могу проверить доступ к своему заказу в hook_commerce_entity_access_condition_commerce_order_alter()
.
Реальная проблема
Проблема, с которой я сталкиваюсь, возникает при загрузке заказов через представления;
Представления не загружают сущность, а просто добавляют ее в запрос select, а затем выполняют описанные выше проверки доступа, начиная с commerce_order_query_commerce_order_access_alter()
(hook_query_TAG_alter()
). Таким образом, сущность не задана (commerce_entity_access()
никогда не вызывается) и, следовательно, недоступна для проверки доступа, и все, что мне нужно изменить, - это запрос.
То, что я придумал с
На самом деле единственное, о чем я мог подумать, это загрузить все объекты коммерческих заказов, пропустить их все через мою проверку доступа и сохранить идентификаторы разрешенных заказов. Затем в hook_commerce_entity_access_condition_commerce_order_alter()
добавьте все эти идентификаторы в запрос в условии.
Однако я боюсь, что это приведет к огромному снижению производительности, как только будут сделаны некоторые заказы
Итак, есть ли способ извлечь сущности из запроса выбора представлений? Или удостоверения личности? Или мне нужно выполнить проверку в другом месте?
1 answers
Ваша вещь, которую вы придумали, безусловно, является одним из способов сделать это, хотя вы добавляете шаг. Если вы можете гарантировать, что ваше поле ссылки на сущность всегда будет в заказе, то вы можете просто присоединить свой запрос к таблице ссылок на сущности и сверить его с UID текущего пользователя.
Что-то вроде:
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***
Или что-то в этом роде.
То, как вы это реализовали сейчас, вы начнете видеть снижение производительности с тех пор, как вы добавляете много накладных расходов. Использование чистого SQL очень поможет, и вы не увидите никакого замедления.
В качестве альтернативы, поскольку к вашему заказу прикреплено поле ссылки на сущность/пользователя, вы должны иметь возможность просто добавить его в качестве фильтра и установить пользователя фильтра в качестве текущего. Может быть, и нет, но если вы еще не пробовали, то попробовать стоит.