Перейти к основному содержимому

Событие перед изменением элемента инфоблока

[OnBeforeUpdateItem] Событие перед изменением элемента инфоблока​

Событие OnBeforeUpdateItem вызывается перед обновлением конкретного элемента инфоблока через CIblockElement::Update(). Позволяет модифицировать данные, которые будут записаны в элемент.

Событие вызывается, только если модуль собрал для элемента хотя бы одно поле на обновление. На практике это почти каждый элемент порции: MODIFIED_BY добавляется всегда, когда в настройках задан пользователь, а ACTIVE, описания и раздел — часто без сравнения с текущим значением (подробности ниже).

Как модуль читает ответ
  • Исключение из обработчика модуль не перехватывает — оно обрывает шаг импорта. Оборачивайте код в try/catch.
  • Параметры последнего обработчика, вернувшего EventResult::SUCCESS, целиком заменяют arUpdateItemFields. Ответы не сливаются: каждый обработчик получает исходный массив модуля.
  • EventResult::ERROR игнорируется — отменить обновление им нельзя.
  • Возврат пустого массива тоже не отменяет обновление: модуль всё равно вызовет CIBlockElement::Update() с пустым набором полей и посчитает элемент обновлённым.
  • SUCCESS без параметров даёт null, который уходит в CIBlockElement::Update(). Всегда возвращайте полный массив, а если менять нечего — не возвращайте ничего.

Параметры события

ПараметрТипОписание
entitystringСущность в МойСклад: product, variant, bundle, service
currentItemarrayДанные о текущем элементе (содержит BX и MS)
arUpdateItemFieldsarrayМассив данных для передачи в CIblockElement::Update()

Структура currentItem

[
'BX' => [ // элемент инфоблока Битрикс
'ID' => 1234,
'IBLOCK_ID' => 5,
'NAME' => 'Название товара',
'XML_ID' => 'abc123externalcode',
'ACTIVE' => 'Y',
'CODE' => 'nazvanie-tovara',
'SORT' => 500,
'PREVIEW_TEXT' => 'Краткое описание',
'DETAIL_TEXT' => 'Подробное описание',
'PREVIEW_PICTURE' => 100,
'DETAIL_PICTURE' => 101,
'PREVIEW_TEXT_TYPE' => 'text',
'DETAIL_TEXT_TYPE' => 'html',
// у каждого поля есть пара с тильдой: '~NAME', '~DETAIL_TEXT' и т.д.
],
'MS' => $itemMs // объект из МойСклад, доступ к полям через свойства
]
Какие поля есть в BX

Модуль выбирает только поля из примера выше — IBLOCK_SECTION_ID и других полей элемента в массиве нет. Строки получены через GetNext(): значения HTML-экранированы, исходные лежат под ключами с тильдой (~NAME, ~DETAIL_TEXT).

Структура ms-объекта (currentItem['MS'])

$item = $currentItem['MS'];
$item->name // 'Название товара'
$item->externalCode // 'abc123externalcode'
$item->archived // false
$item->description // 'Описание товара'
$item->weight // 0.5
$item->article // 'ART-001'
$item->variantsCount // 3 (для product)
$item->attributes // массив доп. атрибутов МС
$item->images // массив изображений
$item->productFolder // объект с meta->href группы товаров

Структура arUpdateItemFields

Содержит поля, собранные модулем по опциям обновления сущности. Сравнение с текущим значением есть не у всех полей — отсутствие поля в массиве не значит, что оно не изменилось, а присутствие не значит, что изменилось:

[
'MODIFIED_BY' => 1, // всегда, если в настройках задан пользователь
'NAME' => 'Новое название', // если изменилось имя
'ACTIVE' => 'N', // см. ниже
'IBLOCK_SECTION_ID' => 15, // ID раздела или false — «вне разделов»
'SORT' => 100, // если изменилось значение поля сортировки
'PREVIEW_TEXT' => 'Новое описание', // без сравнения, см. ниже
'PREVIEW_TEXT_TYPE' => 'html', // 'text' или 'html', если тип задан в настройках
'DETAIL_TEXT' => 'Новое полное описание', // без сравнения, см. ниже
'DETAIL_TEXT_TYPE' => 'html',
'CODE' => 'novoe-nazvanie', // если включена опция обновления символьного кода
'PREVIEW_PICTURE' => [...], // массив для CFile или ['del' => 'Y']
'DETAIL_PICTURE' => [...], // массив для CFile или ['del' => 'Y']
]

Как собираются поля:

  • ACTIVE — если активность управляется доп. полем МойСклад, ставится всегда: 'Y', когда поле отмечено, иначе 'N'. Иначе при опции архивности — 'N' для архивного и 'Y' для разархивированного товара; при опции активации по фильтру — 'Y' для неактивного элемента. При опции «игнорировать активность» не ставится.
  • IBLOCK_SECTION_ID — при опции обновления группы; false, если раздел для группы не найден. Текущий раздел элемента модуль не выбирает, поэтому найденный раздел попадает в массив практически всегда (кроме случая, когда включено сохранение нескольких разделов и элемент уже в нескольких).
  • PREVIEW_TEXT / DETAIL_TEXT — ставятся без сравнения с текущим текстом: всегда, когда источник описания непуст, а при опции удаления описаний — и пустой строкой.
  • CODE — при опции обновления символьного кода: транслит названия, при опции уникальности дополненный _<ID> при совпадении с другим элементом; ставится, только если отличается от текущего.
  • PREVIEW_PICTURE / DETAIL_PICTURE — массив файла, если картинка в МойСклад сменилась; ['del' => 'Y'], если картинок в МойСклад нет и включено удаление картинок.

Возвращаемое значение

Верните EventResult::SUCCESS с полным модифицированным массивом $arUpdateItemFields. Этот массив будет передан в CIblockElement::Update().

return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $arUpdateItemFields);