Skip to content
ms3PromoCode
ms3PromoCode
Промо-коды для MiniShop3 с гибкими правилами, генерацией по маске и интеграцией в позиции заказа
  • MODX 3
  • PHP 8.2
  • miniShop3
  1. Компоненты
  2. ms3PromoCode
  3. Разработка
  4. События плагина

События плагина ​

ms3PromoCode — один MODX-плагин, который слушает события MiniShop3 и MODX.

Список подписок ​

СобытиеКогдаЧто делает плагин
OnLoadWebDocumentВывод страницы на фронтеРегистрирует JS/CSS по пресету frontend_assets_preset
msOnAddToCartПокупатель добавил товар в корзинуsyncAfterCartChange — пересчитать или снять код
msOnChangeInCartИзменено количество позицииТо же
msOnChangeOptionInCartИзменены или удалены опции уже добавленной позицииТо же
msOnRemoveFromCartУдалена позиция из корзиныТо же
msOnCreateOrderProductМенеджер добавил позицию в заказ через прежнюю админкуТо же (новая Vue-админка использует JS-перехватчик)
msOnUpdateOrderProductТо же — изменение позицииТо же
msOnRemoveOrderProductТо же — удаление позицииТо же
msOnCreateOrderПокупатель оформил заказrecordApplication — фиксация в ms3_promo_code_usages
msOnChangeOrderStatusИзменён статус заказаОткат или восстановление применения по cancel_statuses
msOnManagerCustomCssJsЗагрузка страницы редактирования заказаПодключение order-tab.js — вкладка «Промо-код»

syncAfterCartChange ​

События изменения корзины (msOnAddToCart, msOnChangeInCart, msOnChangeOptionInCart, msOnRemoveFromCart) и правки позиций заказа из админки (msOnCreateOrderProduct, msOnUpdateOrderProduct, msOnRemoveOrderProduct) идут через ApplicationService::syncAfterCartChange($order):

  1. Если в properties.promo_code нет применённого кода — ничего не делает.
  2. Иначе — вызывает apply($order, $code) повторно с тем же кодом. Проверка (жизненный цикл, min_order_amount, правила) запускается заново, уценка пересчитывается по текущему составу корзины. Внутренние шаги apply — на странице Сервисы.
  3. Если новый состав корзины уже не подходит коду, apply возвращает ошибку, плагин вызывает remove($order) и снимает применение. Фронтовое событие ms3promocode:auto-removed формирует само headless-ядро — оно сравнивает кэш с ответом GET /api/v1/promo/current после ms3:cart:updated и посылает событие, если код исчез.

Сохранённая цена позиции и внешние плагины

Между apply и следующей синхронизацией цену позиции может переписать сторонний плагин — например, ms3Variants при смене опции. Тогда properties.ms3promocode.original_price устаревает: для повторного применения берётся текущая price, а не сохранённое значение. При remove в этой же ситуации сохранённая цена чистится без «восстановления» прежней — текущая остаётся как есть.

При автоматическом снятии кода с заказа (события из админки) в msOrderLog пишется запись:

json
{
    "operation": "ms3promocode_auto_remove",
    "reason": "min_order",
    "message": "Сумма заказа меньше требуемого минимума (5 000 ₽)"
}

Какие события не используются ​

  • msOnGetCartCost — не используется. Сумма корзины уже считается из msOrderProduct.cost (модель «уценка позиций»); вычитать скидку ещё раз из агрегата — двойная скидка.
  • msOnGetProductPrice — не используется. Скидки не применяются к отдельным товарам вне контекста корзины.

Свои события компонента ​

Headless-ядро на фронтенде посылает на document DOM-события (см. JS API):

СобытиеКогда
ms3promocode:readyHeadless-ядро инициализировано
ms3promocode:appliedКод успешно применён
ms3promocode:removedКод успешно снят
ms3promocode:auto-removedКод автоматически снят при изменении корзины
ms3promocode:errorОшибка операции

Подписка:

js
document.addEventListener('ms3promocode:applied', (e) => {
    console.log(e.detail.code, e.detail.discount);
});

Подписка на события из своего плагина ​

Чтобы реагировать на применение кода, подпишитесь на стандартные события MiniShop3 — их данные уже содержат всё нужное.

Пример: своё уведомление о применении ​

php
// elements/plugins/myplugin.php
$eventName = $modx->event->name;

if ($eventName === 'msOnCreateOrder') {
    /** @var \MiniShop3\Model\msOrder $order */
    $order = $scriptProperties['msOrder'];
    $properties = $order->get('properties');

    if (!empty($properties['promo_code'])) {
        $code = $properties['promo_code']['code'];
        $discount = $properties['promo_code']['discount_amount'];

        // ... отправить в Telegram, метрику и т.п.
        myNotifier()->send("Применён код {$code}, скидка {$discount}");
    }
}

Пример: запрет применения определённого кода ​

php
// Проверка перед применением на уровне плагина
if ($eventName === 'msOnCreateOrder') {
    $order = $scriptProperties['msOrder'];
    $properties = $order->get('properties');
    $code = $properties['promo_code']['code'] ?? null;

    if ($code === 'BANNED-CODE') {
        // Снять код принудительно
        /** @var \ms3PromoCode\Services\ApplicationService $svc */
        $svc = $modx->services->get('ms3promocode_application_service');
        $svc->remove($order);
    }
}

Внимание

Своего обработчика перед применением с возможностью отмены ms3PromoCode не даёт — только события после факта. Если нужна отмена до применения — заведите задачу в issue tracker.