286  /  382
Справочник

События

Просмотров: 126166
Дата последнего изменения: 13.11.2023
Роберт Басыров
Сложность урока:
3 уровень - средняя сложность. Необходимо внимание и немного подумать.
1
2
3
4
5
Недоступно в лицензиях:
Ограничений нет

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

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

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

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");

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

AddEventHandler - функция предназначена для регистрации произвольных обработчиков, которые не расположены в модулях. Ее необходимо вызывать до возникновения события на тех страницах, где требуется его обработать. Например, если событие нужно обработать на всех страницах, где оно возникает, то функцию можно вызвать в /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. То есть использование первой функции приводит к дополнительной нагрузке на БД. Её лучше использовать в ситуациях, когда выполняемые действия должны быть зафиксированы раз и навсегда и именно в БД.


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

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

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

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

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



56
Курсы разработаны в компании «1С-Битрикс»

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