PHP
#bitrix#php#order#event#recursion#logging#sale

Безопасное обновление заказа без рекурсии событий

Защита от бесконечной рекурсии при обновлении заказа через флаг контекста и логирование изменений.

Как использовать

  1. Скопируйте нужный фрагмент кода.
  2. Вставьте в свой проект и при необходимости измените под задачу.
  3. Проверьте зависимости и окружение (версии, переменные).

Предотвращает бесконечную рекурсию при обновлении заказа в обработчике события OnSaleOrderSaved. Используйте флаг контекста и логирование для отладки.

use Bitrix\Main\Event;
use Bitrix\Sale\Order;

// Статический флаг для предотвращения рекурсии
static $updateInProgress = false;

AddEventHandler('sale', 'OnSaleOrderSaved', function(Event $event) {
    $order = $event->getParameter('ENTITY');
    if (!($order instanceof Order)) {
        return;
    }
    
    global $updateInProgress;
    
    // Проверяем флаг, чтобы избежать рекурсии
    if ($updateInProgress) {
        return; // Уже обновляем, выходим
    }
    
    // Устанавливаем флаг
    $updateInProgress = true;
    
    try {
        // Логируем изменение (если логгер настроен в .settings.php)
        if (class_exists('\Bitrix\Main\Diag\Logger')) {
            $logger = \Bitrix\Main\Diag\Logger::create('order_update');
            if ($logger) {
                $logger->info('Order update started', [
                    'order_id' => $order->getId(),
                    'status' => $order->getField('STATUS_ID')
                ]);
            }
        }
        
        // Ваша логика обновления
        if ($order->getField('STATUS_ID') === 'N') {
            // Обновляем без триггера события (параметр false отключает события)
            $order->setField('COMMENTS', 'Updated by handler');
            $order->save(false);
        }
        
        if (isset($logger) && $logger) {
            $logger->info('Order update completed', ['order_id' => $order->getId()]);
        }
    } finally {
        // Снимаем флаг
        $updateInProgress = false;
    }
});

Usage:

Добавьте в /local/php_interface/init.php или в модуле. Флаг предотвратит повторный вызов обработчика при сохранении.

Notes:

⚠️ Используется статический флаг $updateInProgress для предотвращения рекурсии. Метод $order->save(false) с параметром false отключает события при сохранении. Logger требует настройки в .settings.php (см. документацию Bitrix). Альтернатива без логгера — просто убрать блок с Logger::create().