0 руб
Оформить заказСобытия (Events) в OpenCart — это механизм «хуков» (перехватчиков), который позволяет расширять и изменять поведение магазина, не правя файлы ядра. Проще говоря: в нужных местах платформы (до или после выполнения контроллера, модели, формирования вида и т.д.) можно «подвесить» свой обработчик — и он выполнится автоматически. Это даёт мощную и безопасную возможность добавить функциональность, изменять данные или влиять на вывод, не ломая базовую логику магазина.
Главная идея: вместо того, чтобы редактировать чужой код, вы говорите «когда случится X — вызови Y». X — это триггер (например, "catalog/view/common/header/before"), Y — ваш обработчик (контроллер/метод, который что-то сделает).
Почему лучше использовать Events, а не OCMOD
Коротко о преимуществах событийной системы по сравнению с классическими модификациями через OCMOD:
- Нет прямых правок файлов — события не переписывают файлы ядра, поэтому уменьшается риск конфликтов и «сломать» сайт при обновлении.
- Локальность и прозрачность — логика модуля остаётся в его файлах/контроллерах; легче понять, где что выполняется.
- Простота удаления — при корректной реализации "install()"/"uninstall()" можно чисто убрать событие из БД, не оставляя «хвостов».
- Гибкость — можно подписываться на очень разные точки исполнения (контроллеры, модели, сборки вида), менять аргументы по ссылке и контролировать порядок выполнения через "sort_order".
- Меньше конфликтов между расширениями — поскольку нет глобальных патчей файлов, разные расширения реже пересекаются.
- Рекомендуемый подход в OpenCart 4 — в новой ветке событийная модель стала центральным инструментом расширения функционала (поэтому при разработке под OC4 лучше ориентироваться именно на неё).
OCMOD всё ещё может быть полезен (например для массовых правок структуры файлов/шаблонов), но для большинства задач расширения и интеграции Events — более надёжный и современный путь.
Кому будет полезна эта статья
- Разработчикам, которые создают модули под OpenCart 4 и хотят делать это безопасно и устойчиво к обновлениям.
- Администраторам и техподдержке, которым нужно понимать, как работают расширения, чтобы быстрее находить и устранять проблемы.
- Любому, кто хочет иметь «шпаргалку» по типовым триггерам, шаблонам обработчиков и процедурам установки/деинсталляции.
Далее в статье мы шаг за шагом пройдём: как регистрировать события (несколько способов), как писать обработчики (контекст, сигнатуры, работа с аргументами по ссылке), как тестировать и отлаживать, как корректно убирать события при удалении модуля, типичные сценарии и набор готовых шаблонов кода, которые можно будет копировать.
Как зарегистрировать событие: 3 способа
В OpenCart 4 есть несколько способов добавить новое событие. Все они в итоге делают одно и то же — создают запись в таблице "oc_event" и регистрируют обработчик для указанного триггера. Разница лишь в том, где и когда это происходит.
1. Регистрация события в "install()" модуля
Самый классический и безопасный способ.
Мы создаём событие в момент установки модуля, а в "uninstall()" — удаляем его.
Для реализации этого способа нам нужно собрать установочный архив модуля "my_module.ocmod.zip" и установить его через встроенный в админке установщик ("Extensions → Installer")
Пример реализации:
Создаем архив "my_module.ocmod.zip" со следующей структурой:
[code lang=xhtml] my_module.ocmod.zip └── ├── install.json ├── admin/ │ └── controller/ │ └── other/ │ └── my_module.php ├── catalog/ │ ├── controller/ │ │ └── event/ │ │ └── my_module.php │ │ │ └── view/ │ └── stylesheet/ │ └── custom.css [/code]Создаем внутри архива файл: install.json
[code lang=json] { "name": "My Module", "description": "My Module for Opencart 4.", "version": "1.0.0", "author": "uni-opencart", "type": "other", "code": "my_module", "link": "https://opencart-4x.ru" } [/code]Создаем внутри архива файл и папки по пути к нему: admin/controller/other/my_module.php
Добавляем в файл содержимое:
[code lang=php] <?php namespace Opencart\Admin\Controller\Extension\MyModule\Other; class MyModule extends \Opencart\System\Engine\Controller { /** * Index */ public function index(): void { $this->document->setTitle('My Module'); /* Здесь все необходимые настройки модуля */ } /** * Устанавливаем модуль и регистрируем события */ public function install(): void { $this->load->model('setting/event'); // Список событий модуля $event_data = [ [ 'code' => 'my_module_header_after', 'description' => 'My Module: вывод view headerAfter', 'trigger' => 'catalog/view/common/header/after', 'action' => 'extension/my_module/event/my_module.headerAfter', 'status' => 1, 'sort_order' => 0 ], [ 'code' => 'my_module_header_before', 'description' => 'My Module: вывод controller headerBefore', 'trigger' => 'catalog/controller/common/header/before', 'action' => 'extension/my_module/event/my_module.headerBefore', 'status' => 1, 'sort_order' => 0 ] ]; // Удаляем события с такими кодами перед созданием (на случай переустановки) foreach ($event_data as $event) { $this->model_setting_event->deleteEventByCode($event['code']); } // Регистрируем новые события foreach ($event_data as $event) { $this->model_setting_event->addEvent($event); } } /** * Удаляем модуль и все его события */ public function uninstall(): void { $this->load->model('setting/event'); // Список кодов событий для удаления $event_codes = [ 'my_module_header_after', 'my_module_header_before' ]; foreach ($event_codes as $code) { $this->model_setting_event->deleteEventByCode($code); } } } ?> [/code]Обработчик события:
Создаем внутри архива файл и папки по пути к нему: catalog/controller/event/my_module.php
Добавляем в файл содержимое:
[code lang=php] <?php namespace Opencart\Catalog\Controller\Extension\MyModule\Event; class MyModule extends \Opencart\System\Engine\Controller { /** * BEFORE: Получаем аргументы по ссылке и модифицируем их * * string $route — имя маршрута (например, catalog/controller/common/header/before) * array &$args — аргументы, которые передаются в контроллер */ public function headerBefore(string &$route, array &$args): void { // Добавляем CSS-файл в массив $args, если он передан // Но чаще в header можно напрямую использовать document $this->document->addStyle('extension/my_module/catalog/view/stylesheet/custom.css'); } /** * AFTER: здесь меняем уже готовый HTML * * string $route — имя маршрута * array $args — аргументы, переданные в контроллер * string &$output — готовый HTML для вывода */ public function headerAfter(string &$route, array $args, string &$output): void { // Добавляем HTML-блок перед закрывающим тегом </header> $custom_block = '<div class="my-module-banner">Привет из My Module!</div>'; $output = str_replace('</header>', $custom_block . '</header>', $output); } } ?> [/code]Создаем файл стилей модуля, путь: catalog/view/stylesheet/custom.css
[code lang=css] .my-module-banner { background: #ffeb3b; color: #000; padding: 10px; text-align: center; font-weight: bold; } [/code]1. Устанавливаем модуль через установщик.
Переходим в раздел: "Модули / Расширения" → "Установка расширений"
Загружаем наш архив и после загрузки нажимаем "Установить"
После выполнения этого действия файлы нашего архива переместятся в директорию extension/my_module/, где с ними можно работать дальше (добавлять/изменять код и тд) а в таблицу базы данных "oc_extension_install" добавится запись с кодом нашего расширения "my_module", как прописано в install.json
2. Далее переходим в раздел "Модули / Расширения" → "Модули / Расширения", выбираем тип расширения: "Другое"(Other) и активируем модуль "My Module" При активации модуля, в контроллере запускается функция "install()" и события регистрируются в таблице oc_event.
Теперь когда OpenCart рендерит common/header, сначала вызовется headerBefore (можно модифицировать аргументы или документ). После рендеринга — headerAfter, где мы можем модифицировать HTML до отправки клиенту.
3. Для деинсталяции переходим в раздел "Модули / Расширения" → "Модули / Расширения", выбираем тип расширения: "Другое"(Other) и деактивируем модуль "My Module"
При деактивации модуля, запускается функция "uninstall()" и события удаляются из таблицы oc_event.
- Событие регистрируется только при установке модуля.
- Удаление модуля полностью убирает событие из системы.
- Код легко поддерживать и переносить.
2. Регистрация события через Startup (новое в OpenCart 4.1)
В OpenCart 4.1 появилась возможность регистрировать события на лету, прямо из стартового контроллера модуля.
Для этого:
1. При установке модуля регистрируем Startup-обработчик.
2. В методе "index()" этого обработчика вызываем "$this->event->register()".
Для реализации этого способа нам так же как и в предыдущем способе, нужно собрать установочный архив модуля "my_module.ocmod.zip" и установить его через встроенный в админке установщик ("Extensions → Installer")
Но в файле: admin/controller/other/my_module.php необходимо изменить функции install() и uninstall() на код ниже.
А так же, удалить Event контроллер и добавить вместо него Startup контроллер в котором будет происходить регистрация события и выполнение действий.
Регистрация Startup при установке:
В созданном ранее файле: admin/controller/other/my_module.php заменим функции install / uninstall
[code lang=php] public function install(): void { $this->load->model('setting/startup'); // Список Startup обработчиков модуля $startup_data = [ [ 'code' => 'my_module_startup_catalog', 'description' => 'My Module: Startup Catalog', 'action' => 'catalog/extension/my_module/startup/my_module', 'status' => 1, 'sort_order' => 0 ] ]; // Удаляем Startup с такими кодами перед созданием (на случай переустановки) foreach ($startup_data as $startup) { $this->model_setting_startup->deleteStartupByCode($startup['code']); } // Регистрируем новые Startup-обработчики foreach ($startup_data as $startup) { $this->model_setting_startup->addStartup($startup); } } public function uninstall(): void { $this->load->model('setting/startup'); // Список кодов Startup для удаления $startup_codes = [ 'my_module_startup_catalog' ]; foreach ($startup_codes as $code) { $this->model_setting_startup->deleteStartupByCode($code); } } [/code]Startup-контроллер с регистрацией события:
Создаем внутри архива файл и папки по пути к нему: catalog/controller/startup/my_module.php
Добавляем в файл содержимое:
[code lang=php] <?php namespace Opencart\Catalog\Controller\Extension\MyModule\Startup; class MyModule extends \Opencart\System\Engine\Controller { public function index(): void { //Регистрируем события $this->event->register( 'controller/common/header/before', new \Opencart\System\Engine\Action('extension/my_module/startup/my_module.headerBefore') ); $this->event->register( 'view/common/header/after', new \Opencart\System\Engine\Action('extension/my_module/startup/my_module.headerAfter') ); } /** * BEFORE: Получаем аргументы и модифицируем их * * string $route — имя маршрута (например, catalog/controller/common/header/before) * array &$args — аргументы, которые передаются в контроллер */ public function headerBefore(string &$route, array &$args): void { // Добавляем CSS-файл в массив $args, если он передан // Но чаще в header можно напрямую использовать document $this->document->addStyle('extension/my_module/catalog/view/stylesheet/custom.css'); } /** * AFTER: здесь меняем уже готовый HTML * * string $route — имя маршрута * array $args — аргументы, переданные в контроллер * string &$output — готовый HTML для вывода */ public function headerAfter(string &$route, array $args, string &$output): void { // Добавляем HTML-блок перед закрывающим тегом </header> $custom_block = '<div class="my-module-banner">Привет из My Module!</div>'; $output = str_replace('</header>', $custom_block . '</header>', $output); } } ?> [/code] Плюсы способа:- Гибкость — можно регистрировать события динамически в зависимости от условий.
- Подходит для временных событий (только на время работы модуля).
- Событие будет регистрироваться при каждом запуске Startup (немного дороже по производительности).
- Если Startup отключить в админке — событие перестанет работать.
3. Регистрация напрямую в базе данных или через менеджер событий в админке
Третий способ — просто добавить запись в таблицу "oc_event":
[code lang=sql] INSERT INTO "oc_event" ("code", "description", "trigger", "action", "status", "sort_order") VALUES ('my_module_header_after', 'My Module: View Header After', 'catalog/view/common/header/after', 'extension/my_module/event/my_module.headerAfter', 1, 0); INSERT INTO "oc_event" ("code", "description", "trigger", "action", "status", "sort_order") VALUES ('my_module_header_before', 'My Module: Controller Header Before', 'catalog/controller/common/header/before', 'extension/my_module/event/my_module.headerBefore', 1, 0); [/code]Или же — установить и использовать "Модуль менеджер событий Events для Opencart 4", в админке ("Extensions → Event Manager") и добавить событие вручную.
Для реализации этого способа нам не нужно собирать установочный архив модуля и устанавливать его в admin/.
Достаточно создать обработчик события в catalog/, файл и папки по пути к нему: catalog/controller/event/my_module.php, с содержимым как описано в первом способе.
- Можно быстро протестировать обработчик без написания install-кода.
- Удобно для единоразовых правок или отладки.
- Легко забыть удалить событие при отключении/удалении модуля.
- Не подходит для автоматической установки расширений.
Какой способ выбрать
- Для стабильных модулей — всегда через "install()"/"uninstall()".
- Для динамических задач (например, загрузка ассетов или временные перехваты) — через "Startup".
- Для тестов и отладки — через SQL или установленный модуль в админке "Менеджер событий".
Заключение и рекомендации
Система событий (Event) в OpenCart 4 позволяет модифицировать логику магазина без правок ядра, что делает код чище и упрощает обновления.
Главные правила, которые стоит запомнить:
- Всегда используйте уникальные коды событий для каждого модуля.
- При переустановке модуля удаляйте старые события, чтобы избежать дубликатов.
- Используйте before для изменения входных данных и after для модификации результата.
- Тестируйте работу событий на тестовом окружении перед применением на боевом магазине.
Еще никто не написал комментарий, вы можете быть первым.