EventManager в Битрикс: что это такое и как с ним работать
ОглавлениеЧто такое EventManagerЗачем использовать EventManagerПодключение EventManagerРегистрация обработчика событияСоздание класса обработчиковГде регистрировать событияСобытия пользователейСобытия инфоблоковСобытия заказов интернет-магазинаСоздание собственного событияПодписка на собственное событиеИспользование EventResultORM-события DataManagerУдаление обработчикаТипичные ошибки при работе с EventManagerРекомендации по использованию EventManagerЗаключение
При разработке проектов на 1С-Битрикс часто возникает необходимость выполнять определенные действия при наступлении событий системы. Например, отправить уведомление после регистрации пользователя, изменить данные заказа перед сохранением или очистить кеш после обновления элемента инфоблока. Для решения подобных задач в Битрикс используется EventManager — современный механизм работы с событиями в D7 API.
В этой статье подробно рассмотрим, что такое EventManager, как он работает и как создавать собственные обработчики событий с примерами кода.
Что такое EventManager
EventManager — это класс D7 API, предназначенный для регистрации и обработки событий системы. Класс находится в пространстве имен:Bitrix\Main\EventManager
С помощью EventManager можно:
- подписываться на системные события;
- создавать собственные события;
- подключать обработчики модулей;
- изменять данные до сохранения;
- выполнять действия после изменения данных;
- организовывать слабосвязанный код.
Зачем использовать EventManager
Без событий разработчикам пришлось бы изменять ядро системы или вносить правки в сторонние модули. Использование EventManager позволяет:- не изменять ядро Битрикс;
- создавать расширяемую архитектуру;
- упрощать поддержку проекта;
- разделять бизнес-логику;
- безопасно обновлять систему.
Подключение EventManager
Для работы необходимо подключить класс:use Bitrix\Main\EventManager;
Получение экземпляра менеджера событий:
$eventManager = EventManager::getInstance();
Через этот объект выполняется регистрация обработчиков.
Регистрация обработчика события
Самый распространенный способ — методaddEventHandler().
Пример:
use Bitrix\Main\EventManager;
EventManager::getInstance()->addEventHandler(
'main',
'OnBeforeUserAdd',
['UserHandlers', 'onBeforeUserAdd']
);
Где:
main— модуль;OnBeforeUserAdd— событие;UserHandlers::onBeforeUserAdd()— обработчик.
Создание класса обработчиков
Обычно обработчики выносят в отдельный класс. Пример:namespace Local\EventHandlers;
class UserHandlers
{
public static function onBeforeUserAdd(&$fields)
{
$fields['LOGIN'] = trim($fields['LOGIN']);
}
}
Такой подход делает код более структурированным и удобным для поддержки.
Где регистрировать события
Чаще всего регистрация выполняется в файле:/local/php_interface/init.php
Пример:
use Bitrix\Main\EventManager;
use Local\EventHandlers\UserHandlers;
EventManager::getInstance()->addEventHandler(
'main',
'OnBeforeUserAdd',
[UserHandlers::class, 'onBeforeUserAdd']
);
Для крупных проектов рекомендуется выполнять регистрацию в модуле.
События пользователей
Одни из наиболее популярных событий относятся к пользователям.Перед созданием пользователя
OnBeforeUserAdd
Пример:
public static function onBeforeUserAdd(&$fields)
{
$fields['LOGIN'] = strtolower($fields['LOGIN']);
}
После создания пользователя
OnAfterUserAdd
Пример отправки уведомления:
public static function onAfterUserAdd(&$fields)
{
if ($fields['ID'])
{
// отправка уведомления
}
}
Перед обновлением пользователя
OnBeforeUserUpdate
Позволяет изменить данные до сохранения.
События инфоблоков
При работе с контентом чаще всего используются события инфоблоков.Перед добавлением элемента
OnBeforeIBlockElementAdd
Пример генерации символьного кода:
public static function onBeforeElementAdd(&$fields)
{
if (empty($fields['CODE']))
{
$fields['CODE'] = translit($fields['NAME']);
}
}
После добавления элемента
OnAfterIBlockElementAdd
Перед обновлением элемента
OnBeforeIBlockElementUpdate
После обновления элемента
OnAfterIBlockElementUpdate
Эти события активно используются в SEO-проектах и интернет-магазинах.
События заказов интернет-магазина
Для модуля интернет-магазина доступны собственные события. Например:OnSaleOrderBeforeSaved
Пример:
public static function onBeforeOrderSave($event)
{
$order = $event->getParameter('ENTITY');
}
Через событие можно:
- проверять данные заказа;
- изменять свойства;
- рассчитывать скидки;
- отправлять уведомления.
Создание собственного события
EventManager позволяет создавать пользовательские события. Создание события:use Bitrix\Main\Event;
$event = new Event(
'local.module',
'OnProductImported',
[
'PRODUCT_ID' => 15
]
);
$event->send();
Теперь любой модуль может подписаться на это событие.
Подписка на собственное событие
Регистрация обработчика:EventManager::getInstance()->addEventHandler(
'local.module',
'OnProductImported',
['ProductHandlers', 'onImport']
);
Обработчик:
class ProductHandlers
{
public static function onImport($event)
{
$productId = $event->getParameter('PRODUCT_ID');
}
}
Таким образом можно организовать взаимодействие между модулями без жестких зависимостей.
Использование EventResult
Иногда необходимо вернуть данные обратно в событие. Для этого используется класс:Bitrix\Main\EventResult
Пример:
use Bitrix\Main\EventResult;
return new EventResult(
EventResult::SUCCESS,
[
'NAME' => 'Новое значение'
]
);
Этот механизм активно применяется внутри D7 ORM.
ORM-события DataManager
Каждая ORM-сущность поддерживает собственные события. Например:Перед добавлением записи
onBeforeAdd
После добавления
onAfterAdd
Перед обновлением
onBeforeUpdate
После удаления
onAfterDelete
Пример:
public static function onBeforeAdd($event)
{
$fields = $event->getParameter('fields');
}
Это позволяет реализовывать бизнес-логику непосредственно внутри ORM-сущностей.
Удаление обработчика
Если необходимо убрать обработчик:$handlerId = EventManager::getInstance()->addEventHandler(
'main',
'OnBeforeUserAdd',
['UserHandlers', 'handler']
);
EventManager::getInstance()->removeEventHandler(
'main',
'OnBeforeUserAdd',
$handlerId
);
Такой подход полезен при динамическом управлении событиями.
Типичные ошибки при работе с EventManager
Обработчик не вызывается
Следует проверить:- правильность названия события;
- регистрацию обработчика;
- namespace класса;
- подключение файла.
Класс не найден
Необходимо проверить автозагрузку:Loader::registerAutoLoadClasses()
или настройки Composer.
Изменения не применяются
Иногда проблема связана с кешированием или тем, что используется неправильное событие. Например, изменения после сохранения нельзя выполнять в обработчикеOnAfter..., если требуется изменить сохраняемые данные.
Рекомендации по использованию EventManager
Для крупных проектов рекомендуется:- хранить обработчики в отдельных классах;
- использовать пространства имен;
- избегать тяжелых запросов внутри событий;
- логировать ошибки обработчиков;
- создавать собственные события для интеграций.