Internal API UK

Материал из WiKi - UserSide

en | uk | ru

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