Иногда на практике разработки приходится решать нестандартные задачи, посредством использования стандартного API битрикса. Возникла необходимость получить корневой раздел элемента, который находится на несколько уровней выше по структуре каталога. После чего уже относительно корневого элемента требуется выбрать несколько вложенных элементов. Первое что требуется сделать это определить корневой раздел.
Некоторое время потратил на поиск просмотр документации, и отдельного специального метода для этой задачи я не нашел. По этой причине нашел другой выход из ситуации, посредством получения массива всей цепочки разделов до основного.
Имея поля элемента, мы знаем IBLOCK_SECTION_ID раздела, непосредственно в котором находится элемент. Относительного него мы и начнём отталкиваться. Получить всю цепочку разделов мы можем с помощью метода CIBlockSection::GetNavChain(), после этого проверяя поле DEPTH_LEVEL – уровень вложенности, мы сможем определить запись корневого раздела.
// получение цепочки разделов $scRes = CIBlockSection::GetNavChain( $arResult['IBLOCK_ID'], $arResult['IBLOCK_SECTION_ID'], array("ID","DEPTH_LEVEL") ); $ROOT_SECTION_ID = 0; while($arGrp = $scRes->Fetch()){ // определяем корневой раздел if ($arGrp['DEPTH_LEVEL'] == 1){ $ROOT_SECTION_ID = $arGrp['ID']; } }
В этом участке кода всё что требуется сделать, это определить ID корневого раздела. В качестве входных параметров методу передаются IBLOCK_ID (ID инфоблока) и IBLOCK_SECTION_ID (ID раздела элемента). Третий параметр массив полей для выборки.
Теперь приступим к выборке элементов, здесь всё гораздо удобнее, получаем список элементов, посредством метода CIBlockElement::GetList().
if ($ROOT_SECTION_ID > 0){ // выбираем товары относительно корневого раздела $res = CIBlockElement::GetList( array(), array( "ACTIVE" => "Y", "IBLOCK_ID" => $arResult['IBLOCK_ID'], "IBLOCK_TYPE" => $arResult['IBLOCK_TYPE'], "!=ID" => $arResult['ID'], "IBLOCK_SECTION_ID" => $ROOT_SECTION_ID, "INCLUDE_SUBSECTIONS" => "Y" ), false, array("nTopCount" => 12), // ограничение выборки до 12 array("ID","NAME","PREVIEW_PICTURE","DETAIL_PAGE_URL","CATALOG_GROUP_1","PROPERTY_PRICE_TEXT") ); $arResult['RCM_PRODUCTS'] = array(); while($ob = $res->GetNextElement()){ $arFields = $ob->GetFields(); if ($arFields['PREVIEW_PICTURE'] > 0){ $arFields['PREVIEW_PICTURE'] = CFile::GetPath($arFields["PREVIEW_PICTURE"]); } $arResult['RCM_PRODUCTS'][] = $arFields; } }
В моём примере для выборки используются элементы, которые представляют из себя товары каталога. По этой причине, в полях для выборки данных указаны некоторые данные которые характерны именно для моего случая. Кроме того, в самом фильтре указано несколько полей. Хотел обратить внимание на запись «!=ID». Эта запись обозначает что элементы с указанным ID (ID текущего элемента), должны исключаться. Запись фильтра INCLUDE_SUBSECTIONS указывает на то чтобы выборка производилась так же из вложенных секций.
На этом вроде всё, если есть вопросы, пишите в комментариях, постараюсь ответить.