Нужно было при работе со списком некоторые поля при сохранении элемента проставить автоматически в зависимости от заполненных полей.
Вроде все просто. Решил это сделать через события OnBeforeIBlockElementUpdate и OnBeforeIBlockElementAdd, так как была необходимость не дать сохранить элемент при определенных условиях.
Поля, с которыми предстояло работать были: число, дата и привязка к элементам. Было понятно, что структура массивов в $arFields для разных типов полей будет (или может) отличаться, но каково было мое удивление, когда для одного и того же поля (например, число) структура массива менялась даже при различных действиях. Вот пример массива при разных действиях:
При добавлении элемента (261 это ID свойства и соответственно ключ в массиве $arFields["PROPERTY_VALUES"]):
Создаем элемент и свойство не добавили:
[261]=>
array(0) {
}
Создаем элемент и свойство добавили:
[261]=>
array(1) {
["n0"]=>
float(100)
}
Тут пока вроде нормально. Идем дальше:
Создаем элемент копированием другого элемента. Свойство не было заполнено и его заполнили:
[261]=>
array(1) {
["n0"]=>
float(100)
}
Создаем элемент копированием другого элемента. Свойство было заполнено и его изменили, либо оставили таким же:
[261]=>
array(1) {
["6841:261"]=>
float(100)
}
Тут становится понятно, что нужно уже выводить дампы всех возможных комбинаций добавления и редактирования элемента, чтобы чего-то не упустить. Приводить дампы всех вариантов не буду. Приведу еще парочку красивых при редактировании элемента.
Редактируем элемент. Свойство не было заполнено и его не заполнили:
[261]=>
array(1) {
["6841:261"]=>
array(2) {
["VALUE"]=>
NULL
["DESCRIPTION"]=>
NULL
}
}
Редактируем элемент. Свойство не было заполнено и его заполнили:
[261]=>
array(1) {
["n0"]=>
float(100)
}
Редактируем элемент. Свойство было заполнено и его очистили:
[261]=>
array(1) {
["6841:261"]=>
array(2) {
["VALUE"]=>
string(4) "100"
["DESCRIPTION"]=>
NULL
}
}
Ну и напоследок редактируем элемент. Свойство было заполнено и его оставили:
[261]=>
array(1) {
["6841:261"]=>
float(100)
}
Здесь уже понятно, что раз у меня несколько свойств и разного типа, то проверок нужно сделать много, чтобы чего-то не упустить.
Я смирился и проверки сделал. Все заработало! Ура!
Но тут одно но… Захотел я из админки отредактировать тот же элемент и… О, чудо! Функционал, который я так старался написать, не работает!
Вопрос. Почему?
Правильно! Угадали! При редактировании из админки в событие OnBeforeIBlockElementUpdate массив $arFields приходит с другой структурой массивов значений свойств. Пока обнаружил различия в свойстве привязка к элементам. Другие пока не проверял, так как понял, что мне предстоит бессонная ночь в поисках различий (почти как в детской игре «Найди 5 различий») и переделке обработчиков.
Пока решил на пару минут отвлечься от работы, чтобы написать этот пост и спросить у народа, может кто подскажет:
1. Зачем такое разнообразие в событиях для одного типа поля?
2. И особенно, зачем нужны различия в событии при работе с элементами из админки и из списков?
3. Может быть есть какой-то универсальный способ или функция для работы с массивом $arFields в обработчиках? Неужели без кучи проверок одного поля никак не обойтись?