Готовые решения
Бесплатная доставка по критерию производителя.
            Всем привет.
У меня появилась задачка, суть в следующем, некоторые вендоры спонсируют бесплатную доставку, а не которые нет. Поэтому кретерий бесплатная доставка или платная является производитель. Как это сделать в МS2?
1) Первый шаг. Это сделать дополнительное поле в настройках. Я уже описывал как это сделать в отдельной статье "Добавить поле в опции MS вкладка «Производитель товара» msVendor"
        
        
        
        
    У меня появилась задачка, суть в следующем, некоторые вендоры спонсируют бесплатную доставку, а не которые нет. Поэтому кретерий бесплатная доставка или платная является производитель. Как это сделать в МS2?
1) Первый шаг. Это сделать дополнительное поле в настройках. Я уже описывал как это сделать в отдельной статье "Добавить поле в опции MS вкладка «Производитель товара» msVendor"
[msPromoCode2] Кейс. Установка промо-кода программно при входе на сайт

Мало кто знает, что msPromoCode2 можно использовать и как компонент для скидок на товары, без обязательного ввода промо-кода юзером. Всего лишь нужно написать маленький плагин, взаимодействующий с программным API. В этом посте предлагаю данный кейс.
К сожалению, никак не успеваю пополнить раздел API, пусть этот пост станет началом!
Плюс и минус в каунте корзины MS2
            Досточно простой вопрос, который мучает начинающих разработчиков. Решил поделиться решением, как сделать кнопки плюс и минус в корзине MS2. Что бы все было «по-фуншую»
Начнем c разметки. Я показываю на страндартной теме MS2. Вносим правки в чанк tpl.msCart
        
        
        
    Начнем c разметки. Я показываю на страндартной теме MS2. Вносим правки в чанк tpl.msCart
...
<td class="count">
<form method="post" class="ms2_form" role="form">
  <input type="hidden" name="key" value="{$product.key}"/>
  <div class="form-group">
    <div class="input-group input-group-sm qty">
      <span class="input-group-prepend">
      <span class="input-group-text minus input_count_action">-</span>
      </span>
      <input type="number" name="count" value="{$product.count}" class="form-control"/>
      <span class="input-group-append">
      <span class="input-group-text plus input_count_action">+</span>
      <span class="input-group-text">{'ms2_frontend_count_unit' | lexicon}</span>
      </span>
    </div>
      <button class="btn btn-sm" type="submit" name="ms2_action" value="cart/change">
      ↻</button>
  </div>
</form>
</td>
...        Выведение опций товара по категориям
            Сниппет msProductOptions выводит товары общим массивом. В принципе, никто не запрещает в чанке вывода делать с этим массивом всё что угодно, в том числе и делить по категориям. Однако всё чаще поступает запрос от клиента не только вывести категории, но и соблюсти их сортировку.
Для этих целей мне пришлось msProductOptions переписать. Мой вариант сниппета воспроизводит запрос msProductData::loadOptions с сортировкой по полю rank категории, затем группирует все опции по категориям с соблюдением сортировки самих опций.
        
        
        
        
    Для этих целей мне пришлось msProductOptions переписать. Мой вариант сниппета воспроизводит запрос msProductData::loadOptions с сортировкой по полю rank категории, затем группирует все опции по категориям с соблюдением сортировки самих опций.
Сброс и обновление кэша сниппета в определенное время
            Уже когда-то задавался этим вопросом, пришел к такому решению (уже без getCache, но с fenom и включенным pdotools_fenom_parser).
UPD Зачем вообще это.
        
        
        
        
    UPD Зачем вообще это.
Скрипт подмены конфигов сайта на лету
            Надоело каждый раз при переносе сайтов между серверами прописывать конфиги в нескольких местах. Каждый раз напрягаешься, чтобы не перепутать. Написал скрипт, который делает это автоматически в зависимости от $_SERVER['HTTP_HOST'] сервера на котором он запускается.         
        
        
        
    Плагин ms2Gallery для TinyMCE 4
            Всем привет! Давненько я ничего не писал в «Готовые решения».
Данная заметка будет полезна тем, кто не разбирается в WYSIWYG редакторах, в частности для тех, кто никогда не писал для них плагины. Я работаю с TinyMCE RTE, посему если вы тоже работаете на нем, то этот пост для вас. Я переехал в MODx из WP, а как известно я думаю многим, в WP многие плагины работают через, так называемые shortcode. Это код, который выводит что-то из каких-то кастомных плагинов в контент.
        
        
        
    Данная заметка будет полезна тем, кто не разбирается в WYSIWYG редакторах, в частности для тех, кто никогда не писал для них плагины. Я работаю с TinyMCE RTE, посему если вы тоже работаете на нем, то этот пост для вас. Я переехал в MODx из WP, а как известно я думаю многим, в WP многие плагины работают через, так называемые shortcode. Это код, который выводит что-то из каких-то кастомных плагинов в контент.
Вывод карточек товара магазина в статьях на сайте
            Несколько недель назад от заказчика поступила такая хотелка — надо чтоб в статьи блога на сайте магазина можно было бы вставлять карточки товаров этого самого магазина. Обдумывал разные варианты, но в итоге, совместно с чатиком в телеграме пришел к такому решению:
        
        
        
        
    - В статье в нужном месте менеджер делает конструкцию такого вида: %%34,45,54%%, где 34,45 и 54 — айди товаров в магазине, таких вхождений может быть хоть сколько в статье.
 - На событие onWebPagePrerender вешается плагин, который с помощью регулярки выбирает все вхождения нашего паттерна, для каждого вхождения вызывает сниппет msProducts и последним шагом заменяет в контенте страницы паттерны соответствующими результатами сниппета.
 
Обновление дубликатов страниц (duplicate_updater_modx)
            Может кому пригодится, написал скриптец для поиска дублей страниц и обновления последних путем добавление префикса +=1
Инструкция залить duplicate_updater_modx.php в корень сайта и запустить в браузере yousute.ru/duplicate_updater_modx.php
git: github.com/vectorserver/duplicate_updater_modx
Сам код:
        
        
        
    Инструкция залить duplicate_updater_modx.php в корень сайта и запустить в браузере yousute.ru/duplicate_updater_modx.php
git: github.com/vectorserver/duplicate_updater_modx
Сам код:
<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 25.06.2019
 * Time: 14:19
 */
define('MODX_API_MODE', true);
require 'index.php';
$modx->getService('error', 'error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_FATAL);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
$msg = "";
$table_prefix = $modx->config['table_prefix'];
//Ищем двойников
$find_query = $modx->query("SELECT group_concat(`id`) ids, count(id) c FROM `" . $table_prefix . "site_content` GROUP by concat(uri) HAVING c > 1");
$dubles = $find_query->fetchAll(PDO::FETCH_ASSOC);
//Если нашли
if (count($dubles)) {
    foreach ($dubles as $item) {
        //Разбивем ID
        $ids = explode(",", $item['ids']);
        //Сортируем - старые вверх
        sort($ids, SORT_NUMERIC);
        $count = 0;
        foreach ($ids as $doc_id) {
            $count++;
            //ПРопускаем оригинал
            if ($count > 1) {
                //Обновляем ресурс
                $originalRes = $modx->getObject('modResource', $doc_id);
                $generated = $originalRes->cleanAlias($originalRes->get('pagetitle')) . "-" . $count;
                $originalRes->set('alias', $generated);
                $originalRes->save();
                //В лог
                $msg .= $originalRes->get('id') . " | " . $originalRes->get('pagetitle') . " - обновлен.\n";
            }
        }
        //Сброрс кеша
        $modx->cacheManager->refresh();
    }
} else {
    $msg .= "Дублей нет\n";
}
echo "<pre>" . $msg;        Запрос через XPDO к тв параметрам с использование having
            Запрос на XPDO для выборки ресурсов у которых совпадают значения тв параметров.
Функция having посчитает количество совпадений по групперуемому полю contentid
        
        
        
        
    Функция having посчитает количество совпадений по групперуемому полю contentid