Как вывести из инфоблока определенные разделы и вложенные элементы в виде дерева?
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 запроса к БД
Источник
Форум
Всем привет! Долго ломаю голову, надеюсь хоть здесь мне смогут помочь..
Моя задача в следующем: На странице каталога нужно вывести разделы и подразделы каталога.
Структура следующая:
— Главный раздел
— Подраздел
— Дочерний раздел
— Дочерний раздел
— Подраздел
— Дочерний раздел
Т.е. переходя на страницу «главного» раздела, отображается заголовок этого раздела и подразделы с их дочерними. И так в каждом «главном» разделе.
Написал для этого функцию:
function func_sectionList($ar_Items) < $req = $_REQUEST["SECTION_ID"]; foreach ($ar_Items as $ar_Value) < $arItemR = CFile::GetFileArray($ar_Value['PICTURE']); $count = CIBlockElement::GetList( array(), array( 'IBLOCK_ID'=>$ar_Value['IBLOCK_ID'], 'SECTION_ID'=>$ar_Value['SECTION_ID'] ), array() ); $id = $ar_Value['IBLOCK_SECTION_ID'].'/'; $by_id = $ar_Value['IBLOCK_SECTION_ID']; $rsSections = CIBlockSection::GetByID($by_id); $arSection = $rsSections->Fetch(); $id_main = $arSection['IBLOCK_SECTION_ID'].'/'; if( count($ar_Value['SUB_SECTION']) > 0 ) < if ($ar_Value['DEPTH_LEVEL'] == 2 && $id == $req)< echo''; echo''; >'; echo''; echo''.$ar_Value['NAME'].'
'; echo''; ?>" alt="Битрикс вывести дерево разделов инфоблока">
'; > echo func_sectionList($ar_Value['SUB_SECTION']); > elseif ($ar_Value['DEPTH_LEVEL'] == 3 && $id_main == $req ) < echo'
- '.$ar_Value['NAME'].''; > > echo'
Она выводит все на странице в нужной обертке, сохраняя необходимую верстку.
Выглядит это так:
http://itmages.ru/image/view/2440573/3182c698
Сама верстка выглядит так:
Обнаружение - измерение3 640
- Поток, измерения давления и уровня
- Температура и влажность
- Измерение установки
- Измерение силы
- Оптические и акустические измерения
- Электрические измерение
- Аналитическое оборудование
- Метрологии и оборудование для испытаний
- Проверка и мониторинг
- Лабораторное оборудование
В файле list.php вызывается компонент catalog.section.list, в который передается ID текущего раздела в SECTION_ID. В компоненте и вызывается моя функция.Вызов функции выглядит так:
Источник
Структура разделов
Компонент стандартный, входит в дистрибутив модуля и содержит 5 шаблонов: store_v3, .default, tree, store_v3_menu и bootstrap_v4.
В визуальном редакторе компонент расположен по пути Контент > Каталог > Структура разделов.
Компонент относится к модулю Информационные блоки.
Параметры
Поле Параметр Описание Примечание Основные параметры Тип инфо-блока IBLOCK_TYPE Указывается один из созданных в системе типов информационных блоков. Инфо-блок IBLOCK_ID Для выбранного типа инфоблоков указывается идентификатор необходимого информационного блока. ID раздела SECTION_ID Указывается код, в котором передается идентификатор раздела. Код раздела SECTION_CODE Указывается код раздела. Источник данных Показывать количество элементов в разделе COUNT_ELEMENTS [Y|N] При отмеченной опции будет показано количество элементов в разделе. Показывать количество COUNT_ELEMENTS_FILTER Выбирается для каких товаров показывать количество: активных, доступных или всех. Дополнительный фильтр для подсчета количества элементов в разделе ADDITIONAL_COUNT_ELEMENTS_FILTER Задается имя переменной, в которую передается параметры дополнительного фильтра для подсчета количества элементов в разделе. Скрывать разделы с нулевым количеством элементов HIDE_SECTIONS_WITH_ZERO_COUNT_ELEMENTS [Y|N] При отмеченной опции разделы без элементов отображаться не будут. Максимальная отображаемая глубина разделов TOP_DEPTH Параметр определяет максимальную глубину отображаемых разделов. Поля разделов SECTION_FIELDS Указываются поля раздела, которые будут отображены на странице структуры разделов. Заполняется из публичной части редактора, удерживая клавишу Ctrl либо в коде, указывая массив:
- A — Авто + Управляемое: автоматически обновляет кеш компонентов в течение заданного времени или при изменении данных;
- Y — Кешировать: для кеширования необходимо определить время кеширования;
- N — Не кешировать: кеширования нет в любом случае.
Пример вызова
IncludeComponent("bitrix:catalog.section.list","", Array( "ADDITIONAL_COUNT_ELEMENTS_FILTER" => "additionalCountFilter", "VIEW_MODE" => "TEXT", "SHOW_PARENT_NAME" => "Y", "IBLOCK_TYPE" => "", "IBLOCK_ID" => "", "SECTION_ID" => $_REQUEST["SECTION_ID"], "SECTION_CODE" => "", "SECTION_URL" => "", "COUNT_ELEMENTS" => "Y", "COUNT_ELEMENTS_FILTER" => "CNT_ACTIVE", "HIDE_SECTIONS_WITH_ZERO_COUNT_ELEMENTS" => "N", "TOP_DEPTH" => "2", "SECTION_FIELDS" => "", "SECTION_USER_FIELDS" => "", "ADD_SECTIONS_CHAIN" => "Y", "CACHE_TYPE" => "A", "CACHE_TIME" => "36000000", "CACHE_NOTES" => "", "CACHE_GROUPS" => "Y" ) );?>Источник