Работа с инфоблоками на API Bitrix
Битрикс имеет широкие возможности по работе с разделами и элементами инфоблоков на низкоуровневом API. Рассмотрим примеры, которые позволят выбрать и обработать содержимое инфоблока. Применяться они могут как в шаблонах, так и непосредственно на страницах.
- Работа с элементами инфоблока
- Изменение элемента инфоблока
- Выборка разделов инфоблока
- Перебор и обработка активных элементов
- Получение пользовательских полей
Для тестирования примеров создайте новый файл с содержимым:
<? require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php"); $APPLICATION->SetTitle("API Bitrix"); CModule::IncludeModule("iblock"); // примеры require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
Работа с элементами инфоблока
Начнём с простого — получение родительской секции по ID элемента. Допустим, в каталоге есть карточка товара с идентификатром 2138. Требуется узнать название раздела, к которому она относится.
$itemElement = CIBlockElement::GetByID(2138)->Fetch(); echo 'Название элемента: ' . $itemElement['NAME'] . '<br>'; $itemSection = CIBlockSection::GetByID($itemElement["IBLOCK_SECTION_ID"])->Fetch(); echo 'Название родительской секции: ' . $itemSection['NAME'];
А вот пример получения свойства элемента:
$arIBlockElement = GetIBlockElement(2138); $MINIMUM_WEIGHT = $arIBlockElement['PROPERTIES']['MINIMUM_WEIGHT']['VALUE'];
Выборка элементов раздела с ID 101 инфоблока с ID 12:
$itemsElement = GetIBlockElementList(12, 101, Array("SORT"=>"DESC")); while($arItem = $itemsElement->GetNext()) { echo $arItem["NAME"]."<br>"; }
При такой выборке свойства полей инфоблока не попадут в результат, поэтому следует в цикле использовать предыдущий пример.
Изменение элемента инфоблока
API Bitrix позволяет создавать, удалять и редактировать элементы инфоблоков. Рассмотрим пример с изменением названия и детального описания у карточки товара с идентификатром 2138.
$element = new CIBlockElement; $res = $element->Update(2138, array( "NAME" => "Хачапури с сыром", "DETAIL_TEXT" => '<p>Текст <b>детального</b> описания</p>', "DETAIL_TEXT_TYPE" => 'html', "TIMESTAMP_X" => FALSE ));
В качестве параметра передаётся массив с полями, которые требуют перезаписи. Чтобы у элемента не поменялась дата последнего изменения, добавьте в массив параметр 'TIMESTAMP_X' => FALSE.
Аналогичным образом осуществляется удаление и добавление новых элементов, смотрите официальную документацию по CIBlockElement::Delete и CIBlockElement::Add.
Выборка разделов инфоблока
Получаем все разделы и подразделы инфоблока c ID 12:
$itemsSection = GetIBlockSectionList(12); while($arItem = $itemsSection->GetNext()) { echo $arItem["NAME"]."<br>"; }
Выбираем подразделы из раздела c ID 99 инфоблока с ID 12:
$itemsSection = GetIBlockSectionList(12, 99, Array("SORT"=>"DESC")); while($arItem = $itemsSection->GetNext()) { echo $arItem["NAME"]."<br>"; }
Выборка из инфоблока (ID=12) 20 активных разделов/подразделов:
$arFilter = array("ACTIVE" => "Y","GLOBAL_ACTIVE"=>"Y"); $arSort = array("SORT"=>"DESC"); $itemsSection = GetIBlockSectionList(12, false, $arSort, 20, $arFilter); while($arItemSection = $itemsSection->GetNext()) { echo $arItemSection["NAME"]."<br>"; }
Пример аналогичен предыдущему, за исключением добавления новых параметров. Они являются не обязательными, но Bitrix разработчики знать их должны.
- 12 — идентификатор инфоблока.
- false — указывает что выбираем все разделы/подразделы. Вместо этого параметра можно указать ID любого раздела, чтобы выбирать уже его подразделы.
- $arSort — массив с параметрами сортировки результатов. Подробности смотрите в официальной документации.
- 20 — ограничение по выборке, по-умолчанию — 0.
- $arFilter — массив с условиями выборки. В нашем случае в него записано два условия:
- ACTIVE — раздел/подраздел должен быть активным;
- GLOBAL_ACTIVE — вся цепочка родительских разделов так же должна быть активна.
Перебор и обработка активных элементов
Код перебора всех разделов каталога с обработкой названия у активных карточект товаров. Обработка заключается в подмене «Машина» на «Авто». Комментарии в коде.
$countEditElements = 0; $arrayIdElem = array(); // Вынимаем все активные секции инфоблока 12 (max = 6000) $itemsSection = GetIBlockSectionList(12, false, array("SORT"=>"DESC"), 6000, array("ACTIVE" => "Y","GLOBAL_ACTIVE"=>"Y")); while($arItemSection = $itemsSection->GetNext()) { // Выбираем все элементы текущей секции $itemsElement = GetIBlockElementList(12, $arItemSection["ID"]); while($arItem = $itemsElement->GetNext()) { // Если элемент уже был в другом разделе, то пропускаем if (in_array($arItem["ID"], $arrayIdElem)) { continue; } else $arrayIdElem[] = $arItem["ID"]; $currentName = $arItem["NAME"]; $newName = preg_replace('|^Машина (.+)$|i', 'Авто $1', $currentName); if ($currentName != $newName) { $element = new CIBlockElement; $res = $element->Update($arItem[ID], array("NAME" => $newName, 'TIMESTAMP_X' => FALSE)); $countEditElements++; } } } echo 'Было изменено элементов: ' . $countEditElements;
Примеры по обработке выполняйте только при наличии резервной копии базы данных. Это позволит сделать откат в случае ошибки или непредвиденных обстоятельств.
При необходимости изменения дополнительных свойств элементов, используйте следующую функцию:
$element = new CIBlockElement; $arProperty = Array( "CATALOG_AVAILABLE" => 2, ); $res = $element->SetPropertyValuesEx($arItem[ID], false , $arProperty);
Получение пользовательских полей
Часто элементы и разделы дополняют пользовательскими полями. Это поля, которые носят префикс «UF_» (user field). Для получения их значений предыдущие способы не подходят, так как результирующий набор их не может содержать. Следует использовать методы «CIBlockSection::GetList» для разделов и «CIBlockElement::GetList» для элементов.
Пример получения пользовательского поля «UF_H1» раздела (ID 99), инфоблока с ID 12:
$arFilter = array( "IBLOCK_ID" => 12, "ID" => $arCurSection['ID'], "ACTIVE" => "Y", "GLOBAL_ACTIVE"=>"Y", "CODE" => 99 ); $arSort = array("SORT"=>"DESC"); $itemsSection = CIBlockSection::GetList( $arSort, $arFilter, false, $arSelect = array("UF_H1") ); $UF_H1 = ''; while($arItemSection = $itemsSection->GetNext()) { $UF_H1 = $arItemSection["UF_H1"]; }