Repository navigation
Классическая Fenom-витрина не учитывает группы ресурсов #670
Description
Проблема
Классическая витрина на Fenom не учитывает группы ресурсов MODX. Товар или категория, закрытые владельцем магазина штатными средствами платформы, выводятся сниппетом ms3_products анонимному посетителю наравне с публичными.
Это та же проблема, что описана в #659, но для другого слоя. #666 закрывает её для публичного Web API; сюда фикс не распространяется.
Почему фикс из #666 сюда не достаёт
core/components/minishop3/elements/snippets/ms3_products.php строит выборку через ModxPro\PdoTools\Fetch:
use ModxPro\PdoTools\Fetch;
...
$pdoFetch = $modx->services->get(Fetch::class);
...
$rows = $pdoFetch->run();То есть сырой SQL, собираемый pdoTools по конфигу, минуя ProductCatalogService и весь наш сервисный слой. Проверено грепом: ни один сниппет в elements/snippets/ не обращается ни к ProductCatalogService, ни к CatalogResourceGroupVisibility.
Нюанс, который делает задачу нетривиальной: pdoTools не хидратирует xPDO-объекты, а возвращает сырые строки. Значит унаследованная от modAccessibleObject проверка политики, которая срабатывает при обычном getObject()/getCollection(), здесь не отрабатывает тоже — ни на уровне SQL, ни на уровне PHP.
Почему это важнее, чем headless-часть
Сегодня подавляющее большинство магазинов на MiniShop3 — это обычные сайты на Fenom-шаблонах, а не headless-витрины на Web API. Получается, что после #666 дыра закрыта для сценария, который пока почти не встречается, и остаётся открытой в том, который используют реально все.
При этом владелец магазина, закрывший раздел средствами MODX, разумно считает, что закрыл его везде.
Что предстоит решить
- Куда встраивать фильтр. Варианты: добавить условие в
whereконфига pdoTools передrun(); либо вынести построение условия изCatalogResourceGroupVisibilityв форму, пригодную и для xPDOQuery, и для сырого SQL, и переиспользовать в обоих местах. Второе предпочтительнее — иначе получим две реализации одной проверки, которые со временем разойдутся. - Охват. Помимо
ms3_productsестьms3_gallery,ms3_options,ms3_product_options— надо пройти по всем и понять, где выборка может отдать закрытый ресурс. - Настройка. Логично переиспользовать тот же выключатель
ms3_web_catalog_respect_resource_groups, что и в feat(web-api): учитывать ACL групп ресурсов в публичном каталоге #666, либо ввести общий — но тогда имя настройки со словомweb_catalogперестанет соответствовать смыслу. - Производительность. Листинги на Fenom-витрине бывают тяжёлыми, а pdoTools кэширует результаты. Надо проверить, что условие попадает в ключ кэша — иначе закэшированная страница отдаст закрытые товары независимо от фильтра.
Четвёртый пункт, вероятно, самый неприятный: у CatalogResourceGroupVisibility в #666 уже есть метод для участия в ключе кэша, и здесь потребуется аналогичное, но для механизма кэширования pdoTools.
Критерии приёмки
-
ms3_productsне выводит анониму ресурсы из закрытых групп - Условие видимости строится одним кодом с Web API, а не отдельной копией
- Ресурс без групп и ресурс с явным грантом анониму (
principal = 0) остаются видимыми - Кэш pdoTools учитывает видимость и не отдаёт закрытое из закэшированной выдачи
- Остальные сниппеты проверены на тот же класс проблемы
- Есть тест, исполняющий выборку против реальных
document_groupsиaccess_resource_groups
Контекст
- Публичный каталожный API игнорирует resource_groups — решить, поддерживаем ли #659 — исходная задача
- feat(web-api): учитывать ACL групп ресурсов в публичном каталоге #666 — реализация для публичного Web API
- msCustomerGroup: связать покупателей с группами ресурсов MODX #669 — связка
msCustomerс группами ресурсов, чтобы авторизованный покупатель видел открытое ему
Activity