new

Reactions

Реакции для MODX 3: от 👍/👎 до набора в стиле GitHub
Бесплатно
Загрузите дополнение из админки вашего сайта.
Как загрузить?
Автор дополнения
Иван Бочкарев
Пакетов
20
Закачек
132
Автор дополнения
Пакетов
20
Закачек
132
Версия 1.0.0-pl
Дата выпуска 14.07.2026
Загрузки 0
Просмотры 2
Внимание, этот компонент требует PHP 8.2 или выше!
Внимание, этот компонент требует MODX 3 или выше.
Reactions — реакции для MODX 3 на ресурс, товар miniShop3 или комментарий Tickets: от 👍/👎 до набора в стиле GitHub и полного списка из 24 эмодзи. Headless: UI менеджера нет. Настройки системы, REST API и CLI.

Возможности
  • Наборыupdown (👍/👎, exclusive); github (👍👎❤️😂😮😢😡🎉); full (24 типа, в т.ч. 🚀👀🔥👏🤔🥳⭐🍺✨💯🙏💪😎😍😕🙌). Подмножество через настройку reactions_full_types или параметр &types=
  • Layout виджетаauto (picker при >3 типах), picker (чипы + кнопка + / popover), bar (все кнопки в ряд)
  • Любой объектmodResource, msProduct, TicketComment; в API/сниппетах class / class_key, в БД поле object_class
  • Идентификация — auth_only, IP, IP+Cookie, Session; exclusive и allow_multiple
  • Топы и trending — периоды day/week/month/year/all; формула Reddit
  • Защита — rate limit, anti-bot, CSRF, Origin check, replay protection
  • Интеграции — события MODX, webhooks (Telegram / Discord / Slack), уведомления автору, JSON-LD AggregateRating, pdoTools leftJoin по агрегатам
  • Свои типы — CLI или admin REST без Vue-админки

Сниппеты
  • Reactions
    — виджет с кнопками / picker и AJAX-счётчиками
  • ReactionsCount
    — текстовые счётчики: {TOTAL}, {LIKES}, {DISLIKES}, {RATING}, {love}, {fire}
  • TopLiked
    — топ по числу лайков
  • TopRated
    — топ по рейтингу (likes − dislikes)
  • Trending
    — горячие материалы
  • ReactionsSchema
    — JSON-LD AggregateRating для SEO

Подключение ассетов
<link rel="stylesheet" href="{'assets_url' | config}components/reactions/js/web/reactions.css">
<script src="{'assets_url' | config}components/reactions/js/web/reactions.js" defer></script>

Примеры вызовов

Виджет на ресурсе (MODX):


{'!Reactions' | snippet : ['set' => 'github', 'object' => $_modx->resource.id]}
{'!Reactions' | snippet : ['set' => 'updown', 'object' => $_modx->resource.id]}

{'!Reactions' | snippet : ['set' => 'github', 'layout' => 'bar', 'object' => $_modx->resource.id]}

{'!Reactions' | snippet : ['set' => 'full', 'types' => 'like,love,fire,star', 'object' => $_modx->resource.id]}

Счётчики без кнопок:


{'!ReactionsCount' | snippet}

{'!ReactionsCount' | snippet : [
    'format' => 'Всего {TOTAL}: 👍 {LIKES} / 👎 {DISLIKES}',
]}

{'!ReactionsCount' | snippet : [
    'format' => '❤️ {love}',
]}

{'!ReactionsCount' | snippet : [
    'format' => '❤️ {love} · 🔥 {fire} · ⭐ {star} · 🚀 {rocket}',
]}

Топы и схема:


{'!TopLiked' | snippet : ['period' => 'day', 'limit' => 5]}
{'!TopLiked' | snippet : ['period' => 'month', 'limit' => 5]}
{'!TopLiked' | snippet : ['period' => 'all', 'limit' => 10]}

{'!TopRated' | snippet : ['period' => 'month', 'limit' => 10]}
{'!TopRated' | snippet : ['period' => 'year', 'limit' => 10]}

{'!Trending' | snippet : ['period' => 'all', 'limit' => 3]}

{raw ('!ReactionsSchema' | snippet : [
    'class'   => 'msProduct',
    'object'  => $_modx->resource.id,
    'context' => 'web',
])}

miniShop3 (карточка + сортировка каталога):


{'!Reactions' | snippet : [
    'class'   => 'msProduct',
    'object'  => $_modx->resource.id,
    'set'     => 'github',
    'context' => 'web',
]}

{'!Reactions' | snippet : [
    'class'  => 'msProduct',
    'object' => $_modx->resource.id,
    'set'    => 'updown',
]}

{'!ReactionsCount' | snippet : [
    'class'  => 'msProduct',
    'object' => $id,
    'format' => '👍 {LIKES}',
]}

{'!msProducts' | snippet : [
    'parents' => 10,
    'limit' => 12,
    'leftJoin' => '{"Aggregate":{"class":"Reactions\\Model\\ReactionAggregate","on":"Aggregate.object_id = msProduct.id AND Aggregate.object_class = \'msProduct\'"}}',
    'sortby' => 'Aggregate.likes',
    'sortdir' => 'DESC',
    'tpl' => 'tpl.msProduct.card',
]}

Три шага до результата
  1. Установите транспортный пакет. Подключите CSS и JS (см. выше).
  2. Вызовите [[!Reactions? &set=`github`]].
  3. Кликните реакцию в виджете — счётчики обновятся через AJAX.

CLI
php core/components/reactions/cli.php recount
php core/components/reactions/cli.php type create --name=favorite --emoji=⭐
php core/components/reactions/cli.php ban add --ip=203.0.113.10
php core/components/reactions/cli.php stats

Для кого
  • Контент и блоги — лайки и emoji на ресурсах, топы недели
  • Магазины на miniShop3 — реакции на msProduct, сортировка по likes
  • Разработчики — REST, CLI, кастомные наборы, schema.org

Требования: MODX 3.0+, PHP 8.2–8.4, MySQL/MariaDB (InnoDB).

Документация: docs.modx.pro/components/reactions/ — установка, настройки, сниппеты, API, JS-виджет, CLI.

Скриншоты




Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[1.0.0-pl] - 2026-07-13

Fixed

  • Порядок resolvers при установке: таблицы создаются до сидинга пресетов типов/наборов
  • CacheService: корректный TTL для xPDO (lifetime, не options-массив)
  • IdentityResolver: IP из $modx->request (не boolean от getRequest())
  • Связи модели / загрузка типов: FQCN в metaMap; counts нормализуются из JSON/string
  • Поле class_key в таблицах реакций переименовано в object_class (конфликт с STI xPDO); API/сниппеты по-прежнему принимают class / class_key
  • ObjectLookup: короткие алиасы (msProduct, TicketComment) резолвятся в FQCN / STI без вызова xPDO по незарегистрированному короткому классу
  • CLI / api.php: поиск корня MODX при симлинке Extra; сортировки type/ban/set через newQuery (xPDO 3)
  • getCounts: без долгого кеша карты счётчиков (SSR ReactionsCount не отставал от AJAX-виджета); CountFormat подставляет ключи по убыванию длины
  • CountFormat: неизвестный плейсхолдер типа ({love}…) → 0, не сырой текст
  • Виджет: exclusive = набор exclusive или !allow_multiple; синхронизация соседних виджетов (reactions:updated); SSR-классы кнопок совпадают с JS
  • Dev-resolver симлинков: сайт → Extras/Reactions (исходники остаются в git)

    Removed

  • Настройка reactions_allowed_classes и серверный allowlist class_key: класс объекта задаётся в вызове сниппета/API; при апгрейде настройка удаляется

Added

  • Каркас пакета для MODX 3 (структура ModExtra3): bootstrap, DI-сервис Reactions, _build, лексиконы en/ru
  • Системные настройки: набор по умолчанию, reactions_full_types, стратегия идентификации, allow_multiple, rate limit, кэш, webhooks, уведомления, блокировка ботов
  • Модель xPDO 3 (InnoDB): ReactionType, ReactionSet, ReactionSetType, Reaction, ReactionAggregate, ReactionBan
  • Пресеты наборов updown (👍/👎), github (👍👎❤️😂😮😢😡🎉) и full (24 типа, в т.ч. 🚀👀🔥👏🤔🥳⭐🍺✨💯🙏💪😎😍😕🙌) при установке; подмножество full через настройку / &types=
  • Сервисы: ReactionService, IdentityResolver, RateLimiter, BotDetector, AggregateService, TrendingCalculator, WebhookDispatcher, NotificationService, CacheService
  • События MODX: OnBeforeReaction, OnAfterReaction, OnReactionRemoved, OnReactionChanged
  • AJAX/REST API (assets/components/reactions/api.php): counts, react, top, trending, latest, csrf; admin CRUD типов/наборов/банов и stats
  • Безопасность API: CSRF, Origin check, nonce (replay protection), rate limit
  • Сниппеты: Reactions, ReactionsCount, TopLiked, TopRated, Trending, ReactionsSchema
  • TypeScript-виджет (Vite): оптимистичные обновления, ARIA, клавиатура; автоопределение URL API; data-types для подмножества кнопок; data-exclusive / data-allow-multiple; layout picker/bar/auto (чипы + popover для github/full; Escape / клик снаружи)
  • _build/build.php: сборка фронтенда (frontend/assets/…/js/web/) в шаге assets()
  • CLI: recount, cleanup, export, type, set, ban, stats
  • Документация: сниппеты, интеграции (pdoTools, miniShop3, Tickets, Collections, SEO), API, JS, CLI, события, webhooks
  • Тесты Pest (unit) и Vitest (frontend); GitHub Actions CI на PHP 8.2–8.4

Requirements

  • MODX Revolution 3.x
  • PHP 8.2+

Последние обсуждения в сообществе MODX.pro