Андрей Шевяков

Андрей Шевяков

С нами с 28 сентября 2016; Место в рейтинге пользователей: #57

Обновление полей ресурсов на основе csv-файла иморта (modx 2.8.8 + minishop 2)

Задача была обновить поля у ресурсов (ресурсы: категории, товары; поля: основные, дополнительные (тв)).
Обновление изображений (галерея) в задачу не входило.
Возможно, кому-нибудь пригодится. Если будут корректировки/замечания, буду только рад.
Виталий
17 февраля 2026, 03:09
modx.pro
3
140
+5

Видеогалерея на MIGX. Может кому понадобится (решено)

*Помогите толком разобраться, как редактировать поля title, desc, image, duration, которые находятся внутри json массива у видео в виде отдельных полей, а не кривыми ручками

Видеогалерея на MIGX

  1. Устанавливаем VideoGallery
  2. Создаем tv с именем video тип ввода VideoGallery
  3. Создаем tv с именем videogallery. Тип ввода migx, конфигурация videogallery, выбираем шаблон для отображения
  4. Создаем сниппет VideoJsonToPlaceholders
    ! ВНИМАНИЕ в п.2 удалите пробел между & quot;

    <?php
    // Получаем параметры
    $json = $modx->getOption('json', $scriptProperties, '');
    $prefix = $modx->getOption('prefix', $scriptProperties, 'json.');
    
    // 1. Проверяем наличие данных
    if (empty($json)) {
        return 'Ошибка: JSON‑строка пуста';
    }
    
    // 2. Удаляем все & quot; из строки ! Внимание в следующей строке удалите пробел между & quot;
    $json = str_replace('& quot;', '', $json);
    
    // 3. Исправляем экранированные слеши
    $json = str_replace('\\/', '/', $json);
    
    // 4. Парсим JSON
    $data = json_decode($json, true);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        return 'Ошибка JSON: ' . json_last_error_msg() . ' (строка: ' . htmlspecialchars($json) . ')';
    }
    
    // 5. Проверяем, что результат — массив
    if (!is_array($data)) {
        return 'Ошибка: JSON не содержит массив';
    }
    
    // 6. Функция для извлечения корневого адреса (с защитой от повторного объявления)
    if (!function_exists('getRootUrl')) {
        function getRootUrl($url) {
            if (!filter_var($url, FILTER_VALIDATE_URL)) {
                return null;
            }
    
            $parsed = parse_url($url);
            if (!$parsed || !isset($parsed['scheme']) || !isset($parsed['host'])) {
                return null;
            }
    
            $root = $parsed['scheme'] . '://' . $parsed['host'];
    
            if (isset($parsed['port'])) {
                $isDefaultHttp = ($parsed['scheme'] === 'http' && $parsed['port'] === 80);
                $isDefaultHttps = ($parsed['scheme'] === 'https' && $parsed['port'] === 443);
                if (!$isDefaultHttp && !$isDefaultHttps) {
                    $root .= ':' . $parsed['port'];
                }
            }
    
            return $root;
        }
    }
    
    // 7. Устанавливаем плейсхолдеры с обработкой
    foreach ($data as $key => $value) {
        // Приводим строки к UTF‑8
        if (is_string($value)) {
            $value = mb_convert_encoding($value, 'UTF-8', 'UTF-8');
        }
    
        // Если это поле video и содержит URL — извлекаем корневой адрес
        if ($key === 'video' && !empty($value)) {
            $rootUrl = getRootUrl($value);
            if ($rootUrl) {
                $modx->setPlaceholder($prefix . 'video_root', $rootUrl);
            }
            // Сохраняем исходный URL
            $modx->setPlaceholder($prefix . 'video', $value);
        }
    
        // Преобразуем videoDuration из PT... в оптимальный формат
        if ($key === 'videoDuration') {
            if (empty($value) || !is_string($value)) {
                $value = '0 с';
            } else {
                preg_match('/PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/', $value, $matches);
                $hours   = isset($matches[1]) ? (int)$matches[1] : 0;
                $minutes = isset($matches[2]) ? (int)$matches[2] : 0;
                $seconds = isset($matches[3]) ? (int)$matches[3] : 0;
    
                if ($hours > 0) {
                    $value = sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
                } elseif ($minutes > 0) {
                    $value = sprintf('%02d:%02d', $minutes, $seconds);
                } else {
                    $value = $seconds . ' с';
                }
            }
        }
    
        // Подставляем значения по умолчанию для критических полей
        switch ($key) {
            case 'title':
                if (empty($value)) {
                    $value = 'Без названия';
                }
                break;
            case 'desc':
                if (empty($value)) {
                    $value = 'Описание отсутствует';
                }
                break;
        }
    
        // Устанавливаем плейсхолдер (если он ещё не установлен через парсинг)
        if (!in_array($key, ['video', 'video_root'])) {
            $modx->setPlaceholder($prefix . $key, $value);
        }
    }
    
    return '';
  5. Создаем новое MIGx поле videogallery
  6. Экспортируем туда конфиг
    {
      "formtabs": [
        {
          "caption": "Видеогалерея",
          "print_before_tabs": "0",
          "fields": [
            {
              "field": "video",
              "caption": "Видео",
              "inputTV": "video"
            }
          ],
          "pos": 1
        }
      ],
      "contextmenus": "",
      "actionbuttons": "",
      "columnbuttons": "",
      "filters": "",
      "extended": {
        "actionbuttonsperrow": 4,
        "gridload_mode": 1,
        "has_jointable": "yes"
      },
      "permissions": {},
      "fieldpermissions": "",
      "columns": [
        {
          "header": "Рендер",
          "dataIndex": "render",
          "width": 1,
          "sortable": "false",
          "show_in_grid": 0,
          "renderer": "this.renderChunk",
          "renderchunktpl": "[[!VideoJsonToPlaceholders? &json=`[[+video]]` &prefix=`video.`]]"
        },
        {
          "header": "Название",
          "dataIndex": "video_title",
          "sortable": "false",
          "show_in_grid": 1,
          "renderer": "this.renderChunk",
          "renderchunktpl": "[[+video.title]]"
        },
        {
          "header": "Видео",
          "dataIndex": "video_video",
          "sortable": "false",
          "show_in_grid": 1,
          "renderer": "this.renderChunk",
          "renderchunktpl": "<iframe src=\"[[+video.video]]\" width=\"160\" height=\"90\" frameborder=\"0\"></iframe>"
        },
        {
          "header": "Превью",
          "dataIndex": "video_image",
          "sortable": "false",
          "show_in_grid": 1,
          "renderer": "this.renderChunk",
          "renderchunktpl": "<img src=\"[[+video.image]]\" width=\"160\">"
        },
        {
          "header": "Время",
          "dataIndex": "video_duration",
          "width": 100,
          "sortable": "false",
          "show_in_grid": 1,
          "renderer": "this.renderChunk",
          "renderchunktpl": "[[+video.videoDuration]]"
        },
        {
          "header": "videoId",
          "dataIndex": "video_videoId",
          "sortable": "false",
          "show_in_grid": "0",
          "renderer": "this.renderChunk",
          "renderchunktpl": "[[+video.videoId]]"
        },
        {
          "header": "Описание",
          "dataIndex": "video_description",
          "sortable": "false",
          "show_in_grid": 1,
          "renderer": "this.renderChunk",
          "renderchunktpl": "[[+video.desc]]"
        }
      ],
      "category": ""
    }
SYAN
09 февраля 2026, 01:00
modx.pro
2
2 378
0

[msPromoCode2] Применение скидки при входе на сайт



Мало кто знает, что компонент msPromoCode2 можно использовать не только как классическую систему промокодов, но и как полноценную глобальную скидку для всего сайта – применяемую автоматически, без необходимости ввода кода на странице оформления заказа.

При этом стандартная логика работы промокодов полностью сохраняется: если пользователь в корзине введёт промокод с более выгодными условиями, система корректно применит именно его.

Вся реализация настраивается всего в три простых шага.
Павел Гвоздь
08 января 2026, 13:40
modx.pro
1
342
+6

Свой обработчик доставки (стоимость доставки по яндекс картам, готовое решение)

Доброейшего вечера/дня/ночи/утра!

Я продолжаю свой путь, я продолжаю покорять minishop2

Забегая вперед, то что я пишу, больше для меня самого, но если вдруг, кому-то будет полезно, то я буду несказанно счастлив!

Небольшое вступление: и так, стояла задача, научить минишоп рассчитывать стоимость доставки, в зависимости от удаленности.
Т.е. к примеру, клиенту нужно сделать доставку. Удаленность от физического магазина 15 км. Очень хочется, что бы доставка рассчитывалась не руками — менеджером, а автоматически. Собственно до сегодняшнего дня так и было.

И так, мне нужно через яндекс карты построить маршрут, высчитать расстояние, рассчитать стоимость доставки и передать все это дело в минишоп. Звучит просто, если ты понимаешь в программировании. Но это не мой случай! Слава богу, что есть ИИ.
Дмитрий
28 декабря 2025, 18:36
modx.pro
1
188
+2

resComments — многоуровневые комментарии с пагинацией для ресурсов MODX3

Всем привет!
Представляю вниманию компонент для реализации комментариев/отзывов и т. д. к любым ресурсам MODX3.
Отличие от ticketsComments — возможность пагинации. Отличие от easyComm — многоуровневость.

Основные свойства
  • Неограниченная вложенность
  • Несколько вызовов на странице
  • Оценка публикации / ресурса
  • Оценки и рейтинг ответов
  • WYSIWYG-редактор Pell
  • Разметка Schema.org
  • Аватары пользователей с поддержкой Gravatar
  • Возможность удаления собственных комментариев
  • Email-уведомления менеджеру сайта, автору публикации, автору комментария об ответах
  • Пагинация (с pdoPage)
  • Работает без jQuery (за исключением связки с pdoPage)
  • Настраиваемые всплывающие уведомления (Notyf из коробки, по остальным см. системные настройки)
  • Приложение в админке с поиском, фильтрацией и возможностью создания / удаления / редактирования (включая ответы разных уровней)
  • Вкладка «Комментарии» у ресурсов с указанными шаблонами
  • Вкладка «Комментарии» у ресурсов с указанными ID
  • Системные события перед созданием комментария и после.
Демо здесь.

Павел Романов
25 декабря 2025, 13:47
modx.pro
1
699
+11

msVK (уведомление о новом заказе в ВК для minishop, готовое решение)

В связи с тем, что идет не хорошая тенденция с отключением мессенджеров, я решил переходить на отечественные решения, а именно в ВК.

На просторах интернета я натыкался на плагин, который делает уведомление в ТГ, имя этому дополнению msTelegram, спасибо большое человеку за его творение.

На его базе сделал свое, но для ВК, поэтому оставлю это здесь больше для себя, но да и вдруг кому будет полезно.

Дмитрий
14 декабря 2025, 09:21
modx.pro
2
285
+2

PdoPage без jQuery

Давно делал костылями пагинацию без jQuery
недавно дошли руки поковырять PdoPage

Скажу сразу в скрипте могут быть баги
У меня с ресурсами работает отлично
ВитОс
01 октября 2025, 18:25
modx.pro
3
935
+8

MODX HTML Cache Plugin

Плагин для MODX, который сохраняет сгенерированные страницы в HTML-файлы и отдает их напрямую без парсинга MODX.
Это позволяет значительно ускорить работу сайта на фронтенде.

ЗЫ: Делался плагин в основном для статики и лендингов!!! (Если в шаблоне есть динамические данные (например, корзина, личный кабинет), лучше исключить его из кэширования.)

Файлы сохраняются в директории:
core/cache/html_pages/{template_id}/
Имя файла формируется так:
{resource_id}_{md5(uri)}.html
vectorserver
30 сентября 2025, 10:18
modx.pro
5
694
+7

Compare - сравнение товаров miniShop2 и MiniShop3

Привет!

UPD 09.02.2026: для MODX 3 и MiniShop3 выпущена платная обновленная версия дополнения: Compare.

Весь текст ниже относится к связке MODX 2 + miniShop2.

Сегодня выложил в github свою наработку с одного из сайтов — дополнение под названием Compare, которое умеет сравнивать товары.



Наумов Алексей
15 августа 2025, 12:37
modx.pro
5
1 551
+11

[MIGX] Исправляем "сжатые" таблицы

Всем привет, есть такая давняя проблема, когда редактируешь ТВ поля MIGX в ресурсах, они изначально «сжаты» влево… Я решил эту проблему, для этого нужен небольшой плагин.


Денис Усманов
05 августа 2025, 14:27
modx.pro
7
2 036
+12