Почему не работают события OnAfterIBlockElementUpdate?
Если вы столкнулись с тем, что обработчики событий OnAfterIBlockElementUpdate или OnAfterIBlockElementAdd не обновляют цену в каталоге, причина в порядке выполнения событий:
Сначала выполняются обработчики для инфоблока, а затем для каталога.
Это значит, что если вы попытаетесь обновить цену через CPrice::Update в стандартном обработчике, она будет перезаписана значениями из вкладки «Торговый каталог».
Решение: изменение цены через событие BXIBlockAfterSave
Чтобы корректно обновлять цену из свойства при добавлении или редактировании элемента (через админку или публичную часть), выполните два шага:
Шаг 1: Настройка инфоблока
-
Перейдите в настройки инфоблока с товарами (Контент → Инфоблоки → Типы инфоблоков → Ваш инфоблок).
-
На вкладке «Настройки» найдите поле:
«Файл для редактирования элемента, позволяющий модифицировать поля перед сохранением»
-
Укажите путь:
/bitrix/php_interface/include/iblock_catalog_edit_after_save.php
-
Сохраните изменения и создайте этот файл на сервере.
Шаг 2: Код для обновления цены
В файл iblock_catalog_edit_after_save.php добавьте следующий код:
<?php
function BXIBlockAfterSave($arFields) {
// Получаем цену из свойства (ID = 55, замените на ваш)
$price = array_shift($_POST['PROP'][55]); // Берём первое значение
$price = str_replace(',', '.', $price); // Заменяем запятую на точку
$PRODUCT_ID = $arFields['ID'];
$arField = [
"PRODUCT_ID" => $PRODUCT_ID,
"CATALOG_GROUP_ID" => 1, // ID типа цены (базовая = 1)
"PRICE" => $price,
"CURRENCY" => "RUB"
];
// Проверяем существование цены и обновляем/добавляем
$res = CPrice::GetList([], ["PRODUCT_ID" => $PRODUCT_ID, "CATALOG_GROUP_ID" => 1]);
if ($arr = $res->Fetch()) {
CPrice::Update($arr["ID"], $arField);
} else {
CPrice::Add($arField);
}
}
?>Разбор кода и нюансы
-
BXIBlockAfterSave– это событие, которое позволяет перехватить данные после сохранения элемента, но до обновления каталога. -
$_POST['PROP'][55]– здесь55– это ID свойства, из которого берется цена. Замените его на ваш. -
Логирование – если что-то не работает, добавьте отладку:
AddMessage2Log($_POST); // Логируем POST-данные
Убедитесь, что в
dbconn.phpуказан путь к лог-файлу:define("LOG_FILENAME", $_SERVER["DOCUMENT_ROOT"]."/.log.txt");
-
CPrice::UpdateиCPrice::Add– обновляют или создают цену в каталоге.
Вывод
Этот метод гарантирует, что цена из свойства будет записана в торговый каталог после сохранения элемента. Если у вас есть вопросы или предложения – пишите в комментариях!