← Назад к справке

Модули

События в модуле

Рабочая справка по событиям в локальном модуле Bitrix: регистрация при установке, удаление обработчиков, CRM-события, OnProlog и ORM-события.

События лучше регистрировать при установке модуля и удалять при удалении. Не стоит каждый раз добавлять обработчики в include.php без необходимости.

Общее понимание

События позволяют модулю реагировать на действия ядра, CRM, ORM и других модулей.

Какие бывают события

Тип Пример Когда использовать
События ядра OnProlog, OnEpilog Подключение JS/CSS, общая логика на страницах.
События CRM OnAfterCrmDealUpdate Реакция на изменение сделок, лидов, контактов, компаний.
ORM-события OnBeforeAdd, OnAfterUpdate Логика вокруг своих ORM-таблиц.
Свои события OnAfterExampleSync Когда модуль должен дать точку расширения для другого кода.

Где регистрировать

Постоянные обработчики удобно регистрировать в installEvents() установщика и удалять в uninstallEvents(). Временные обработчики на один хит можно добавлять через addEventHandler(), но это другой сценарий.

Регистрация событий

Пример регистрации обработчиков в установщике модуля.

installEvents

<?php

use Bitrix\Main\EventManager;

class test_example extends CModule
{
    public $MODULE_ID = 'test.example';

    /**
     * Регистрирует обработчики событий.
     */
    public function installEvents(): bool
    {
        $event_manager = EventManager::getInstance();

        $event_manager->registerEventHandler(
            'crm',
            'OnAfterCrmDealUpdate',
            $this->MODULE_ID,
            \test\Example\EventHandler\CrmDealHandler::class,
            'onAfterDealUpdate'
        );

        $event_manager->registerEventHandler(
            'main',
            'OnProlog',
            $this->MODULE_ID,
            \test\Example\EventHandler\AssetHandler::class,
            'onProlog'
        );

        return true;
    }
}

uninstallEvents

<?php

use Bitrix\Main\EventManager;

class test_example extends CModule
{
    public $MODULE_ID = 'test.example';

    /**
     * Удаляет обработчики событий.
     */
    public function uninstallEvents(): bool
    {
        $event_manager = EventManager::getInstance();

        $event_manager->unRegisterEventHandler(
            'crm',
            'OnAfterCrmDealUpdate',
            $this->MODULE_ID,
            \test\Example\EventHandler\CrmDealHandler::class,
            'onAfterDealUpdate'
        );

        $event_manager->unRegisterEventHandler(
            'main',
            'OnProlog',
            $this->MODULE_ID,
            \test\Example\EventHandler\AssetHandler::class,
            'onProlog'
        );

        return true;
    }
}

Класс обработчика

Обработчики удобно хранить отдельно в lib/EventHandler.

/local/modules/test.example/lib/EventHandler/
├── CrmDealHandler.php
└── AssetHandler.php

Не забудь зарегистрировать эти классы в автозагрузке модуля.

Примеры

Несколько типовых обработчиков, которые часто нужны в локальных модулях.

Событие CRM

<?php

namespace test\Example\EventHandler;

class CrmDealHandler
{
    /**
     * Обрабатывает изменение сделки.
     */
    public static function onAfterDealUpdate(array &$deal_fields): void
    {
        $deal_id = isset($deal_fields['ID']) ? (int) $deal_fields['ID'] : 0;

        if ($deal_id <= 0) {
            return;
        }

        AddMessage2Log(
            [
                'message' => 'Сделка изменена',
                'deal_id' => $deal_id,
                'fields' => $deal_fields,
            ],
            'test_example'
        );
    }
}

Если обработчик внутри себя меняет ту же сделку, добавь защиту от повторного запуска.

Событие OnProlog

<?php

namespace test\Example\EventHandler;

use Bitrix\Main\Context;
use Bitrix\Main\Page\Asset;

class AssetHandler
{
    /**
     * Подключает ресурсы модуля на страницах CRM.
     */
    public static function onProlog(): void
    {
        $request_uri = (string) Context::getCurrent()->getRequest()->getRequestUri();

        if (strpos($request_uri, '/crm/') === false) {
            return;
        }

        Asset::getInstance()->addCss('/local/css/test.example/app.css');
        Asset::getInstance()->addJs('/local/js/test.example/app.js');
    }
}

ORM-событие

Для своей ORM-таблицы можно описать методы событий прямо в Table-классе.

<?php

namespace test\Example\Model;

use Bitrix\Main\Entity;
use Bitrix\Main\ORM\Event;
use Bitrix\Main\ORM\EventResult;
use Bitrix\Main\ORM\Fields;

class ExampleTable extends Entity\DataManager
{
    /**
     * Возвращает имя таблицы.
     */
    public static function getTableName(): string
    {
        return 'b_test_example_item';
    }

    /**
     * Возвращает карту полей.
     */
    public static function getMap(): array
    {
        return [
            new Fields\IntegerField('ID', [
                'primary' => true,
                'autocomplete' => true,
            ]),
            new Fields\StringField('TITLE'),
        ];
    }

    /**
     * Проверяет данные перед добавлением.
     */
    public static function onBeforeAdd(Event $event): EventResult
    {
        $result = new EventResult();
        $fields = $event->getParameter('fields');

        if (empty($fields['TITLE'])) {
            $result->addError(
                new Entity\FieldError(
                    static::getEntity()->getField('TITLE'),
                    'Название не заполнено'
                )
            );
        }

        return $result;
    }
}

Источники