Yandex Metrika
sanches.free 19 просмотров

Обработчики событий в 1С‑Битрикс: EventManager (D7) и AddEventHandler

Зачем вообще события

В «Битрикс» почти всегда можно обойтись без правок ядра: вместо этого вы подписываетесь на уже объявленный в модуле хук и добавляете свою функцию или метод. Так проще поддерживать обновления и не терять патчи между релизами.

Современная регистрация (ядро D7)

На уровне \Bitrix\Main\EventManager описываются связки «отправитель → модуль → событие → класс/метод». Фактические записи лежат в таблице b_module_to_module; её обычно не трогают руками — достаточно вызова API при установке вашего решения или в init.php на время отладочной сборки.

<?php
use Bitrix\Main\EventManager;

$eventManager = EventManager::getInstance();
$eventManager->registerEventHandler(
    'search',
    'OnReindex',
    'my.vendor',
    '\\Vendor\\Catalog\\SearchHooks',
    'handleReindex'
);

Имена модулей и классов здесь условные: подставьте свой префикс и отдельный класс-хелпер — так проще включать/отключать логику и прогонять статический анализ.

Наследие: AddEventHandler

Старый, но всё ещё встречающийся способ из прологов и сторонних модулей — простой вызов с массивом [класс, метод] или именем процедуры. Пример подписки на событие после успешного входа пользователя:

<?php
AddEventHandler('main', 'OnAfterUserLogin', ['AuthAudit', 'rememberSessionMeta']);

Для большинства задач имеет смысл новым кодом идти через EventManager, а AddEventHandler оставлять там, где проект уже на нём построен — смешивать стили можно, главное держать единые соглашения внутри одного блока функционала.

Популярные точки главного модуля

Полный перечень смотрите в документации по событиям главного модуля. Несколько понятных сценариев:

СобытиеКогда вызываетсяТиповое применение
OnBeforeEndBufferContentПеред финальным сбросом буфера ответаДоработать HTML (например, обработку внешних ссылок) без затрагивания шаблонов.
OnBeforeUserRegisterДо сохранения новой учётной записиВалидация полей, проверки рефералов, санитизация профиля.
OnBeforeUserLoginДо фактической авторизации по логину/паролюЖёсткие запреты, проверки по IP или MFA-обвязку.
OnAfterUserLoginПосле попытки входаОчистка своих кэшей пользователя, лог действий, синхронизация с ERP.

Пример: запрет входа пользователю вне офисной сети

Ниже — учебная заготовка: для логина demo_local мы разрешаем только адреса из частных диапазонов 192.168.* и 10.0.*. В реальности список сетей и учётные данные нужно брать из настроек, а не захардкодить.

<?php
AddEventHandler('main', 'OnBeforeUserLogin', ['LocalLoginPolicy', 'denyOutsideOffice']);

class LocalLoginPolicy
{
    private static string $rejectMessage = 'Доступ с этой машины закрыт политикой безопасности.';

    public static function denyOutsideOffice(&$arFields): bool
    {
        $login = isset($arFields['LOGIN']) ? strtolower((string)$arFields['LOGIN']) : '';
        if ($login !== 'demo_local') {
            return true;
        }

        $clientIp = $_SERVER['REMOTE_ADDR'] ?? '';
        if ($clientIp === '' || preg_match('#^(192\.168\.|10\.0\.)#', $clientIp) !== 1) {
            global $APPLICATION;
            $APPLICATION->throwException(self::$rejectMessage);
            return false;
        }

        return true;
    }
}
  • Значение из throwException можно вывести в шаблоне формы авторизации — проверьте в своей теме, что сообщение действительно читают.
  • Тестируйте с отключённым агентским кешированием и с несколькими IP (VPN, офис Wi‑Fi, мобильный интернет).

Не хотите копаться сами?

Починю за 1-3 дня. Без предоплаты — оплата по результату.

15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии