Изменение основного раздела на лету при выгрузке из 1С
При выгрузке из 1С может возникнуть ситуация, когда товар привязан к нескольким разделам каталога, но вот выбрать основной из 1С они не могут. Поэтому основным выбирается тот, у которого ID меньше. Подробнее про основной раздел и о том, как может быть важно его указывать можно прочитать в этой статье.
Предлагаю способ, как менять основной раздел на лету. Для этого нужно, чтобы внешний код XML_ID (или как его еще называют ГУИД/GUID) основного раздела из 1С передавали просто в строковое свойство товара. Тогда по событиям добавления и изменения элемента мы будем подменять программно ID основного раздела.
Для начала напишем функцию, которая ищет ID раздела инфоблока по его внешнему коду XML_ID.
<?php
function getSectionIdByXmlId($iblockId, $sectionXmlId)
{
$entityIblockSection = \Bitrix\Iblock\Model\Section::compileEntityByIblock($iblockId);
$section = $entityIblockSection::getList([
'select' => [
'ID', //выбираем только ID, остальное нам не нужно
],
'filter' => [
'XML_ID' => $sectionXmlId,
],
])->fetch();
return $section ? $section['ID'] : false;
}
Также добавим вспомогательную функцию, которая возвращает массив свойств элементов инфоблока.
<?php
function getIblockProperties($iblockId)
{
if (empty($iblockId)) return false;
$filter = [
'IBLOCK_ID' => $iblockId,
];
$propertyList = \CIBlockProperty::GetList(
['SORT' => 'ASC'],
$filter
);
while ($property = $propertyList->Fetch()) {
$res[$property['CODE']] = [
'ID' => $property['ID'],
'CODE' => $property['CODE'],
'NAME' => $property['NAME'],
];
}
return !empty($res) ? $res : false;
}
Далее "подписываемся" на события добавления и изменения элемента ИБ и пишем функцию обработчик.
<?php
$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandler(
'iblock',
'OnBeforeIBlockElementAdd',
'changeMainSection'
);
$eventManager->addEventHandler(
'iblock',
'OnBeforeIBlockElementUpdate',
'changeMainSection'
);
function changeMainSection(&$arFields)
{
if ($arFields['IBLOCK_ID'] != CATALOG_ID) return; //подставьте свой ID инфоблока каталога
if ($properties = $arFields['PROPERTY_VALUES']) {
//получаем массив свойств инфоблока
$iProps = getIblockProperties($arFields['IBLOCK_ID']);
//получаем ID свойства, где MAIN_SECTION_UID - код свойства с УИДом
$sectionUidPropId = $iProps['MAIN_SECTION_UID']['ID'];
if ($sectionUidPropId && $properties[$sectionUidPropId]) {
$uidProp = reset($properties[$sectionUidPropId]);
if ((is_array($uidProp) && $uidProp['VALUE'])) {
//ищем ID раздела по внешнему коду из свойства элемента
$sectionId = getSectionIdByXmlId($arFields['IBLOCK_ID'], $uidProp['VALUE']);
if ($sectionId) {
//подменяем ID основного раздела
$arFields['IBLOCK_SECTION_ID'] = $sectionId;
}
}
}
}
}
Этапы обработчика:
- Получаем ID свойства с УИДом по его коду;
- Получаем значение свойства с УИДом из обновляемого элемента;
- Ищем ID раздела по его внешнему коду;
- Подменяем основной раздел IBLOCK_SECTION_ID.
Весь представленный код размещаем в /local/php_interface/init.php.
Дополнительно: вместого того, чтобы жестко задавать CATALOG_ID в коде, можете воспользоваться функцией получения ID инфоблока по его символьному коду. Подробнее в этой статье.
Оставьте комментарий
Если эта статья была полезной для вас, оставьте комментарий ниже или задайте интересующий Вас вопрос. Ваш опыт может помочь другим читателям!
Написать комментарий