21  /  430

События

Иногда бывает необходимо повлиять на ход выполнения какой-нибудь API функции. Но если ее изменить, то эти изменения будут утеряны при очередном обновлении. Для таких случаев и разработана система событий. В ходе выполнения некоторых API функций, в определённых точках установлены вызовы определённых функций, так называемых обработчиков события.

Примечание: С обработчиками следует обращаться очень внимательно. Поскольку событийная модель BitrixFramework довольно богатая, то при небрежности в коде обработчика могут появиться трудноуловимые ошибки. Они могут основательно попортить нервы разработчику.

Какие функции-обработчики должны быть вызваны в каком месте (при каком событии) - нужно устанавливать вызовом функции, регистрирующей обработчики. В данный момент их две: AddEventHandler и RegisterModuleDependences. Сам набор событий для каждого модуля описан в документации по каждому модулю. Вот, например, ссылка на события главного модуля.

RegisterModuleDependences - функция для регистрации обработчиков, расположенных в модулях и использующихся для взаимодействия между модулями системы. Эту функцию необходимо вызвать один раз при инсталляции модуля, после этого функция-обработчик события будет автоматически вызываться в определённый момент, предварительно подключив сам модуль.

Удаляется с помощью UnRegisterModuleDependences при удалении модуля.

Пример

// функции обработчики модуля компрессии подключаются дважды - в начале и в конце каждой страницы
RegisterModuleDependences("main", "OnPageStart", "compression", "CCompress", "OnPageStart", 1);
RegisterModuleDependences("main", "OnAfterEpilog", "compression", "CCompress", "OnAfterEpilog");

// инсталлятор модуля рекламы регистирует пустой обработчик
// при возникновении события OnBeforeProlog модуль рекламы будет просто подключаться на каждой странице
// что сделает возможным выполнять его API функции без предварительного подключения в теле страницы
RegisterModuleDependences("main", "OnBeforeProlog", "advertising");

Каждый модуль может предоставить другим модулям интерфейс для неявного взаимодействия - набор событий. Такое взаимодействие позволяет сделать модули максимально независимыми друг от друга. Модуль ничего не знает об особенностях функционирования другого модуля, но может взаимодействовать с ним через интерфейс событий.

AddEventHandler - функция предназначена для регистрации произвольных обработчиков, которые не расположены в модулях. Ее необходимо вызывать до возникновения события на тех страницах, где требуется его обработать. Например, если событие нужно обработать на всех страницах, где оно возникает, то функцию можно вызвать в /bitrix/php_interface/init.php.

Пример

// регистрация обработчика в /bitrix/php_interface/init.php
AddEventHandler("main", "OnBeforeUserLogin", "MyOnBeforeUserLoginHandler");
function MyOnBeforeUserLoginHandler($arFields)
{
   if(strtolower($arFields["LOGIN"])=="guest")
   {
       global $APPLICATION;
       $APPLICATION->throwException("Пользователь с именем входа Guest не может быть авторизован.");
       return false;
   }
}

Различия в использовании функций

Действия, которые вы будете осуществлять с помощью событий должны быть где-то физически прописаны, и они должны быть зафиксированы, что они срабатывают на нужное событие.

RegisterModuleDependences производит регистрацию в БД, а AddEventHandler в файле init.php. То есть использование первой функции приводит к дополнительной нагрузке на БД. Её лучше использовать в ситуациях, когда выполняемые действия должны быть зафиксированы раз и навсегда и именно в БД.


Как правило, события делятся по месту возникновения и назначению на следующие группы:

  • Предназначенные для отмены дальнейшего выполнения метода. Например, событие OnBeforeUserDelete позволяет отменить удаление пользователя при заданных условиях (наличие критических связанных объектов), событие OnBeforeUserLogin - запретить авторизацию пользователю;
  • Позволяющие выполниться в определённых методах, при завершении их исполнения. Например, OnAfterUserLogin - после проверки имени входа и пароля, событие OnUserDelete - перед непосредственным удалением пользователя из БД, позволяет удалить связанные объекты;
  • Возникающие во время исполнения страницы, для того чтобы включить свой код в определённые места на странице. Например, OnBeforeProlog, (подробнее см. порядок выполнения страниц).
Совет от Антона Долганина.

Если необходимо расширить журнал событий новыми видами событий (например, при действиях с инфоблоками), то нужно использовать обработчик событий OnEventLogGetAuditTypes. Массив, который он вернет, приплюсуется к стандартному массиву в админке. Именно с помощью него дописывает типы модуль Форум, например.

Список и описание событий, доступных тому или иному модулю размещаются в Документации для разработчика.

Список ссылок по теме:

28

Если вы нашли неточность в тексте, непонятное объяснение, пожалуйста, сообщите нам об этом в комментариях.
Развернуть комментарии