yunaweb / bitrix-section-tree
Build/flatten section trees from flat lists (e.g. Bitrix CIBlockSection / D7 SectionTable rows) without hierarchy hacks.
v0.1.0
2026-07-20 21:20 UTC
Requires
- php: >=8.1
Requires (Dev)
- phpunit/phpunit: ^10.5
README
Собрать дерево разделов из плоского списка (например, из \Bitrix\Iblock\SectionTable::getList() или CIBlockSection::GetList()) — без ручного unset/usort-хака. Работает с обычными PHP-массивами, к Bitrix не привязан.
Установка
composer require yunaweb/bitrix-section-tree
Использование
Плоский список → дерево
use Yunaweb\SectionTree\SectionTree; $sections = [ ['ID' => 1, 'IBLOCK_SECTION_ID' => null, 'NAME' => 'Каталог'], ['ID' => 2, 'IBLOCK_SECTION_ID' => 1, 'NAME' => 'Телефоны'], ['ID' => 3, 'IBLOCK_SECTION_ID' => 1, 'NAME' => 'Ноутбуки'], ]; $tree = SectionTree::toTree($sections); // $tree[0]['NAME'] === 'Каталог' // $tree[0]['CHILDREN'][0]['NAME'] === 'Телефоны'
Дерево → плоский список с глубиной и путём
$flat = SectionTree::toFlat($tree); // $flat[1]['DEPTH'] === 1 // $flat[1]['PATH'] === [1, 2]
Цепочка предков (breadcrumbs)
$chain = SectionTree::breadcrumbs($sections, 2); // array_column($chain, 'NAME') === ['Каталог', 'Телефоны']
С Bitrix D7
use Bitrix\Iblock\SectionTable; use Yunaweb\SectionTree\SectionTree; $rows = SectionTable::getList([ 'filter' => ['IBLOCK_ID' => 8], 'select' => ['ID', 'IBLOCK_SECTION_ID', 'NAME', 'SORT'], ])->fetchAll(); $tree = SectionTree::toTree($rows);
Пример: <select> с отступами по уровню вложенности
$flat = SectionTree::toFlat(SectionTree::toTree($sections)); foreach ($flat as $section) { $indent = str_repeat('— ', $section['DEPTH']); echo '<option value="' . htmlspecialchars((string) $section['ID']) . '">' . $indent . htmlspecialchars($section['NAME']) . "</option>\n"; }
Пример: рекурсивное меню (вложенные <ul>)
function renderMenu(array $items): string { $html = '<ul>'; foreach ($items as $item) { $html .= '<li>' . htmlspecialchars($item['NAME']); if ($item['CHILDREN'] !== []) { $html .= renderMenu($item['CHILDREN']); } $html .= '</li>'; } return $html . '</ul>'; } echo renderMenu(SectionTree::toTree($sections));
Настраиваемые ключи
Если поля называются не как в Bitrix (ID / IBLOCK_SECTION_ID), передайте свои имена:
SectionTree::toTree($items, idKey: 'id', parentKey: 'parent_id');
Ошибки
Отсутствующий idKey в элементе, дублирующийся id, циклическая ссылка на родителя или breadcrumbs() с несуществующим id бросают Yunaweb\SectionTree\Exception\SectionTreeException.
Ограничения
- Библиотека сама ничего не экранирует —
NAMEи другие поля из вашего источника данных попадают в вывод как есть. Перед выводом в HTML используйтеhtmlspecialchars()(см. примеры выше). toTree()/toFlat()не рассчитаны на непроверенные данные с неограниченной глубиной вложенности: на цепочке из нескольких тысяч уровней проверка циклов и подсчётPATHработают за O(n²) по времени/памяти. Для типичной глубины разделов каталога (единицы–десятки уровней) это не заметно, но для импорта из недоверенного источника с неизвестной глубиной ограничьте её до вызова библиотеки.
Тесты
composer install vendor/bin/phpunit
Лицензия
MIT