[YandexMarket2] интеграция с msOptionsPrice2

[ анонс компонента ]   [ как это работает на Vue.js в админке MODX ]   [ купить в Modstore ]

Как не начну писать — всё получается рекламная статья. Ну не без этого)

Возможно, кто-то ещё не знаком с обновлённой версией компонента для выгрузки различных прайс-листов в XML в Яндекс.Маркет и другие агрегаторы (да, из коробки есть формат Google RSS 2.0).

+ архитектура компонента предполагает удобное добавление новых маркетплейсов или вообще «накликивание» XML в произвольном формате. Подробности по ссылкам выше ↑

Нет смысла подробно рассказывать про msOptionsPrice2, который добавляет модификации по опциям к товарам miniShop2 — его и так все знают и многие пользуются :)

TL;DR С версии 1.3 (уже в Modstore) можно выгружать модификации в XML быстро, просто и гибко.

  пример, где в прайс-листе — и товары с модификациями, и без них (с fallback-обработчиками)

А далее уже информация по настройке для тех, кто хотел или планирует выгружать модификации.

 

Введение (можно не читать)


Ещё в первом анонсе я писал о планах сделать эту интеграцию, но как гласит пословица чем дольше программист, тем меньше времени.
Спасибо всем, кто меня постоянно пинговал и согласился задонатить для ускорения процесса.

Сразу отмечу, что я отошёл от MODX проектов и у меня нет магазинов на поддержке. А какие-то важные изменения на маркетплейсах и вообще в магазино-строении на MODX я могу упускать из виду.
Но я всё ещё хочу улучшать свои компоненты и делать экосистему немного удобнее)

Поэтому очень важно писать свои комментарии или замечания мне о каких-то неудобных и недоработанных моментах. Можно и в поддержку :)
 

Особенности интеграции c msOptionsPrice2


Весь компонент я задумывал максимально быстрым, удобным и не требовательным к ресурсам.
Чтобы по минимуму запросов в БД, а лучше вообще по одному для товаров и категорий (почти так и работает с активной настройкой yandexmarket2_reduce_queries).
И в этой доработке удалось соблюсти мои стандарты, кмк.

  • В одном прайс-листе можно выводить как товары с модификациями, так и без них.
  • Без дополнительных запросов в базу данных (left join таблицы модификаций и группировка). Будут работать условия по модификациям.
    Маленький нюанс: Джойнятся только активные модификации, вряд ли для кого-то это будет проблемой. Но зато не нужно ставить условие Modification.active = 1, которое обрубило бы товары без модификаций.
  • Все опции модификации доступны как ассоциативный массив в {$modifcation.options} (хитрый select в MySQL формирующий почти JSON через GROUP_CONCAT).
  • Расчёт цены модификации на стороне компонента YM2 (по тем же правилам msop2).
    И здесь нюанс: на цены модификаций не применяются плагины скидок miniShop2, так как я особо не вникал в порядок применения скидок. Если важно — пишите, всё можно придумать.
  • Строится уникальная ссылка (c get-параметром ?mid=111) по которой на странице товара можно отметить нужные опции и серверно проставить корректную цену (потребует правки в вёрстке).
  • Можно подменить и артикул, и название модификации (для этого приложу сниппет ниже, хотя это вполне могло бы быть из коробки msop2 не создавая доп запросов).
 

Настройка интеграции (TODO: добавить это в документацию)


! Если на сайте нужно выгружать только модификации, то нужно как-раз добавить условие Modification.active = 1 и уже fallback-обработчики можно будет не использовать.


Компонент всегда подсказывает по столбцам Modification.*, если детектит наличие компонента msOptionsPrice2.

  1. Во вкладке предложений нужно отредактировать класс ресурса, добавив туда :msop2 (как на самом первом скриншоте).

  2. Если используете осмысленные названия для модификаций, то в элементе <name> выберите Modification.name. Это значение можно прибавить к названию товара написав в обработчике:
    {$pagetitle} {$input} // в $input попадет значение столбца. Можно использовать и $modification.name

  3. Ссылка и цена проставятся автоматически через соответствующие прокси-поля Offer.url и Offer.price. Но всегда есть доступ к исходной цене товара в Data.price и модификации в Modification.price (не забывайте, что у модификации ещё есть type цены: увеличение, уменьшение или точная сумма, но ещё там могут быть проценты).

  4. Вывод опции модификации. Компонент не подсказывает все возможные опции, поэтому нужно вводить в поле самостоятельно. Если цвет, то вводить в поле Modification.options.color, если в прайс-листе есть и товары без модификаций, то добавьте в обработчик: {$input ?: $option.color}.

    Пример настройки, чтобы в XML вывелось <param name=«Цвет»>зеленый</param>


  5. Подменяем на товаре цену и отмечаем опции по автоматически добавленному get-параметру mid={$modification.id} (не создавая доп. запросов).
    Если же хотите выводить название модификации, вес, артикул, то переходите сразу к шагу 6.

    При заходе на страницу товара в miniShop2 срабатывает событие msOnGetProductPrice, под который есть плагин в msop2 (ловит $_REQUEST['mid'] и считает цену товара, оставляя для других компонентов подсказки в специальных плейсхолдерах).
    • Цена заменится автоматически, если использовать плейсхолдеры {$price} или [[!+price]] (строго некэшированный вызов).
    • Для отметки выбранных опций в чанке опций с <select> элементом (как правило это tpl.msOptions) в переборе значений для вывода <option> сделайте так:
      <option value="{$value}" {if $_modx->getPlaceholder('_returned_price')['msoptionsprice_options'][$name] == $value}selected{/if}>
          {$value}
      </option>
      Да, может хак грязноватый, но рабочий. Покрасивее в следующем шаге.

  6. Получение всех параметров модификации по get-параметру и выставление своих плейсхолдеров. Здесь мы тоже не будем изобретать велосипед, а будем использовать встроенные методы в msoptionsprice2. Код сниппета (вызывать его некэшированным в шаблоне товара):
    <?php
    /** @var modX $modx */
    /** @var array $scriptProperties */
    
    $modificationGetParam = $modx->getOption('getParam', $scriptProperties, 'mid');
    $modificationPlaceholderPrefix = $modx->getOption('placeholderPrefix', $scriptProperties, 'modification.');
    $resourceId = $modx->getOption('resourceId', $scriptProperties, $modx->resource->id ?? null);
    
    $corePath = $modx->getOption('msoptionsprice_core_path', null,
        $modx->getOption('core_path', null, MODX_CORE_PATH).'components/msoptionsprice/');
    
    /** @var msoptionsprice $msoptionsprice */
    $msoptionsprice = $modx->getService('msoptionsprice', 'msoptionsprice', $corePath.'model/msoptionsprice/',
        ['core_path' => $corePath]);
    if (!$msoptionsprice) {
        return 'Could not load msoptionsprice class!';
    }
    
    if (isset($_GET[$modificationGetParam])
        && is_numeric($_GET[$modificationGetParam])
        && ($modification = $msoptionsprice->getModificationById((int)$_GET[$modificationGetParam], $resourceId))
        && ((int)$modification['rid'] === (int)$resourceId)
        && ($modification['active'] ?? false)) {
        $placeholders = $msoptionsprice->makePlaceholders($modification, $modificationPlaceholderPrefix);
        $modx->setPlaceholders($placeholders['vl']);
    }

    На выходе мы получим плейсхолдеры с префиксом modifcation. (но можете поменять)
    // И на странице товара уже можно будет использовать:
    {$_modx->getPlaceholder('modification.name') ?: $_modx->resource.pagetitle}
    
    // А в чанке опций так (потому что makePlaceholders создаёт плоский массив)
    <option value="{$value}" {if $_modx->getPlaceholder('modification.options.'~$name) == $value}selected{/if}>
        {$value}
    </option>

    Название Get-параметра можно поменять, задав системную настройку yandexmarket2_modification_param. Но тогда будет работать только сниппет из шага 6 (там тоже поправить не забудьте).

В общем-то всё. Если что-то забыл, то допишу к статье или в комментариях.

P.s. Есть неприятный баг с msOptionsPrice2 s6200.h3.modhost.pro/katalog.html?mid=234
Если к странице товара (и даже категории) добавить get-параметр mid с id любой существующей модификации, то цена применится к товару не проверяя его ID (и даже ко всем товарам в категории). Такого, конечно, быть не должно. Хоть компонент msOptionsPrice2 давно не обновлялся, но если будет обновление, то @Володя, прошу учесть этот момент.
Заодно можно и плейсхолдеры выставлять с названием, артикулом и другими полями модификации)
Евгений Шеронов
31 октября 2021, 19:50
modx.pro
1
1 077
+8
Поблагодарить автора Отправить деньги

Комментарии: 1

Евгений
23 ноября 2024, 11:51
0
Отличное дополнение, спасибо!
Подскажите, как организовать файл если стоит msOptionsPrice2 привязан к опции size там может быть много позиций с разными ценами?
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    1