Мой ремейк очень полезного алгоритма прохода по дереву каталога от Юлии Бедросовой
Небольшой ремейк для себя
CModule::IncludeModule('iblock'); $map=array(); $arParams["IBLOCK_MAP_ID"] = XX; // - каким-то образом задается параметр с ID инфоблока $sort_by = 'name'; // поле, по которому нужно произвести сортировку разделов $sort_order = 'asc'; // направление сортировки if(isset($arParams["IBLOCK_MAP_ID"])){ $arFilter = Array( 'IBLOCK_ID'=>$arParams["IBLOCK_MAP_ID"], 'GLOBAL_ACTIVE'=>'Y' ); $db_list = CIBlockSection::GetList(Array($sort_by=>$sort_order), $arFilter, true); while($ar_result = $db_list->GetNext()) { $map[''.$ar_result['ID']]=$ar_result; } }
Таким образом, в переменной $map получаем полный список разделов, отсортированных по нужному полю и в нужном направлении.
Дальше - строим дерево из разделов:
$map_sec = array(); foreach ($map as $key => $val) { if ($val['IBLOCK_SECTION_ID'] > 0) { $parent_id = $map[$val['IBLOCK_SECTION_ID']]['ID']; if(!isset($map_sec[$parent_id])){ $map_sec[$parent_id]['ID'] = $map[$parent_id]['ID']; $map_sec[$parent_id]['CODE'] = $map[$parent_id]['CODE']; $map_sec[$parent_id]['NAME'] = $map[$parent_id]['NAME']; $map_sec[$parent_id]['SECTION_PAGE_URL'] = $map[$parent_id]['SECTION_PAGE_URL']; $map_sec[$parent_id]['UF_SOMECODE'] = $map[$parent_id]['UF_SOMECODE']; $map_sec[$parent_id]['DEPTH_LEVEL'] = $map[$parent_id]['DEPTH_LEVEL']; $map_sec[$parent_id]['IBLOCK_SECTION_ID'] = $map[$parent_id]['IBLOCK_SECTION_ID']; } $map_sec[$parent_id]['CHILDS'][$val['ID']] = array( "ID" => $val['ID'], "CODE" => $val['CODE'], "NAME" => $val['NAME'], "DEPTH_LEVEL" => $val['DEPTH_LEVEL'], "SECTION_PAGE_URL" => $val['SECTION_PAGE_URL'], "UF_SOMECODE" => $val['UF_SOMECODE'], "IBLOCK_SECTION_ID" => $val['IBLOCK_SECTION_ID'], ); } else { if(!isset($map_sec[$val['ID']])){ $map_sec[$val['ID']] = array( "ID" => $val['ID'], "CODE" => $val['CODE'], "NAME" => $val['NAME'], "DEPTH_LEVEL" => $val['DEPTH_LEVEL'], "SECTION_PAGE_URL" => $val['SECTION_PAGE_URL'], "UF_SOMECODE" => $val['UF_SOMECODE'], "IBLOCK_SECTION_ID" => $val['IBLOCK_SECTION_ID'], ); } } }
Таким образом, в переменной $map_sec хранится дерево разделов. В отличие от гениально простого алгоритма, предложенного Юлией по ссылке в начале статьи - данный алгоритм также учитывает и те разделы, который не имеют подразделов, а являются листьями на первом же уровне вложенности.
Ну и напоследок, алгоритм вывода дерева, начиная с конкретного узла, или всего дерева целиком:
function ShowElementsTree($category_arr, $parent_id) { if (intval($parent_id) > 0) { if (isset($category_arr[$parent_id])) { foreach ($category_arr[$parent_id]['CHILDS'] as $value) { // Обходим echo "<div style=\"margin-left:" . ($value['DEPTH_LEVEL'] * 25) . "px;\">" . $value['ID'] . '. ' . $value['NAME'] . ' (' . $value['ELEMENT_CNT'] . ')' . "</div>"; echo "<div style=\"margin-left:" . ($value['DEPTH_LEVEL'] * 35) . "px;\">"; // тут выводим какие-то дополнительные данные о разделе echo "</div>"; if (count($category_arr[$value["ID"]]['CHILDS']) > 0) { //Рекурсивно вызываем эту же функцию, но с новым $parent_id self::ShowElementsTree($category_arr, $value["ID"]); } else { //Выводим листик } } } } else { foreach ($category_arr as $parent_id => $arItems) { if (isset($category_arr[$parent_id])) { $value = $category_arr[$parent_id]; echo "<div>" . $value['ID'] . '. ' . $value['NAME'] . ' (' . $value['ELEMENT_CNT'] . ')' . "</div>"; foreach ($category_arr[$parent_id]['CHILDS'] as $value) { //Обходим echo "<div style=\"margin-left:" . ($value['DEPTH_LEVEL'] * 25) . "px;\">" . $value['ID'] . '. ' . $value['NAME'] . ' (' . $value['ELEMENT_CNT'] . ')' . "</div>"; echo "<div style=\"margin-left:" . ($value['DEPTH_LEVEL'] * 35) . "px;\">"; // тут выводим какие-то дополнительные данные о разделе echo "</div>"; if (count($category_arr[$value["ID"]]['CHILDS']) > 0) { // Рекурсивно вызываем эту же функцию, но с новым $parent_id self::ShowElementsTree($category_arr, $value["ID"]); } else { //Выводим листик } } } } } }
Таким образом, если нужно вывести все дерево, вызываем функцию:
ShowElementsTree($map_sec,'');
а для того, чтобы вывести ветку только для одного раздела, вторым параметром передаем этот раздел.
Надеюсь, кому-то кроме меня этот алгоритм будет полезен ...
Всем легкого кода!
UPDATE 2015-09-29: Понадобилось тут мне дерево разделов в формате массива, а не в формате echo-публикаций. Вот родилась новая функция:
function GetSectionsTreeArray(&$category_arr, $parent_id){ $arResult = array(); if (intval($parent_id) > 0) { if (isset($category_arr[$parent_id])) { foreach ($category_arr[$parent_id]['CHILDS'] as $value) { if (count($category_arr[$value["ID"]]['CHILDS']) > 0) { //Рекурсивно вызываем эту же функцию, но с новым $parent_id $value['CHILDS'] = self::GetSectionsMenu($category_arr, $value["ID"]); } $arResult[$value["ID"]] = $value; } } } else { foreach ($category_arr as $parent_id => $arItems) { if (isset($category_arr[$parent_id])) { $value = $category_arr[$parent_id]; if(intval($value['DEPTH_LEVEL']) > 1) continue; foreach ($category_arr[$parent_id]['CHILDS'] as $value2) { if (count($category_arr[$value2["ID"]]['CHILDS']) > 0) { $value2['CHILDS'] = self::GetSectionsMenu($category_arr, $value2["ID"]); } $value['CHILDS'][$value2["ID"]] = $value2; } $arResult[$value["ID"]] = $value; } } } return $arResult; }
Разработка сайта
Подайте заявку на разработку сайта на базе готового решения от компании 1С-Битрикс или одного из партнеров компании. Максимально подробно опишите, чему будет посвящен сайт, если это интернет-магазин - что он будет продавать, нужна ли мультиязычность, будут ли разные типы цен (розница, опт, крупный опт), будет ли интеграция с 1С, будет ли выгрузка товаров на различные торговые площадки...
Сопровождение сайта
Вы можете подать заявку на сопровождение вашего сайта на базе 1С-Битрикс. Сопровождение включает в себя: проверка актуальности обновлений сайта, проверка актуальности резервной копии, консультации по сайту. Опишите в заявке, какие еще объемы планируются на сопровождении и на какой срок вы планируете заключить договор на сопровождение - мы подберем подходящий вам бюджет на сопровождение
Работы по сайту
Вы можете подать заявку на выполнение определенного объема работ по сайту. Опишите в заявке объем работ. Это может быть разработка какого-то нового функционала, доработки по имеющемуся функционалу, доработки под требования сео-специалистов. На основании заявки вам будет сформирован бюджет работ, а также названы сроки на выполнение тех или иных работ.