ГлавнаяБлогРазделы инфоблока в виде массива 1С-Битрикс

Разделы инфоблока в виде массива 1С-Битрикс

Рамиль Юналиев
Рамиль Юналиев
E-Commerce Lead
19 января 2014 г.
2 мин чтения

По умолчанию CIBlockSection::GetList() возвращает секции в порядке обхода в ширину — плоским списком. Иногда нужна либо вложенная структура для рекурсивного рендера меню, либо плоский массив с явными метаданными иерархии для построения <select>.

Способ 1 — плоский массив с метаданными иерархии

Сортируем по left_margin, получаем поля DEPTH_LEVEL, LEFT_MARGIN, RIGHT_MARGIN, IBLOCK_SECTION_ID:

$rs_Section = CIBlockSection::GetList(array('left_margin' => 'asc'), array('IBLOCK_ID' => 8));
while ( $ar_Section = $rs_Section->Fetch() )
{
	$ar_Result[] = array(
		'ID' => $ar_Section['ID'],
		'NAME' => $ar_Section['NAME'],
		'IBLOCK_SECTION_ID' => $ar_Section['IBLOCK_SECTION_ID'],
		'LEFT_MARGIN' => $ar_Section['LEFT_MARGIN'],
		'RIGHT_MARGIN' => $ar_Section['RIGHT_MARGIN'],
		'DEPTH_LEVEL' => $ar_Section['DEPTH_LEVEL'],
	);
}

Вывод в виде <select> с отступами по уровню вложенности:

<select>
    <option> - Выбрать - </option>
    <?
    foreach( $ar_Result as $ar_Value )
    {
        $s = '';
        for($i = 1; $i <= $ar_Value['DEPTH_LEVEL']; $i++ )
            $s .= '.';
        
        $s .= ' '.$ar_Value['NAME'];
        
        ?><option value="<?=$ar_Value['ID']?>"><?=$s?></option><?
    }
    ?>
</select>

Способ 2 — вложенный массив (дерево)

Алгоритм: сортируем секции по DEPTH_LEVEL убыванием, затем итерируем от максимального уровня вниз — каждый раздел добавляем в SUB_SECTION своего родителя и удаляем из основного массива:

$rs_Section = CIBlockSection::GetList(
	array('DEPTH_LEVEL' => 'desc'),
	$ar_Filter,
	false,
	array('ID', 'NAME', 'IBLOCK_SECTION_ID', 'DEPTH_LEVEL', 'SORT')
);
$ar_SectionList = array();
$ar_DepthLavel = array();
while($ar_Section = $rs_Section->GetNext(true, false))
{
	$ar_SectionList[$ar_Section['ID']] = $ar_Section;
	$ar_DepthLavel[] = $ar_Section['DEPTH_LEVEL'];
}
 
$ar_DepthLavelResult = array_unique($ar_DepthLavel);
rsort($ar_DepthLavelResult);
 
$i_MaxDepthLevel = $ar_DepthLavelResult[0];
 
for( $i = $i_MaxDepthLevel; $i > 1; $i-- )
{
	foreach ( $ar_SectionList as $i_SectionID => $ar_Value )
	{
		if( $ar_Value['DEPTH_LEVEL'] == $i )
		{
			$ar_SectionList[$ar_Value['IBLOCK_SECTION_ID']]['SUB_SECTION'][] = $ar_Value;
			unset( $ar_SectionList[$i_SectionID] );
		}
	}
}
 
function __sectionSort($a, $b)
{
	if ($a['SORT'] == $b['SORT']) {
		return 0;
	}
	return ($a['SORT'] < $b['SORT']) ? -1 : 1;
}
 
usort($ar_SectionList, "__sectionSort");

Рекурсивный вывод дерева в виде вложенных <ul>:

function __recursivRenderMenu($ar_Items)
{
    foreach ($ar_Items as $ar_Value)
    {
        if( count($ar_Value['SUB_SECTION']) > 0  )
        {
            echo '<ul>';
                echo '<li>';
                    echo $ar_Value['NAME'];
                    echo '<ul>';
                        echo __recursivRenderMenu($ar_Value['SUB_SECTION']);
                    echo '</ul>';
                echo '</li>';
            echo '</ul>';                
        }    
        else
        {
            echo '<li>'.$ar_Value['NAME'].'</li>';
        }    
    }    
}
 
echo __recursivRenderMenu($ar_SectionList);