Приведу небольшой примерчик как одним запросом и одним циклом получить иерархию разделов в виде:
Array
(
[ROOT] => Array
(
[CHILD] => Array
(
[12] => Array
(
[ID] => 12
[~ID] => 12
[NAME] => Раздел с ид 12
[~NAME] => Раздел с ид 12
[DEPTH_LEVEL] => 1
[~DEPTH_LEVEL] => 1
[CHILD] => Array
(
[63] => Array
(
[ID] => 63
[~ID] => 63
.............
[CHILD] => Array
(
........
)
)
.......
[63] => Array
(
[ID] => 63
[~ID] => 63
.............
)
.......
)
)
..............
)
)
)
На мой взгляд, с такой структурой работать в большинстве случаев удобнее, чем со списком, отсортированном по LEFT_MARGIN
Итак код:
$arFilter = array(
'ACTIVE' => 'Y',
'IBLOCK_ID' => $arParams['IBLOCK_ID'],
'GLOBAL_ACTIVE'=>'Y',
);
$arSelect = array('IBLOCK_ID','ID','NAME','DEPTH_LEVEL','IBLOCK_SECTION_ID');
$arOrder = array('DEPTH_LEVEL'=>'ASC','SORT'=>'ASC');
$rsSections = CIBlockSection::GetList($arOrder, $arFilter, false, $arSelect);
$sectionLinc = array();
$arResult['ROOT'] = array();
$sectionLinc[0] = &$arResult['ROOT'];
while($arSection = $rsSections->GetNext()) {
$sectionLinc[intval($arSection['IBLOCK_SECTION_ID'])]['CHILD'][$arSection['ID']] = $arSection;
$sectionLinc[$arSection['ID']] = &$sectionLinc[intval($arSection['IBLOCK_SECTION_ID'])]['CHILD'][$arSection['ID']];
}
unset($sectionLinc);
Если мы получаем только активные элементы, то важно указать в фильтре ‘GLOBAL_ACTIVE’=>’Y’, иначе мы можем получить активный элемент с неактивным предком, и его некуда будет определить в иерархию.
В $arSelect нужно не забыть указать IBLOCK_SECTION_ID, иначе иерархию построить не получится
Первое поле в сортировке $arOrder должно быть ‘DEPTH_LEVEL’=>’ASC’, так как иерархия строится от предков к потомкам
Построение иерархии происходит через массив ссылок $sectionLinc