Дата последнего изменения: 13.11.2023
Иногда бывает необходимо повлиять на ход выполнения какой-нибудь API функции. Но если ее изменить, то эти изменения будут утеряны при очередном обновлении. Для таких случаев и разработана система событий. В ходе выполнения некоторых API функций, в определённых точках установлены вызовы определённых функций, так называемых обработчиков события.
Какие функции-обработчики должны быть вызваны в каком месте (при каком событии) - нужно устанавливать вызовом функции, регистрирующей обработчики. В данный момент их две: Bitrix\Main\EventManager::addEventHandler и Bitrix\Main\EventManager::registerEventHandler. Сам набор событий для каждого модуля описан в документации по каждому модулю. Вот, например, ссылка на события главного модуля.
Удаляется с помощью Bitrix\Main\EventManager::unRegisterEventHandler при удалении модуля.
Пример
$eventManager = \Bitrix\Main\EventManager::getInstance();
// функции обработчики модуля компрессии подключаются дважды - в начале и в конце каждой страницы
$eventManager->registerEventHandler("main", "OnPageStart", "compression", "CCompress", "OnPageStart", 1);
$eventManager->registerEventHandler("main", "OnAfterEpilog", "compression", "CCompress", "OnAfterEpilog");
// инсталлятор модуля рекламы регистирует пустой обработчик
// при возникновении события OnBeforeProlog модуль рекламы будет просто подключаться на каждой странице
// что сделает возможным выполнять его API функции без предварительного подключения в теле страницы
$eventManager->registerEventHandler("main", "OnBeforeProlog", "advertising");
Каждый модуль может предоставить другим модулям интерфейс для неявного взаимодействия - набор событий. Такое взаимодействие позволяет сделать модули максимально независимыми друг от друга. Модуль ничего не знает об особенностях функционирования другого модуля, но может взаимодействовать с ним через интерфейс событий.
/bitrix/php_interface/init.php.
Пример
// регистрация обработчика в /bitrix/php_interface/init.php
$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandlerCompatible("main", "OnBeforeUserLogin", "MyOnBeforeUserLoginHandler");
function MyOnBeforeUserLoginHandler($arFields)
{
if(strtolower($arFields["LOGIN"])=="guest")
{
global $APPLICATION;
$APPLICATION->throwException("Пользователь с именем входа Guest не может быть авторизован.");
return false;
}
}
Анонимные функции хорошо подходят для "решить быстро и безболезненно". Чтобы не засорять код именными функциями или классами делаю так:
use Bitrix\Main\EventManager;
$eventManager = EventManager::getInstance();
$eventManager->addEventHandlerCompatible("main", "OnAfterUserLogin", function(&$fields) {
// Мой код
});
Действия, которые вы будете осуществлять с помощью событий должны быть где-то физически прописаны, и они должны быть зафиксированы, что они срабатывают на нужное событие.
registerEventHandler производит регистрацию в БД, а AddEventHandler в файле init.php. То есть использование первой функции приводит к дополнительной нагрузке на БД. Её лучше использовать в ситуациях, когда выполняемые действия должны быть зафиксированы раз и навсегда и именно в БД.
Как правило, события делятся по месту возникновения и назначению на следующие группы:
Совет от Антона Долганина. Если необходимо расширить журнал событий новыми видами событий (например, при действиях с инфоблоками), то нужно использовать обработчик событий OnEventLogGetAuditTypes. Массив, который он вернет, приплюсуется к стандартному массиву в админке. Именно с помощью него дописывает типы модуль Форум, например. |
Список и описание событий, доступных тому или иному модулю размещаются в Документации для разработчика.
Список ссылок по теме: