Работа с инфоблоками на 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"];
}