Internal API
Custom Events v2 - это локальная система внутренних событий ERP. Она выполняет клиентский PHP-код внутри текущего PHP-процесса ERP без HTTP-запросов, веб-хуков и внешних очередей.
Старый механизм legacy/Config/custom_api.txt с функцией api_function(...) остается legacy-контрактом. В v2 старые названия используются только для карты совместимости. Новый клиентский код должен использовать константы CustomEvent::....
Файлы
Рабочий клиентский файл один:
evolution/CustomEvents/v2/handlers.php
Пример:
evolution/CustomEvents/v2/handlers.example.php
Список всех констант:
evolution/CustomEvents/Runtime/v2/CustomEvent.php
Карта старых имен в новые события:
evolution/CustomEvents/Runtime/v2/CustomEventLegacyEventMap.php
Кеш:
var/cache/CustomEvents/handlers.v2.cache.php
Лог:
var/log/custom-events-v2.log
Как писать обработчики
Используется одна функция регистрации: internal_event(...).
В одном файле можно зарегистрировать несколько обработчиков подряд:
internal_event(
CustomEvent::TASK_CREATED,
static function ($event): bool {
$taskId = $event->get('task_id');
return true;
},
);
internal_event(
CustomEvent::CUSTOMER_STATUS_CHANGE_BEFORE,
static function ($event): bool|string {
if ((int)$event->get('new_status_id') === 0) {
return 'Запрещено переводить абонента в этот статус';
}
return true;
},
);
internal_event(
CustomEvent::CUSTOMER_CARD_PRIMARY_CONTENT_RENDER,
static function ($event): string {
$customerId = (int)$event->get('customer_id');
return '<div>Дополнительная информация по абоненту #' . $customerId . '</div>';
},
);
В обработчик всегда приходит один параметр $event.
Данные читаются без типовых оберток:
$taskId = $event->get('task_id');
$customerId = $event->get('customer_id');
$data = $event->all();
Если нужен конкретный тип, приводите значение в своем коде:
$taskId = (int)$event->get('task_id');
$comment = (string)$event->get('comment');
Результат обработчика
Обработчик возвращает простое значение:
| Возврат | Значение |
|---|---|
true
|
Обработчик выполнен успешно |
false
|
Для события *.before запретить штатную операцию
|
null
|
Ничего не менять |
| строка | Для *.before запретить операцию с текстом причины; для *.render вывести строку/HTML
|
События *.before могут отменять штатную операцию. Остальные события не должны отменять уже выполненное действие.
Пример запрета операции
internal_event(
CustomEvent::CUSTOMER_STATUS_CHANGE_BEFORE,
static function ($event): bool|string {
if ((int)$event->get('new_status_id') === 0) {
return 'Запрещено переводить абонента в этот статус';
}
return true;
},
);
Пример вывода HTML
internal_event(
CustomEvent::CUSTOMER_CARD_PRIMARY_CONTENT_RENDER,
static function ($event): string {
$customerId = (int)$event->get('customer_id');
return '<div>Дополнительная информация по абоненту #' . $customerId . '</div>';
},
);
Проверка, кеш и лог
При изменении evolution/CustomEvents/v2/handlers.php ERP проверяет синтаксис через php -l. Если синтаксис корректный, файл копируется в var/cache/CustomEvents/handlers.v2.cache.php.
Runtime-лог пишется в JSON Lines в var/log/custom-events-v2.log. Одна строка - один вызов обработчика, ошибка или факт отсутствия обработчиков.
Пример строки:
{"ts":"2026-05-10T12:01:03+03:00","event":"task.created","has_handlers":true,"handlers":1,"handler_index":0,"duration_ms":2.341,"memory_kb":18,"result":"allow","message":null}
Лог ротируется в:
var/log/custom-events-v2.log.1
Ошибки
Если в обработчике возникнет ошибка, ERP запишет ее в лог и продолжит работу по правилам конкретного события.
Обработчик выполняется внутри того же PHP-процесса, что и ядро ERP. Через ядро проходят тысячи операций, и медленный или ошибочный клиентский код может остановить или дестабилизировать работу всей системы. Не используйте exit, die, бесконечные циклы, тяжелые SQL-запросы без ограничений и долгие внешние операции. Держите обработчики короткими и предсказуемыми.
Рекомендации
- Используйте только константы
CustomEvent::.... - Не пишите строку события вручную.
- Делайте обработчики короткими.
- Не вызывайте HTTP/webhook из высокочастотных событий.
- Не используйте
exit,die, бесконечные циклы и тяжелые выборки без ограничений. - Возвращайте
true,false,nullили строку.
Все события
Ниже перечислены все события v2. Полный технический список констант находится в evolution/CustomEvents/Runtime/v2/CustomEvent.php.
Поля event указаны как текущий контракт данных.
Здания
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::BUILDING_CREATED
|
После создания здания | building_id, data
|
CustomEvent::BUILDING_CHANGED
|
После редактирования здания | building_id, data
|
Коммутация
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::COMMUTATION_CREATE_BEFORE
|
Перед созданием коммутации между объектами | source_type, source_id, target_type, target_id, data
|
CustomEvent::COMMUTATION_DELETE_BEFORE
|
Перед удалением коммутации между объектами | source_type, source_id, target_type, target_id, data
|
Главная страница
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::DASHBOARD_TOP_CONTENT_RENDER
|
При выводе текста в начальной части главной страницы | employee_id, data
|
Оборудование
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::DEVICE_CHANGED
|
После редактирования оборудования | device_id, device_type, data
|
CustomEvent::DEVICE_NOTIFICATION_DOWN
|
При фиксации недоступности оборудования | device_id, device_type, ip, data
|
CustomEvent::DEVICE_NOTIFICATION_UP
|
При восстановлении доступности оборудования | device_id, device_type, ip, data
|
CustomEvent::DEVICE_INTERFACE_PORT_NUMBER_RENDER
|
При выводе номера порта в таблице интерфейсов | device_id, interface_id, port_number, data
|
CustomEvent::DEVICE_INTERFACE_ADDITIONAL_DATA_RENDER
|
При выводе дополнительного содержимого в карточке оборудования | device_id, data
|
Абоненты
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::CUSTOMER_CREATED
|
После создания абонента | customer_id, data
|
CustomEvent::CUSTOMER_CHANGE_BEFORE
|
Перед редактированием абонента | customer_id, data
|
CustomEvent::CUSTOMER_CHANGED
|
После редактирования абонента | customer_id, data
|
CustomEvent::CUSTOMER_MERGED
|
После объединения абонентов | customer_id, target_customer_id, data
|
CustomEvent::CUSTOMER_STATUS_CHANGE_BEFORE
|
Перед изменением статуса абонента | customer_id, new_status_id, old_status_id, data
|
CustomEvent::CUSTOMER_STATUS_CHANGED
|
После изменения статуса абонента | customer_id, new_status_id, old_status_id, data
|
CustomEvent::CUSTOMER_TARIFF_CHANGE_BEFORE
|
Перед изменением тарифа абонента | customer_id, billing_id, new_tariff_id, old_tariff_id, data
|
CustomEvent::CUSTOMER_TARIFF_CHANGED
|
После изменения тарифа абонента | customer_id, billing_id, new_tariff_id, old_tariff_id, data
|
CustomEvent::CUSTOMER_BALANCE_CHANGED
|
При изменении баланса абонента | customer_id, amount, data
|
CustomEvent::CUSTOMER_FORMER_TRANSFER_BEFORE
|
Перед переводом абонента в бывшие абоненты | customer_id, data
|
CustomEvent::CUSTOMER_FORMER_TRANSFERRED
|
После перевода абонента в бывшие абоненты | customer_id, data
|
CustomEvent::CUSTOMER_FORMER_RESTORE_BEFORE
|
Перед восстановлением абонента из бывших абонентов | customer_id, data
|
CustomEvent::CUSTOMER_FORMER_RESTORED
|
После восстановления абонента из бывших абонентов | customer_id, data
|
CustomEvent::CUSTOMER_DISCONNECT_PLAN_BEFORE
|
Перед постановкой абонента на отключение | customer_id, data
|
CustomEvent::CUSTOMER_DISCONNECT_PLANNED
|
После постановки абонента на отключение | customer_id, data
|
CustomEvent::CUSTOMER_DISCONNECT_BEFORE
|
Перед отключением абонента | customer_id, data
|
CustomEvent::CUSTOMER_DISCONNECTED
|
После отключения абонента | customer_id, data
|
CustomEvent::CUSTOMER_DISCONNECT_CANCEL_BEFORE
|
Перед отменой отключения абонента | customer_id, data
|
CustomEvent::CUSTOMER_DISCONNECT_CANCELLED
|
После отмены отключения абонента | customer_id, data
|
CustomEvent::CUSTOMER_SERVICE_ENABLE_BEFORE
|
Перед подключением услуги абоненту | customer_id, service_id, data
|
CustomEvent::CUSTOMER_SERVICE_ENABLED
|
После подключения услуги абоненту | customer_id, service_id, data
|
CustomEvent::CUSTOMER_SERVICE_DISABLE_BEFORE
|
Перед отключением услуги абоненту | customer_id, service_id, data
|
CustomEvent::CUSTOMER_SERVICE_DISABLED
|
После отключения услуги абоненту | customer_id, service_id, data
|
IP/MAC абонента
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::CUSTOMER_IP_ADD_BEFORE
|
Перед добавлением IP/MAC-адреса | customer_id, ip, mac, subnet_property, data
|
CustomEvent::CUSTOMER_IP_ADDED
|
После добавления IP/MAC-адреса | customer_id, ip, mac, subnet_property, data
|
CustomEvent::CUSTOMER_IP_DELETE_BEFORE
|
Перед удалением IP/MAC-адреса | customer_id, ip, mac, subnet_property, data
|
CustomEvent::CUSTOMER_IP_DELETED
|
После удаления IP/MAC-адреса | customer_id, ip, mac, subnet_property, data
|
Метки абонента
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::CUSTOMER_TAG_ADD_BEFORE
|
Перед добавлением метки абоненту | customer_id, tag_id, data
|
CustomEvent::CUSTOMER_TAG_ADDED
|
После добавления метки абоненту | customer_id, tag_id, data
|
CustomEvent::CUSTOMER_TAG_DELETE_BEFORE
|
Перед удалением метки абонента | customer_id, tag_id, data
|
CustomEvent::CUSTOMER_TAG_DELETED
|
После удаления метки абонента | customer_id, tag_id, data
|
Личный кабинет абонента
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::CUSTOMER_PORTAL_REGISTRATION_BEFORE
|
Перед регистрацией абонента в личном кабинете | customer_id, data
|
CustomEvent::CUSTOMER_PORTAL_REGISTERED
|
После регистрации абонента в личном кабинете | customer_id, data
|
CustomEvent::CUSTOMER_PORTAL_LOGIN_BEFORE
|
Перед входом абонента в личный кабинет | customer_id, data
|
CustomEvent::CUSTOMER_PORTAL_DASHBOARD_RENDER
|
При выводе содержимого на главной странице личного кабинета | customer_id, data
|
CustomEvent::CUSTOMER_PORTAL_PAGE_RENDER
|
При выводе содержимого на страницах личного кабинета | customer_id, page_mode, page_id, data
|
CustomEvent::CUSTOMER_PORTAL_HEAD_RENDER
|
При выводе содержимого после head в личном кабинете
|
customer_id, data
|
Карточка абонента
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::CUSTOMER_CARD_PRIMARY_CONTENT_RENDER
|
При выводе основного содержимого в карточке абонента | customer_id, mode, employee_id, data
|
CustomEvent::CUSTOMER_CARD_SECONDARY_CONTENT_RENDER
|
При выводе дополнительного содержимого в карточке абонента | customer_id, mode, employee_id, ip_mac, data
|
CustomEvent::CUSTOMER_CARD_IP_MAC_CONTENT_RENDER
|
При выводе информации возле IP/MAC-адресов абонента | customer_id, ip, mac, data
|
CustomEvent::CUSTOMER_CARD_SMS_CONTENT_RENDER
|
При выводе содержимого отправки SMS в карточке абонента | customer_id, data
|
Сотрудники
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::EMPLOYEE_MESSAGE_CREATED
|
После создания сообщения сотруднику | receiver_employee_id, message_id, data
|
CustomEvent::EMPLOYEE_CHANGED
|
После редактирования сотрудника | employee_id, data
|
CustomEvent::EMPLOYEE_PERSONAL_SECTION_CONTENT_RENDER
|
При выводе информации в персональном разделе сотрудника | employee_id, data
|
Табель работ
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::EMPLOYEE_TIMESHEET_PRINT_HEADER_RENDER
|
При выводе шапки печатного табеля | employee_id, period, data
|
CustomEvent::EMPLOYEE_TIMESHEET_PRINT_FOOTER_RENDER
|
При выводе подвала печатного табеля | employee_id, period, data
|
Склад
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::INVENTORY_TRANSFER_BEFORE
|
Перед перемещением ТМЦ | inventory_id, operation_id, data
|
CustomEvent::INVENTORY_TRANSFERRED
|
После перемещения ТМЦ | inventory_id, operation_id, data
|
Задания
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::TASK_CARD_RENDER
|
При выводе содержимого в карточке задания | task_type_id, task_id, employee_id, data
|
CustomEvent::TASK_WORK_DATE_RENDER
|
При выводе содержимого возле даты работ | task_type_id, task_id, employee_id, data
|
CustomEvent::TASK_CREATE_BEFORE
|
Перед созданием задания | task_type_id, author_employee_id, data
|
CustomEvent::TASK_CREATED
|
После создания задания | task_id, task_type_id, author_employee_id, data
|
CustomEvent::TASK_DELETE_BEFORE
|
Перед удалением задания | task_id, data
|
CustomEvent::TASK_CHANGE_BEFORE
|
Перед редактированием задания | task_id, data
|
CustomEvent::TASK_CHANGED
|
После редактирования задания | task_id, data
|
CustomEvent::TASK_COMMENT_CREATE_BEFORE
|
Перед добавлением комментария к заданию | task_id, comment, data
|
CustomEvent::TASK_COMMENT_CREATED
|
После добавления комментария к заданию | task_id, comment_id, comment, data
|
CustomEvent::TASK_COMMENT_CHANGED
|
После редактирования комментария к заданию | task_id, comment_id, comment, data
|
CustomEvent::TASK_COMMENT_TEXT_RENDER
|
При выводе текста комментария задания | task_id, comment_id, comment, data
|
CustomEvent::TASK_DIVISION_ASSIGN_BEFORE
|
Перед добавлением подразделения к заданию | task_id, division_id, data
|
CustomEvent::TASK_DIVISION_REMOVE_BEFORE
|
Перед исключением подразделения из задания | task_id, division_id, data
|
CustomEvent::TASK_EMPLOYEE_ASSIGN_BEFORE
|
Перед добавлением исполнителя к заданию | task_id, employee_id, data
|
CustomEvent::TASK_EMPLOYEE_REMOVE_BEFORE
|
Перед исключением исполнителя из задания | task_id, employee_id, data
|
CustomEvent::TASK_WATCHER_DIVISION_ASSIGN_BEFORE
|
Перед добавлением подразделения наблюдателем | task_id, division_id, data
|
CustomEvent::TASK_WATCHER_EMPLOYEE_ASSIGN_BEFORE
|
Перед добавлением сотрудника наблюдателем | task_id, employee_id, data
|
CustomEvent::TASK_OBJECT_ATTACHED
|
После добавления объекта к заданию | task_id, object_type, object_id, data
|
CustomEvent::TASK_OBJECT_DETACHED
|
После исключения объекта из задания | task_id, object_type, object_id, data
|
CustomEvent::TASK_RETURNED_TO_AUTHOR
|
После возврата задания автору | task_id, data
|
CustomEvent::TASK_STATE_CHANGE_BEFORE
|
Перед изменением статуса задания | task_id, old_state_id, new_state_id, data
|
CustomEvent::TASK_STATE_CHANGED
|
После изменения статуса задания | task_id, old_state_id, new_state_id, data
|
Сооружения связи
| Константа | Когда вызывается | Данные $event
|
|---|---|---|
CustomEvent::NODE_CARD_ADDITIONAL_DATA_RENDER
|
При выводе дополнительного содержимого в карточке сооружения связи | node_id, data
|
CustomEvent::NODE_CARD_PRIMARY_CONTENT_RENDER
|
При выводе основного содержимого в карточке сооружения связи | node_id, data
|