Дополнительные параметры товаров
В продолжение вот этого вопроса: modxclub.ru/blog/voprosy-spetsyalistov/257.html
Сейчас это еще не реализовано в официальной сборке, но покажу на примере слингов. Сразу скажу, что действий не мало надо сделать. И еще: для обеспечения обратной совместимости хоть какой-то, придется дополнительно напрячься с переопределением классов. Единственное что могу сказать положительное, это то, что версия 2.1.0 как раз и вышла с дополнениями, которые писались под этот функционал. Конечно, это не самое лучшее решение, и более правильный функционал появится позже в самой сборке, но если надо срочно, что чтож, значит надо делать. Итак, поехали.
Готовим параметры и базу данных
1. Создаем необходимые TV-параметры
Надо создать TV-шки этих параметров, меняющихся в товарах. В нашем случае это size и color. При этом надо в этих полях не конечное значение указать, а именно перечислить имеющиеся варианты. К примеру, у вас галстук с размерами L,X,XL и цветами Красный, Синий, Зеленый. В самом товаре надо будет выбрать все возможные значения, которые соответствуют наличию товара.
Лучше всего заводить TV-поле типа Мульти-список, в котором в возможных вариантах сразу прописать все возможные варианты. Вот так:

Или вот так:

В нашем случае не принципиально, но все-таки числовые ID-шники всегда предпочтительней.
В таблице заполненных данных TV-полей у вас будут примерно такие данные: M||XXL||L. То есть по разделителю || можно будет понять, что по этому товару есть размеры M,XXL,L. Получить массив размеров можно будет через explode('||', $value);
2. Редактируем таблицу Заказ-Товар
Надо отредактировать вручную таблицу modx_billing_order_products (через phpMyAdmin или типа того):
2.1 Добавить колонки этих параметров (повторюсь, в нашем случае это size и color). Тип данных сами определите, но ни в коем случае эти колонки не должны быть nullable, и нельзя вставлять значения null.
2.2 Надо подправить индексы — удалить уникальный ключ order_id-product_id и создать уникальный ключ со своими параметрами. В нашем случае это order_id-product_id-size-color.
2.3 Подправить map-файл класса OrderProduct. Надо в него добавить описание ваших колонок. Лучше всего для этого использовать CMPGenerator. На всякий случай ревизия: https://gist.github.com/Fi1osof/f0372195175ade7a72fb/revisions
Суть этого действия в том, чтобы получить возможность в одном заказе иметь несколько товаров с одним и тем же id, только с разными параметрами.
3. Правим шаблоны
Все, на этом этапе мы уже имеем возможность добавлять товары с различными параметрами. Теперь нам просто надо в форме вывести чекбоксы или выпадающие списки с размерами и цветами, и эти данные отправить на процессор добавления товара в корзину. С шаблоном ничего показывать не буду — это обычная задача на уровне шаблона добавить поля в форму. Эти данные автоматически будут передаваться в запросе. Нам остается только на сервере поймать эти данные и учесть в добавлении товара. И вот тут начинаются трудности побольше…
Переопределяем процессоры
Для начала немного общей теории по добавлению товаров в корзину.
При добавлении товаров в корзину, запрос идет на процессор orders/products/add. Но если товара нет в заказе, то его надо добавить к заказу новой строчкой. А если уже есть, то тогда запись надо обновить. Это уже два разных действия и два совершенно разных процессора: один — create-процессор, создающий новую запись, а второй — update-процессор, обновляющий существующую запись.
Как это работает?
Есть add-процессор modMgrOrdersProductsAddProcessor. В нем в методе process выполняется поиск товара через метод findExistingObject() ссылка
и в зависимости от результата выполняется тот или иной конечный процессор.
Вот наша задача здесь — это изменить принцип поиска товара в корзине. То есть здесь выполняется поиск по ключу order_id-product_id ссылка
а нам надо сделать поиск по ключу order_id-product_id-size-color (или order_id-product_id-size, как это конкретно в моем примере). Вот для этого нам надо переопределить add-процессор и перенаправлять запросы на него.
3. Добавляем свой add-процессор.
Создаем свой add-процессор в вашей папке процессоров (у меня это site/web/basket/orders/products/add в неймспейсе modxsite), и в нем переопределяем метод поиска записи товара в заказе: https://gist.github.com/Fi1osof/642525c6ed5de4b38698#file-gistfile1-php-L28
Собственно здесь все. Если запрос на добавление товара будет отправляться на этот процессор, то товар будет искаться с учетом заданных параметров. Только не отправляйте поиск объекта дальше в родительский процессор, а то он получит первый же попавшийся товар с этим id, только без учета дополнительных параметров.
4. Переопределяем action-процессор.
Вот теперь надо сделать главное — это перенаправить запросы с клиента на этот новый add-процессор. В целом, это относительно простая задача. У нас есть в баскете общий action-процессор: https://github.com/Fi1osof/ShopModxBox/blob/master/core/components/basket/processors/basket/web/public/action.class.php
Вот такой у меня переопределяющий action-процессор: https://gist.github.com/Fi1osof/86d19bd9e5299756de55#file-gistfile1-php-L15
Запросы на него попадают двумя способами:
- Ajax — через коннектор. https://github.com/Fi1osof/ShopModxBox/blob/master/assets/components/basket/connectors/connector.php#L22
- Не Ajax — через плагин. https://github.com/Fi1osof/ShopModxBox/blob/master/core/components/basket/elements/plugins/basket.plugin.php#L14
То есть надо подправить путь на свой action-процессор в коннекторе (настройка будет добавлена позже), а в плагине в параметрах плагина изменить параметры basket_processor и basket_namespace (именно настройки плагина в админке, а не исходный код плагина).
Ну, в общих чертах все. Процессор вывода товаров корзины получит все записи товаров с их данными: https://github.com/Fi1osof/ShopModxBox/blob/17791a616ccb43245dfdac5f6defb81a2c90b815/core/components/basket/processors/basket/mgr/orders/products/getdata.class.php#L69
Останется только одна небольшая задача: в админке в модуле управления заказами не будет колонки вывода размена и цен, поэтому либо ориентироваться на данные из писем, либо править JS-ы этого модуля. https://github.com/Fi1osof/ShopModxBox/blob/17791a616ccb43245dfdac5f6defb81a2c90b815/manager/components/shopmodxgroupedit/js/widgets/grid.js
Вот моя ревизия на слингах: https://gist.github.com/Fi1osof/380d7b0587c61738b967/revisions В целом там совсем не много.
Вот и все. Более удобный функционал для подобных задачах появится в самых ближайших версиях движка.