Короткий ответ — да, можно. В Битриксе все «слушатели» событий вызываются через механизм событий, и вы можете программно инициировать их вызов, если знаете модуль/имя события и параметры, которые слушатели ожидают.
Два основных способа.
1) Старый/совместимый способ (GetModuleEvents + ExecuteModuleEventEx)
- Получаете список зарегистрированных обработчиков и вызываете каждый через ExecuteModuleEventEx.
- Удобно, если обработчики были зарегистрированы через AddEventHandler / RegisterModuleDependences и/или ожидают параметры по ссылке.
Пример (для инфоблока, OnAfterIBlockElementUpdate):
<?
$ID = 123;
$arFields = CIBlockElement::GetByID($ID)->GetNext(); // подготовьте данные, как ожидают обработчики
$arHandlers = GetModuleEvents("iblock", "OnAfterIBlockElementUpdate");
foreach ($arHandlers as $handler) {
// Если обработчики ожидают параметры по ссылке, передавайте по ссылке:
ExecuteModuleEventEx($handler, array($ID, $arFields));
}
?>
Если нужен OnBefore... и параметр передаётся по ссылке, можно использовать array(&$arFields).
2) Современный способ (Bitrix\Main\Event)
- Можно создать событие и послать его:
<?
$event = new \Bitrix\Main\Event("iblock", "OnAfterIBlockElementUpdate", array($ID, $arFields));
$event->send();
?>
- Подходит для обработчиков, подписанных через EventManager и для нового API. Минус — параметры передаются как копии, поэтому если обработчики должны изменить данные по ссылке, лучше пользоваться ExecuteModuleEventEx.
Что ещё важно знать
- Имя модуля и имя события нужно брать точно так, как событие инициируется в коде ядра/модулей (для инфоблоков: "iblock" и события типа "OnBeforeIBlockElementAdd", "OnAfterIBlockElementUpdate" и т.д.).
- Для HL-блоков найдите, какие события и под каким модулем/именем используются (обычно смотрите вызовы Event::send или RegisterModuleDependences в коде HL-модуля). После этого тот же приём: GetModuleEvents/ExecuteModuleEventEx или \Bitrix\Main\Event.
- Вызов обработчиков не «пересоздаёт» транзакции/внутреннюю логику модуля — вы только вызываете подписанные колбэки. Если вам нужно полностью симулировать операцию (Add/Update) — лучше выполнить сам Add/Update через API модуля (CIBlockElement::Update / Add, DataManager::update/add для HL), тогда ядро само вызовет все события корректно.
- Будьте внимательны с параметрами: передавайте те аргументы и в том порядке, в котором обработчики их ожидают.
Если скажете точное событие и пример обработчика (его сигнатуру), я напишу готовый код с правильной передачей параметров (и ссылками, если нужно).