Дополнительные параметры товаров

В продолжение вот этого вопроса: 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. На всякий случай ревизия: gist.github.com/Fi1osof/f0372195175ade7a72fb/revisions Суть этого действия в том, чтобы получить возможность в одном заказе иметь несколько товаров с одним и тем же id, только с разными параметрами. 3. Правим шаблоны Все, на этом этапе мы уже имеем возможность добавлять товары с различными параметрами. Теперь нам просто надо в форме вывести чекбоксы или выпадающие списки с размерами и цветами, и эти данные отправить на процессор добавления товара в корзину. С шаблоном ничего показывать не буду — это обычная задача на уровне шаблона добавить поля в форму. Эти данные автоматически будут передаваться в запросе. Нам остается только на сервере поймать эти данные и учесть в добавлении товара. И вот тут начинаются трудности побольше… Переопределяем процессоры Для начала немного общей теории по добавлению товаров в корзину. При добавлении товаров в корзину, запрос идет на процессор orders/products/add. Но если товара нет в заказе, то его надо добавить к заказу новой строчкой. А если уже есть, то тогда запись надо обновить. Это уже два разных действия и два совершенно разных процессора: один — create-процессор, создающий новую запись, а второй — update-процессор, обновляющий существующую запись. Как это работает? Есть add-процессор modMgrOrdersProductsAddProcessor. В нем в методе process выполняется поиск товара через метод findExistingObject() github.com/Fi1osof/ShopModxBox/blob/17791a616ccb43245dfdac5f6defb81a2c90b815/core/components/billing/processors/mgr/orders/products/add.class.php#L37 и в зависимости от результата выполняется тот или иной конечный процессор. Вот наша задача здесь — это изменить принцип поиска товара в корзине. То есть здесь выполняется поиск по ключу order_id-product_id github.com/Fi1osof/ShopModxBox/blob/17791a616ccb43245dfdac5f6defb81a2c90b815/core/components/billing/processors/mgr/orders/products/add.class.php#L94 а нам надо сделать поиск по ключу order_id-product_id-size-color (или order_id-product_id-size, как это конкретно в моем примере). Вот для этого нам надо переопределить add-процессор и перенаправлять запросы на него. 3. Добавляем свой add-процессор. Создаем свой add-процессор в вашей папке процессоров (у меня это site/web/basket/orders/products/add в неймспейсе modxsite), и в нем переопределяем метод поиска записи товара в заказе: gist.github.com/Fi1osof/642525c6ed5de4b38698#file-gistfile1-php-L28 Собственно здесь все. Если запрос на добавление товара будет отправляться на этот процессор, то товар будет искаться с учетом заданных параметров. Только не отправляйте поиск объекта дальше в родительский процессор, а то он получит первый же попавшийся товар с этим id, только без учета дополнительных параметров. 4. Переопределяем action-процессор. Вот теперь надо сделать главное — это перенаправить запросы с клиента на этот новый add-процессор. В целом, это относительно простая задача. У нас есть в баскете общий action-процессор: github.com/Fi1osof/ShopModxBox/blob/master/core/components/basket/processors/basket/web/public/action.class.php Вот такой у меня переопределяющий action-процессор: gist.github.com/Fi1osof/86d19bd9e5299756de55#file-gistfile1-php-L15 Запросы на него попадают двумя способами:

  1. Ajax — через коннектор. github.com/Fi1osof/ShopModxBox/blob/master/assets/components/basket/connectors/connector.php#L22
  2. Не Ajax — через плагин. github.com/Fi1osof/ShopModxBox/blob/master/core/components/basket/elements/plugins/basket.plugin.php#L14 То есть надо подправить путь на свой action-процессор в коннекторе (настройка будет добавлена позже), а в плагине в параметрах плагина изменить параметры basket_processor и basket_namespace (именно настройки плагина в админке, а не исходный код плагина). Ну, в общих чертах все. Процессор вывода товаров корзины получит все записи товаров с их данными: github.com/Fi1osof/ShopModxBox/blob/17791a616ccb43245dfdac5f6defb81a2c90b815/core/components/basket/processors/basket/mgr/orders/products/getdata.class.php#L69 Останется только одна небольшая задача: в админке в модуле управления заказами не будет колонки вывода размена и цен, поэтому либо ориентироваться на данные из писем, либо править JS-ы этого модуля. github.com/Fi1osof/ShopModxBox/blob/17791a616ccb43245dfdac5f6defb81a2c90b815/manager/components/shopmodxgroupedit/js/widgets/grid.js Вот моя ревизия на слингах: gist.github.com/Fi1osof/380d7b0587c61738b967/revisions В целом там совсем не много. Вот и все. Более удобный функционал для подобных задачах появится в самых ближайших версиях движка.