You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
В сниппете msProducts при построении запроса pdoTools запихивает в parent IN все что найдет в дереве ресурсов через $modx->getChildIds() - таким образом конечный SQL запрос для получения товаров может содержать десятки а то и сотни тысяч родителей, тогда как реальных категорий обычно не более 10 штук.
Решение предлагает не пробрасывать в pdoTools логику построения parents, а строит условие для parents самостоятельно.
Основная проблема понятна: getChildIds действительно тяжелый для больших деревьев, где товары лежат вперемешку с категориями. Но перенос этой логики прямо в тело сниппета ms_products создает больше проблем, чем решает.
В перспективе архитектуры: выборка дерева и резолвинг parents — это задача слоя выборки данных (pdoFetch / ядро), а не отдельного сниппета дополнения. Если решать это локальным обходом внутри ms_products, ломается и стабильность, и обратная совместимость (BC):
Производительность на реальных базах:
Поуровневый цикл по глубине делает до 20 синхронных запросов в базу на каждый запуск сниппета без кэширования.
Сборка product_id из msCategoryMember через fetchAll в память PHP и последующая склейка в сырой IN ({}) на магазинах от 20–50k товаров гарантированно упрется либо в memory_limit, либо в переполнение пакета MySQL (max_allowed_packet).
Обратная совместимость (BC):
Захардкоженные published = 1, deleted = 0 ломают штатные параметры &showUnpublished и &showDeleted.
Запрос категорий не учитывает context_key, что приведет к подтягиванию чужих категорий в мультиконтекстных сайтах.
Мутация $scriptProperties['parents'] = 0 затирает исходные свойства в чанке-обертке (tplWrapper) и может ломать логику пагинации в pdoPage.
Если закрывать эту проблему на уровне miniShop2 до системных правок в pdoTools/ядре, делать это нужно без выгрузки списков ID в память PHP и с полным сохранением контракта параметров сниппета — через подзапрос/JOIN к msCategoryMember и с учетом контекста и флагов публикации.
Дерево категорий обходится послойно (1 быстрый запрос на уровень глубины, всего 2–3 индексных запроса по таблице категорий на весь каталог).
Учитываются флаги published = 1 (только если не задан &showUnpublished=1) и deleted = 0.
Связи с дополнительными категориями проверяются через ANSI SQL предикат EXISTS, а исключение категорий — через NOT EXISTS.
Наличие msProduct.parent в $where сообщает pdoFetch автоматически пропустить свой устаревший блок parents (pdofetch.class.php:644-668). При этом $scriptProperties['parents'] не затирается и сохраняет своё значение для плейсхолдеров tplWrapper.
Расход памяти в PHP: 0 байт под ID товаров (вместо выгрузки массивов). В MySQL подзапрос EXISTS мгновенно попадает в составной первичный ключ (product_id, category_id) в msCategoryMember.
2. Целевое решение в ядре (pdoTools и pdoTools3)
В ядре поддержка категорий msCategoryMember переведена с fetchAll(PDO::FETCH_COLUMN) на EXISTS / NOT EXISTS со строгой изоляцией по is_a($class, 'msProduct', true) (чтобы не задевать Tickets и другие ресурсы):
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
В сниппете msProducts при построении запроса pdoTools запихивает в parent IN все что найдет в дереве ресурсов через
$modx->getChildIds()- таким образом конечный SQL запрос для получения товаров может содержать десятки а то и сотни тысяч родителей, тогда как реальных категорий обычно не более 10 штук.Решение предлагает не пробрасывать в pdoTools логику построения parents, а строит условие для parents самостоятельно.