sanches.free
14 просмотров
События Bitrix D7 вне ORM: EventManager и цепочка EventResult
Зачем это нужно
Помимо ORM-хуков у ядра D7 остаются «плоские» точки расширения: имя модуля, имя события и массив параметров. Их используют кастомные модули, мосты к внешним API и временные решения там, где важнее явный контракт, чем рефлексия таблицы.
Регистрация слушателя
EventManager::addEventHandler навешивает коллбек на пару модуль/событие. Внутри обработчика уместно учитывать результаты, которые уже успели добавить более ранние подписчики: ошибки этого типа пропускают, успешные — сливают в рабочий массив.
namespace Acme\Bridge;
use Bitrix\Main\Event;
use Bitrix\Main\EventManager;
use Bitrix\Main\EventResult;
EventManager::getInstance()->addEventHandler(
'acme.notifications',
'OnRecipientsFilterNormalize',
static function (Event $pulse): EventResult {
$carrier = (array) $pulse->getParameter(0);
foreach ($pulse->getResults() as $slot) {
if ($slot->getType() === EventResult::ERROR) {
continue;
}
if ($slot->getParameters()) {
$carrier = $slot->getParameters();
}
}
$carrier['SITE_ID'] = ['s1', 's2'];
return new EventResult($pulse->getEventType(), $carrier);
}
);
$dispatch = new Event('acme.notifications', 'OnRecipientsFilterNormalize', [$draft]);
$dispatch->send();
foreach ($dispatch->getResults() as $slot) {
if ($slot->getType() === EventResult::ERROR) {
continue;
}
$draft = array_merge($draft, (array) $slot->getParameters());
}
$named = new Event('partner.orders', 'OnPackagePrepared', ['ENTITY' => $draft]);
$named->send();Эксплуатация
- Тяжёлые задачи после событий выносят в агенты или очереди, оставив само событие лёгким координатором.
- Между модулями не стоит полагаться на неявный порядок выполнения подписчиков без явной договорённости или приоритета регистрации.
Не хотите копаться сами?
Починю за 1-3 дня. Без предоплаты — оплата по результату.
15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии