Нужно навешать обработчик на
OnBeforeIBlockElementUpdate, потому что при OnIBlockElementUpdate нельзя делать CIBlockElement:Update() (это вызовет циклический вызов обработчика). При OnIBlockElementUpdate значения в changes нужно будет писать через
SetPropertyValuesEx. Хотя с OnIBlockElementUpdate/SetPropertyValuesEx вариант вполне рабочий.
Примерный код с OnBeforeIBlockElementUpdate:
<?php
AddEventHandler("iblock", "OnBeforeIBlockElementUpdate", ["MyClass", "OnBeforeIBlockElementUpdateHandler"]);
class MyClass {
public static function OnBeforeIBlockElementUpdateHandler(&$arFields)
{
if ($arFields['IBLOCK_ID'] == 1) { // Проверяем на нужный ИБ
$userId = $arFields["MODIFIED_BY"];
$propValues = $arFields["PROPERTY_VALUES"];
$propMap = [ // Массив полей, за которым следим в виде ID св-ва => тайтл
8 => "Some prop",
];
$changesPropId = 9; // ID свойства changes
$resOldElem = CIBlockElement::GetList(
[],
["IBLOCK_ID" => $arFields["IBLOCK_ID"], "ID" => $arFields["ID"]],
false,
false,
array_map(function($propId) {
return "PROPERTY_{$propId}";
}, array_keys($propMap))
)->Fetch();
$newChanges = [];
foreach ($propMap as $propId => $propTitle) {
$propValueKey = "PROPERTY_{$propId}_VALUE";
$oldPropValue = $resOldElem[$propValueKey];
$newPropValue = $propValues[$propId][array_key_first($propValues[$propId])]["VALUE"]; // Для множественных свойств нужна своя логика обработки
if ($oldPropValue != $newPropValue) { // Если значение из справочника, то его надо разыменовать, достать значение из ИБ/Хайлоад ИБ
$newChanges[] = "Юзер {$userId} изменил {$propTitle}: {$oldPropValue} -> {$newPropValue}";
}
}
if (!empty($newChanges)) {
$arFields['PROPERTY_VALUES'][$changesPropId] = array_merge($arFields['PROPERTY_VALUES'][$changesPropId], $newChanges);
}
}
}
}
Решение так себе, потому что:
a) множественных значений свойств
b) некрасиво сработает со значениями из справочников
c) захардкоженные ID свойств и их заголовки
d) не достает имя пользователя
Но, как старт для запила фичи дает, я думаю
PS: Хранить изменения товара в самом товаре так себе идея, лучше завести отдельную таблицу с быстрым чтением и записью (HL-инфблоки подойдут) и сделать кастомный вывод истории в админке в карточке редактирования товара