В 1С-Битрикс в D7 есть два принципиально разных механизма регистрации событий: системные события модулей (через
Bitrix\Main\EventManager) и ORM-события сущностей (через Bitrix\Main\ORM\EventManager). Рассмотрим оба.
1. Регистрация обработчика системного события модуля (D7 EventManager)
Основной класс —\Bitrix\Main\EventManager. У него есть три способа подписки:
1.1. Постоянная регистрация (на время установки модуля) — registerEventHandler
Используется в методахInstallDB() / UnInstallDB() класса-установщика модуля. Обработчик хранится в БД и действует постоянно.
\Bitrix\Main\EventManager::getInstance()->registerEventHandler(
fromModule: 'my.helpdesk', // модуль, который генерирует событие
eventType: 'BeforeTicketClose', // код события
toModuleId: 'my.helpdesk', // ваш модуль-обработчик
toClass: \My\Helpdesk\EventHandler\TicketClosedEventHandler::class, // класс-обработчик
toMethod: 'handle', // метод-обработчик
);
При удалении модуля обработчик нужно снять:
\Bitrix\Main\EventManager::getInstance()->unRegisterEventHandler(
fromModule: 'my.helpdesk',
eventType: 'BeforeTicketClose',
toModuleId: 'my.helpdesk',
toClass: \My\Helpdesk\EventHandler\TicketClosedEventHandler::class,
toMethod: 'handle',
);
1.2. Динамическая регистрация (на время выполнения скрипта) — addEventHandler
Подходит для быстрых хуков, например, вinit.php или компонентах. Не сохраняется в БД.
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
fromModule: 'main', // модуль-источник
eventType: 'OnBuildGlobalMenu', // код события
callback: function(\Bitrix\Main\Event $event) {
// ваш код
}
);
Или с указанием класса/метода:
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
fromModule: 'main',
eventType: 'OnBeforeUserAdd',
callback: ['\My\Module\UserHandler', 'onBeforeUserAdd']
);
1.3. Регистрация для старых (не D7) событий — registerEventHandlerCompatible
Некоторые старые события (например,OnBeforeUserAdd) не используют объект \Bitrix\Main\Event. Для них нужно использовать специальный метод:
\Bitrix\Main\EventManager::getInstance()->registerEventHandlerCompatible(
fromModule: 'main',
eventType: 'OnBeforeUserAdd',
toModuleId: 'my.module',
toClass: \My\Module\EventHandler\OnBeforeUserAddHandler::class,
toMethod: 'handle',
);
Сам обработчик в этом случае получает не объект события, а набор аргументов:
class OnBeforeUserAddEventHandler
{
public static function handle(array &$fields): mixed
{
// Работа с $fields
return true;
}
}
2. Регистрация событий ORM-сущностей (Bitrix\Main\ORM\EventManager)
Отдельный менеджер для событий жизненного цикла ORM-сущностей (OnBeforeAdd, OnAfterAdd, OnBeforeUpdate, OnAfterUpdate, OnBeforeDelete, OnAfterDelete и т.д.).
use Bitrix\Main\ORM\EventManager;
$em = \Bitrix\Main\ORM\EventManager::getInstance();
$em->addEventHandler(
\Bitrix\Main\ORM\Data\DataManager::class, // класс сущности (или конкретный DataManager)
\Bitrix\Main\ORM\Data\DataManager::EVENT_ON_BEFORE_ADD, // код события
function(\Bitrix\Main\ORM\Event $event) {
// ваш код
var_dump('ORM event triggered');
}
);
Также можно указать конкретный класс сущности, например BookTable::class:
$em->addEventHandler(
\My\Module\BookTable::class,
\Bitrix\Main\ORM\Data\DataManager::EVENT_ON_BEFORE_ADD,
function(\Bitrix\Main\ORM\Event $event) {
// ...
}
);
3. Создание и отправка собственного D7-события
Чтобы ваше событие можно было ловить черезaddEventHandler, нужно создать и отправить объект \Bitrix\Main\Event:
$event = new \Bitrix\Main\Event(
'my.helpdesk', // модуль-источник
'TicketClosed', // код события
[ // параметры
'ticketId' => 123,
'closeReason' => 'Решено',
]
);
$event->send();
Обработчик будет получать объект \Bitrix\Main\Event и может возвращать результат через \Bitrix\Main\EventResult:
class TicketClosedEventHandler
{
public static function handle(\Bitrix\Main\Event $event)
{
$ticketId = $event->getParameter('ticketId');
// ... логика ...
return new \Bitrix\Main\EventResult(
\Bitrix\Main\EventResult::SUCCESS,
['result' => true]
);
}
}
Рекомендации
- Постоянную регистрацию (
registerEventHandler) используйте только в установщике модуля (InstallDB()). - Динамическую регистрацию (
addEventHandler) используйте для временных/прототипных решений или вinit.php. - Для событий ORM-сущностей всегда используйте
\Bitrix\Main\ORM\EventManager. - Для старых событий (без D7-формата) —
registerEventHandlerCompatible.