Bitrix массив в дерево

Универсальный скрипт создания дерева из ассоциативного массива

Достаточно распространенная задача получать дерево разделов из какого-то внешнего источника и отображение их в виде дерева. В данном посте будет функция-заготовка для обработки таких вот разделов и построения дерева

Сама идея построения дерева очень проста: необходимо всем элементам найти их предков, а после этого всем предкам добавить их потомков. Реализация ниже:

class someClass< var $arSections; // как-то его заполняем массив function Get1CTreeSections() < $sections = []; foreach ($this->arSections as $arSection) < $sections[$arSection['GUID']] = $arSection; // преобразовываем массив, //чтобы ключами были обязательно прописаны уникальные идентификаторы >if(empty($sections)) < return false; >$this->arSections = $sections; unset($sections); $arTree = self::MakeTreeFromArray($this->arSections,false,'GUID','SGUID'); return $arTree; > function MakeTreeFromArray($array,$key=false,$keyField='GUID',$parentKeyField='SGUID') < $branch = []; foreach ($array as &$element)< if($element[$parentKeyField] !== null && $array[$element[$parentKeyField]]==null)< unset($element[$parentKeyField]); >if($element[$parentKeyField]==$key) < $children = self::MakeTreeFromArray( $array, $element[$keyField], $keyField, $parentKeyField); if($children)< $element['children'] = $children; >$branch[$element[$keyField]] = $element; unset($element); > > return $branch; > >

Разработка сайта

Подайте заявку на разработку сайта на базе готового решения от компании 1С-Битрикс или одного из партнеров компании. Максимально подробно опишите, чему будет посвящен сайт, если это интернет-магазин — что он будет продавать, нужна ли мультиязычность, будут ли разные типы цен (розница, опт, крупный опт), будет ли интеграция с 1С, будет ли выгрузка товаров на различные торговые площадки.

Сопровождение сайта

Вы можете подать заявку на сопровождение вашего сайта на базе 1С-Битрикс. Сопровождение включает в себя: проверка актуальности обновлений сайта, проверка актуальности резервной копии, консультации по сайту. Опишите в заявке, какие еще объемы планируются на сопровождении и на какой срок вы планируете заключить договор на сопровождение — мы подберем подходящий вам бюджет на сопровождение

Работы по сайту

Вы можете подать заявку на выполнение определенного объема работ по сайту. Опишите в заявке объем работ. Это может быть разработка какого-то нового функционала, доработки по имеющемуся функционалу, доработки под требования сео-специалистов. На основании заявки вам будет сформирован бюджет работ, а также названы сроки на выполнение тех или иных работ.

Читайте также:  Чем обработать стволы плодовых деревьев летом

Copyright © pai-bx.com | Попович Алексей. Персональный сайт разработчика, 1986-2023

Источник

Универсальный скрипт создания дерева из ассоциативного массива

Достаточно распространенная задача получать дерево разделов из какого-то внешнего источника и отображение их в виде дерева. В данном посте будет функция-заготовка для обработки таких вот разделов и построения дерева

Сама идея построения дерева очень проста: необходимо всем элементам найти их предков, а после этого всем предкам добавить их потомков. Реализация ниже:

class someClass< var $arSections; // как-то его заполняем массив function Get1CTreeSections() < $sections = []; foreach ($this->arSections as $arSection) < $sections[$arSection['GUID']] = $arSection; // преобразовываем массив, //чтобы ключами были обязательно прописаны уникальные идентификаторы >if(empty($sections)) < return false; >$this->arSections = $sections; unset($sections); $arTree = self::MakeTreeFromArray($this->arSections,false,'GUID','SGUID'); return $arTree; > function MakeTreeFromArray($array,$key=false,$keyField='GUID',$parentKeyField='SGUID') < $branch = []; foreach ($array as &$element)< if($element[$parentKeyField] !== null && $array[$element[$parentKeyField]]==null)< unset($element[$parentKeyField]); >if($element[$parentKeyField]==$key) < $children = self::MakeTreeFromArray( $array, $element[$keyField], $keyField, $parentKeyField); if($children)< $element['children'] = $children; >$branch[$element[$keyField]] = $element; unset($element); > > return $branch; > >

Разработка сайта

Подайте заявку на разработку сайта на базе готового решения от компании 1С-Битрикс или одного из партнеров компании. Максимально подробно опишите, чему будет посвящен сайт, если это интернет-магазин — что он будет продавать, нужна ли мультиязычность, будут ли разные типы цен (розница, опт, крупный опт), будет ли интеграция с 1С, будет ли выгрузка товаров на различные торговые площадки.

Сопровождение сайта

Вы можете подать заявку на сопровождение вашего сайта на базе 1С-Битрикс. Сопровождение включает в себя: проверка актуальности обновлений сайта, проверка актуальности резервной копии, консультации по сайту. Опишите в заявке, какие еще объемы планируются на сопровождении и на какой срок вы планируете заключить договор на сопровождение — мы подберем подходящий вам бюджет на сопровождение

Работы по сайту

Вы можете подать заявку на выполнение определенного объема работ по сайту. Опишите в заявке объем работ. Это может быть разработка какого-то нового функционала, доработки по имеющемуся функционалу, доработки под требования сео-специалистов. На основании заявки вам будет сформирован бюджет работ, а также названы сроки на выполнение тех или иных работ.

Читайте также:  Низкая теплопроводность у дерева

Copyright © pai-bx.com | Попович Алексей. Персональный сайт разработчика, 1986-2023

Источник

Как вывести из инфоблока определенные разделы и вложенные элементы в виде дерева?

1. Делаешь выборку разделов по ИД — $idSections = array(104,105,106); // ID разделов
А элементы получаешь все, без ограничений. Я так понимаю элементы тоже нужны только для указанных разделов, тогда в массив $arFilter для CIBlockElement::GetList стоит добавить это ограничение

$arFilter = array("IBLOCK_ID" => $IBLOCK_ID, "ACTIVE_DATE" => "Y", "ACTIVE" => "Y", 'IBLOCK_SECTION_ID' => $idSections);

И вот это дело array(«nPageSize» => 100) тоже убери, хитрец)) — поставь false

2. Лично от меня пожелание, если пишешь в процедурном стиле, когда делаешь выборку собирай массив с ключами = ID, например вместо

while ($sectRes = $dbResSect->GetNext())
while ($sectRes = $dbResSect->GetNext())

3. Все дело в коде под комментариями

// Находим все разделы элемента и собираем их в массив // Собираем массив из разделов и элементов

Запросы в цикле — это плохо, больше элементов в цикле = больше запросов

Итого меняем три блока
1. Добавляем ID в ключи

// Получаем разделы и собираем их в массив while ($sectRes = $dbResSect->GetNext())

2. Добавляем разделы в фильтр, убираем nPageSize и добавляем ключи = ID

// Формируем массив элементов по фильтру //. $arFilter = array("IBLOCK_ID" => $IBLOCK_ID, 'IBLOCK_SECTION_ID' => $idSections, "ACTIVE_DATE" => "Y", "ACTIVE" => "Y"); $res = CIBlockElement::GetList(array("ID" => "ASC"), $arFilter, false, false, $arSelect); while ($el = $res->Fetch())

3. Меняем проблемный блок, т.е. все что ниже комментария // Находим все разделы элемента и собираем их в массив

$elementIdsBySectionIds = []; $iterator = \Bitrix\Iblock\SectionElementTable::getList([ 'select' => ['IBLOCK_SECTION_ID', 'IBLOCK_ELEMENT_ID'], 'filter' => ['IBLOCK_SECTION_ID' => $idSections] ]); while($row = $iterator->fetch()) < $elementIdsBySectionIds[$row['IBLOCK_SECTION_ID']][$row['IBLOCK_ELEMENT_ID']] = $row['IBLOCK_ELEMENT_ID']; >// здесь как раз пригодятся ключи = ID foreach($elementIdsBySectionIds as $sectionId => $elementIds) < foreach($elementIds as $elementId) < if(isset($arResult["ITEMS"][$elementId])) < $arSections[$sectionId]['ITEMS'][] = $arResult["ITEMS"][$elementId]; >> > $arResult = $arSections;
CModule::IncludeModule('iblock'); //Подключаем модуль "Информационные блоки" // Параметры $IBLOCK_ID = 7; // ID ифноблока $idSections = array(104,105,106); // ID разделов // Формируем список разделов по фильтру $dbResSect = CIBlockSection::GetList( array("SORT" => 'asc'), // Параметры сортировки array( "IBLOCK_ID" => $IBLOCK_ID, // ID инфоблока "ID" => $idSections, // Массив разделов ), false, array("ID", "NAME", "UF_ITEMPROP") // Выбираем необходимые поля разделов. ); // Получаем разделы и собираем их в массив while ($sectRes = $dbResSect->GetNext()) < $arSections[$sectRes['ID']] = $sectRes; >// Формируем массив элементов по фильтру $arResult = []; $arSelect = Array( "ID", "NAME", "IBLOCK_ID", "IBLOCK_SECTION_ID", "PROPERTY_FILE", "PROPERTY_ITEMPROP", ); $arFilter = array("IBLOCK_ID" => $IBLOCK_ID, 'IBLOCK_SECTION_ID' => $idSections, "ACTIVE_DATE" => "Y", "ACTIVE" => "Y"); $res = CIBlockElement::GetList(array("ID" => "ASC"), $arFilter, false, false, $arSelect); while ($el = $res->Fetch()) < $arResult["ITEMS"][$el['ID']] = $el; >$elementIdsBySectionIds = []; $iterator = \Bitrix\Iblock\SectionElementTable::getList([ 'select' => ['IBLOCK_SECTION_ID', 'IBLOCK_ELEMENT_ID'], 'filter' => ['IBLOCK_SECTION_ID' => $idSections] ]); while($row = $iterator->fetch()) < $elementIdsBySectionIds[$row['IBLOCK_SECTION_ID']][$row['IBLOCK_ELEMENT_ID']] = $row['IBLOCK_ELEMENT_ID']; >foreach($elementIdsBySectionIds as $sectionId => $elementIds) < foreach($elementIds as $elementId) < if(isset($arResult["ITEMS"][$elementId])) < $arSections[$sectionId]['ITEMS'][] = $arResult["ITEMS"][$elementId]; >> > $arResult = $arSections;

UPD
На моей выборке, примерно 15 товаров, стало меньше на 53 запроса к БД

Читайте также:  Пересадить денежное дерево отростком

Источник

Получение иерархии разделов

Приведу небольшой примерчик как одним запросом и одним циклом получить иерархию разделов в виде:

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

Источник

Оцените статью