Этот код создает иерархическое меню разделов и элементов инфоблока с сохранением структуры вложенности для использования в компонентах меню Битрикс.
Код |
---|
<?php
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
$IBLOCK_ID = 5;
if (!CModule::IncludeModule('iblock')) {
return;
}
$aMenuLinks = [];
// Получение разделов
$allSections = [];
$rsSections = CIBlockSection::GetList(
['LEFT_MARGIN' => 'ASC'],
['IBLOCK_ID' => $IBLOCK_ID, 'ACTIVE' => 'Y'],
false,
['ID', 'NAME', 'SECTION_PAGE_URL', 'DEPTH_LEVEL', 'IBLOCK_SECTION_ID']
);
while ($section = $rsSections->GetNext()) {
$section['CHILDREN'] = [];
$section['ELEMENTS'] = [];
$allSections[$section['ID']] = $section;
}
// Построение дерева
$sectionTree = [];
foreach ($allSections as $id => $section) {
$parentId = $section['IBLOCK_SECTION_ID'];
if ($parentId > 0 && isset($allSections[$parentId])) {
$allSections[$parentId]['CHILDREN'][$id] = &$allSections[$id];
} else {
$sectionTree[$id] = &$allSections[$id];
}
}
// Получение элементов
$rsElements = CIBlockElement::GetList(
['SORT' => 'ASC'],
['IBLOCK_ID' => $IBLOCK_ID, 'ACTIVE' => 'Y'],
false,
false,
['ID', 'NAME', 'DETAIL_PAGE_URL', 'IBLOCK_SECTION_ID']
);
while ($element = $rsElements->GetNext()) {
$sectionId = $element['IBLOCK_SECTION_ID'];
if (isset($allSections[$sectionId])) {
$allSections[$sectionId]['ELEMENTS'][] = [
'NAME' => $element['NAME'],
'URL' => $element['DETAIL_PAGE_URL']
];
}
}
// Построение меню (с вложенными подпунктами)
function buildMenuTree($tree) {
$menu = [];
foreach ($tree as $section) {
$subMenu = [];
// Элементы раздела
foreach ($section['ELEMENTS'] as $element) {
$subMenu[] = [
$element['NAME'],
$element['URL'],
[],
['DEPTH_LEVEL' => $section['DEPTH_LEVEL'] + 1],
''
];
}
// Подразделы
if (!empty($section['CHILDREN'])) {
$subMenu = array_merge($subMenu, buildMenuTree($section['CHILDREN']));
}
$menu[] = [
$section['NAME'],
$section['SECTION_PAGE_URL'],
$subMenu,
['DEPTH_LEVEL' => $section['DEPTH_LEVEL']],
''
];
}
return $menu;
}
$aMenuLinks = buildMenuTree($sectionTree);
?> |
Возможное улучшение: кеширование (если критична производительность)
Код |
---|
$obCache = new CPHPCache();
$cacheTime = 3600; // 1 час
$cacheDir = '/menu_cache/iblock_' . $IBLOCK_ID;
if ($obCache->InitCache($cacheTime, '', $cacheDir)) {
$aMenuLinks = $obCache->GetVars();
} else {
if ($obCache->StartDataCache()) {
// ... весь код построения меню (от получения разделов до buildMenuTree)
$aMenuLinks = buildMenuTree($sectionTree);
$obCache->EndDataCache($aMenuLinks);
} else {
// fallback, если кеш не удалось создать
$aMenuLinks = [];
}
} |