Internal API EN

Материал из WiKi - UserSide
Версия от 19:35, 23 мая 2026; IronBot (обсуждение | вклад) ([IronBot] Fix EN localization text)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)

en | uk | ru

Custom Events v2 is a local ERP internal event system. It runs customer PHP code inside the current ERP PHP process without HTTP requests, webhooks, or external queues.

The old legacy/Config/custom_api.txt mechanism with the api_function(...) function remains a legacy contract. In v2, old names are used only for the compatibility map. New customer code must use CustomEvent::... constants.

Files

There is one working customer file:

evolution/CustomEvents/v2/handlers.php

Example:

evolution/CustomEvents/v2/handlers.example.php

List of all constants:

evolution/CustomEvents/Runtime/v2/CustomEvent.php

Map of old names to new events:

evolution/CustomEvents/Runtime/v2/CustomEventLegacyEventMap.php

Cache:

var/cache/CustomEvents/handlers.v2.cache.php

Log:

var/log/custom-events-v2.log

How to write handlers

One registration function is used: internal_event(...).

Several handlers can be registered one after another in the same file:

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 'Changing the customer to this status is forbidden';
        }

        return true;
    },
);

internal_event(
    CustomEvent::CUSTOMER_CARD_PRIMARY_CONTENT_RENDER,
    static function ($event): string {
        $customerId = (int)$event->get('customer_id');

        return '<div>Additional customer information #' . $customerId . '</div>';
    },
);

The handler always receives one parameter: $event.

Data is read without type wrappers:

$taskId = $event->get('task_id');
$customerId = $event->get('customer_id');
$data = $event->all();

If a specific type is required, cast the value in your code:

$taskId = (int)$event->get('task_id');
$comment = (string)$event->get('comment');

Handler result

The handler returns a simple value:

Return Meaning
true The handler completed successfully
false For a *.before event, block the standard operation
null Do not change anything
string For *.before, block the operation with a reason text; for *.render, output a string or HTML

*.before events can cancel the standard operation. Other events must not cancel an action that has already been completed.

Example: blocking an operation

internal_event(
    CustomEvent::CUSTOMER_STATUS_CHANGE_BEFORE,
    static function ($event): bool|string {
        if ((int)$event->get('new_status_id') === 0) {
            return 'Changing the customer to this status is forbidden';
        }

        return true;
    },
);

Example: outputting HTML

internal_event(
    CustomEvent::CUSTOMER_CARD_PRIMARY_CONTENT_RENDER,
    static function ($event): string {
        $customerId = (int)$event->get('customer_id');

        return '<div>Additional customer information #' . $customerId . '</div>';
    },
);

Validation, cache, and log

When evolution/CustomEvents/v2/handlers.php changes, ERP checks the syntax with php -l. If the syntax is valid, the file is copied to var/cache/CustomEvents/handlers.v2.cache.php.

The runtime log is written as JSON Lines to var/log/custom-events-v2.log. One line is one handler call, error, or fact that no handlers exist.

Example line:

{"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}

The log is rotated to:

var/log/custom-events-v2.log.1

Errors

If an error occurs in a handler, ERP writes it to the log and continues according to the rules of the specific event.

The handler runs inside the same PHP process as the ERP core. Thousands of operations pass through the core, so slow or faulty customer code can stop or destabilize the entire system. Do not use exit, die, endless loops, heavy SQL queries without limits, or long external operations. Keep handlers short and predictable.

Recommendations

  • Use only CustomEvent::... constants.
  • Do not write the event string manually.
  • Keep handlers short.
  • Do not call HTTP/webhook from high-frequency events.
  • Do not use exit, die, endless loops, or heavy selections without limits.
  • Return true, false, null, or a string.

All events

All v2 events are listed below. The complete technical list of constants is in evolution/CustomEvents/Runtime/v2/CustomEvent.php.

The event fields are the current data contract.

Buildings

Constant When called $event data
CustomEvent::BUILDING_CREATED After creating a building building_id, data
CustomEvent::BUILDING_CHANGED After editing a building building_id, data

Commutation

Constant When called $event data
CustomEvent::COMMUTATION_CREATE_BEFORE Before creating commutation between objects source_type, source_id, target_type, target_id, data
CustomEvent::COMMUTATION_DELETE_BEFORE Before deleting commutation between objects source_type, source_id, target_type, target_id, data

Dashboard

Constant When called $event data
CustomEvent::DASHBOARD_TOP_CONTENT_RENDER When rendering text at the top of the dashboard employee_id, data

Equipment

Constant When called $event data
CustomEvent::DEVICE_CHANGED After editing equipment device_id, device_type, data
CustomEvent::DEVICE_NOTIFICATION_DOWN When equipment unavailability is recorded device_id, device_type, ip, data
CustomEvent::DEVICE_NOTIFICATION_UP When equipment availability is restored device_id, device_type, ip, data
CustomEvent::DEVICE_INTERFACE_PORT_NUMBER_RENDER When rendering the port number in the interface table device_id, interface_id, port_number, data
CustomEvent::DEVICE_INTERFACE_ADDITIONAL_DATA_RENDER When rendering additional content in the equipment card device_id, data

Customers

Constant When called $event data
CustomEvent::CUSTOMER_CREATED After creating a customer customer_id, data
CustomEvent::CUSTOMER_CHANGE_BEFORE Before editing a customer customer_id, data
CustomEvent::CUSTOMER_CHANGED After editing a customer customer_id, data
CustomEvent::CUSTOMER_MERGED After merging customers customer_id, target_customer_id, data
CustomEvent::CUSTOMER_STATUS_CHANGE_BEFORE Before changing a customer status customer_id, new_status_id, old_status_id, data
CustomEvent::CUSTOMER_STATUS_CHANGED After changing a customer status customer_id, new_status_id, old_status_id, data
CustomEvent::CUSTOMER_TARIFF_CHANGE_BEFORE Before changing a customer tariff customer_id, billing_id, new_tariff_id, old_tariff_id, data
CustomEvent::CUSTOMER_TARIFF_CHANGED After changing a customer tariff customer_id, billing_id, new_tariff_id, old_tariff_id, data
CustomEvent::CUSTOMER_BALANCE_CHANGED When a customer balance changes customer_id, amount, data
CustomEvent::CUSTOMER_FORMER_TRANSFER_BEFORE Before moving a customer to former customers customer_id, data
CustomEvent::CUSTOMER_FORMER_TRANSFERRED After moving a customer to former customers customer_id, data
CustomEvent::CUSTOMER_FORMER_RESTORE_BEFORE Before restoring a customer from former customers customer_id, data
CustomEvent::CUSTOMER_FORMER_RESTORED After restoring a customer from former customers customer_id, data
CustomEvent::CUSTOMER_DISCONNECT_PLAN_BEFORE Before scheduling customer disconnection customer_id, data
CustomEvent::CUSTOMER_DISCONNECT_PLANNED After scheduling customer disconnection customer_id, data
CustomEvent::CUSTOMER_DISCONNECT_BEFORE Before disconnecting a customer customer_id, data
CustomEvent::CUSTOMER_DISCONNECTED After disconnecting a customer customer_id, data
CustomEvent::CUSTOMER_DISCONNECT_CANCEL_BEFORE Before cancelling customer disconnection customer_id, data
CustomEvent::CUSTOMER_DISCONNECT_CANCELLED After cancelling customer disconnection customer_id, data
CustomEvent::CUSTOMER_SERVICE_ENABLE_BEFORE Before enabling a service for a customer customer_id, service_id, data
CustomEvent::CUSTOMER_SERVICE_ENABLED After enabling a service for a customer customer_id, service_id, data
CustomEvent::CUSTOMER_SERVICE_DISABLE_BEFORE Before disabling a service for a customer customer_id, service_id, data
CustomEvent::CUSTOMER_SERVICE_DISABLED After disabling a service for a customer customer_id, service_id, data

Customer IP/MAC

Constant When called $event data
CustomEvent::CUSTOMER_IP_ADD_BEFORE Before adding an IP/MAC address customer_id, ip, mac, subnet_property, data
CustomEvent::CUSTOMER_IP_ADDED After adding an IP/MAC address customer_id, ip, mac, subnet_property, data
CustomEvent::CUSTOMER_IP_DELETE_BEFORE Before deleting an IP/MAC address customer_id, ip, mac, subnet_property, data
CustomEvent::CUSTOMER_IP_DELETED After deleting an IP/MAC address customer_id, ip, mac, subnet_property, data

Customer tags

Constant When called $event data
CustomEvent::CUSTOMER_TAG_ADD_BEFORE Before adding a tag to a customer customer_id, tag_id, data
CustomEvent::CUSTOMER_TAG_ADDED After adding a tag to a customer customer_id, tag_id, data
CustomEvent::CUSTOMER_TAG_DELETE_BEFORE Before deleting a customer tag customer_id, tag_id, data
CustomEvent::CUSTOMER_TAG_DELETED After deleting a customer tag customer_id, tag_id, data

Customer portal

Constant When called $event data
CustomEvent::CUSTOMER_PORTAL_REGISTRATION_BEFORE Before registering a customer in the customer portal customer_id, data
CustomEvent::CUSTOMER_PORTAL_REGISTERED After registering a customer in the customer portal customer_id, data
CustomEvent::CUSTOMER_PORTAL_LOGIN_BEFORE Before a customer logs in to the customer portal customer_id, data
CustomEvent::CUSTOMER_PORTAL_DASHBOARD_RENDER When rendering content on the customer portal dashboard customer_id, data
CustomEvent::CUSTOMER_PORTAL_PAGE_RENDER When rendering content on customer portal pages customer_id, page_mode, page_id, data
CustomEvent::CUSTOMER_PORTAL_HEAD_RENDER When rendering content after head in the customer portal customer_id, data

Customer card

Constant When called $event data
CustomEvent::CUSTOMER_CARD_PRIMARY_CONTENT_RENDER When rendering the main content in the customer card customer_id, mode, employee_id, data
CustomEvent::CUSTOMER_CARD_SECONDARY_CONTENT_RENDER When rendering additional content in the customer card customer_id, mode, employee_id, ip_mac, data
CustomEvent::CUSTOMER_CARD_IP_MAC_CONTENT_RENDER When rendering information near customer IP/MAC addresses customer_id, ip, mac, data
CustomEvent::CUSTOMER_CARD_SMS_CONTENT_RENDER When rendering SMS sending content in the customer card customer_id, data

Employees

Constant When called $event data
CustomEvent::EMPLOYEE_MESSAGE_CREATED After creating a message for an employee receiver_employee_id, message_id, data
CustomEvent::EMPLOYEE_CHANGED After editing an employee employee_id, data
CustomEvent::EMPLOYEE_PERSONAL_SECTION_CONTENT_RENDER When rendering information in an employee personal section employee_id, data

Timesheet

Constant When called $event data
CustomEvent::EMPLOYEE_TIMESHEET_PRINT_HEADER_RENDER When rendering the printed timesheet header employee_id, period, data
CustomEvent::EMPLOYEE_TIMESHEET_PRINT_FOOTER_RENDER When rendering the printed timesheet footer employee_id, period, data

Warehouse

Constant When called $event data
CustomEvent::INVENTORY_TRANSFER_BEFORE Before moving inventory items inventory_id, operation_id, data
CustomEvent::INVENTORY_TRANSFERRED After moving inventory items inventory_id, operation_id, data

Tasks

Constant When called $event data
CustomEvent::TASK_CARD_RENDER When rendering content in the task card task_type_id, task_id, employee_id, data
CustomEvent::TASK_WORK_DATE_RENDER When rendering content near the work date task_type_id, task_id, employee_id, data
CustomEvent::TASK_CREATE_BEFORE Before creating a task task_type_id, author_employee_id, data
CustomEvent::TASK_CREATED After creating a task task_id, task_type_id, author_employee_id, data
CustomEvent::TASK_DELETE_BEFORE Before deleting a task task_id, data
CustomEvent::TASK_CHANGE_BEFORE Before editing a task task_id, data
CustomEvent::TASK_CHANGED After editing a task task_id, data
CustomEvent::TASK_COMMENT_CREATE_BEFORE Before adding a task comment task_id, comment, data
CustomEvent::TASK_COMMENT_CREATED After adding a task comment task_id, comment_id, comment, data
CustomEvent::TASK_COMMENT_CHANGED After editing a task comment task_id, comment_id, comment, data
CustomEvent::TASK_COMMENT_TEXT_RENDER When rendering task comment text task_id, comment_id, comment, data
CustomEvent::TASK_DIVISION_ASSIGN_BEFORE Before adding a division to a task task_id, division_id, data
CustomEvent::TASK_DIVISION_REMOVE_BEFORE Before removing a division from a task task_id, division_id, data
CustomEvent::TASK_EMPLOYEE_ASSIGN_BEFORE Before adding an assignee to a task task_id, employee_id, data
CustomEvent::TASK_EMPLOYEE_REMOVE_BEFORE Before removing an assignee from a task task_id, employee_id, data
CustomEvent::TASK_WATCHER_DIVISION_ASSIGN_BEFORE Before adding a division as a watcher task_id, division_id, data
CustomEvent::TASK_WATCHER_EMPLOYEE_ASSIGN_BEFORE Before adding an employee as a watcher task_id, employee_id, data
CustomEvent::TASK_OBJECT_ATTACHED After adding an object to a task task_id, object_type, object_id, data
CustomEvent::TASK_OBJECT_DETACHED After removing an object from a task task_id, object_type, object_id, data
CustomEvent::TASK_RETURNED_TO_AUTHOR After returning a task to the author task_id, data
CustomEvent::TASK_STATE_CHANGE_BEFORE Before changing a task status task_id, old_state_id, new_state_id, data
CustomEvent::TASK_STATE_CHANGED After changing a task status task_id, old_state_id, new_state_id, data

Communications installations

Constant When called $event data
CustomEvent::NODE_CARD_ADDITIONAL_DATA_RENDER When rendering additional content in the communications installation card node_id, data
CustomEvent::NODE_CARD_PRIMARY_CONTENT_RENDER When rendering the main content in the communications installation card node_id, data