Работа с ценами в форме редактирования элемента инфоблока на Битрикс
Сайт поддержки разработчиков Битрикс, по материалам статьи Е. Жукова.
Периодически встречается следующая задача: на основании значения свойства элемента или ряда других условия модифицировать какой-то конкретный тип цен при создании/изменении элемента. Первое, что приходит в голову - воспользоваться обработчиками событийOnAfterIBlockElementAdd и OnAfterIBlockElementUpdate. При использовании с API все работает отлично, однако при сохранении изменений в форме редактирования элемента в админке ничего не происходит. Создается впечатление, что обработчик не вызывается. Как результат - обращение в техподдержку и долгие поиски ошибок. В чем же причина?
Ларчик открывается просто, достаточно схематично рассмотреть, как происходит сохранение элемента в форме редактирования.
Итак, Вы нажали кнопку "Сохранить" в форме. Данные отправились на сервер, выполняется проверка переданных данных, относящихся к элементу инфоблока, затем (если инфоблок является торговым каталогом) - проверка валидности цен и данных, относящихся к товару. Проверка прошла успешно, начинается сохранение (или обновление) данных:
- Вызывается CIBlockElement::Add или CIBlockElement::Update. Данные заносятся в базу, вызывается пользовательский обработчик событий, изменяет нужный тип цен.
- Вызывается CCatalogProduct::Add или CCatalogProduct::Update - сохранение свойств товара
- Сохраняются цены и удаляются те, которых не было в форме редактирования.
В итоге - обработчик был вызван, но его изменения позже были затерты.
Какой же может быть выход?
Если использование обработчика необходимо - его можно усложнить, встроив проверку адреса текущей страницы. Если это адрес формы редактирования - никаких действий не выполнять. А требуемый функционал в форме редактирования реализовать через функцию BXIBlockAfterSave. В настройках инфоблока есть поле "Файл для редактирования элемента, позволяющий модифицировать поля перед сохранением". Путь к файлу с функцией необходимо прописать в этом поле. Минус этого решения - в функцию передаются только поля и свойства элемента, но не цены. Выход - либо брать их из базы, либо работать с массивом $_POST.
UPD. Подобная же проблема может возникнуть в скриптах импорта (csv, 1C). В этом случае решение одно - использовать обработчики класса CPrice.
23.06.2012