В сортировке по id есть варианты по возрастанию и по убыванию. Но что делать когда нужен строгий порядок?
Битрикс – свой порядок товаров в сортировке
Немного теории:
Основная сортировка работает через массив arOrder, и если речь про id то выглядит так:
$arOrder = ['id' => 'asc']; $arOrder = ['id' => 'desc'];
С версии 18.6.700 у нас появилась возможность указывать массив из id элементов (новостей, товаров, записей блога и т.д.). Как это выглядит на практике:
$arFilterItem = [2, 1, 3]; $arOrder = ['id' => $arFilterItem];
$arFilterItem – в данном случае массив из id. Важно! Этот же массив должен быть передан в фильтр (параметр arFilter). Именно так говорит нам документация.
Но как нам собрать массив в определенном порядке? Давайте рассмотрим на реальном примере.
Как выводить товары по сортировке из разделов в Битриксе?
Разделим задачу на две части. В первой мы получаем список разделов по индексу сортировке (которая стандартно равна 500):
$res = CIBlockSection::GetList ( Array("SORT" => "ASC"), Array("IBLOCK_ID" => $IBLOCK_ID, "ACTIVE" => "Y"), false, Array('ID') ); while ($arItem = $res->GetNext()) { $arSections[] = $arItem['ID']; }
Вторая часть – используем полученные ID разделов, для поиска товаров из них:
foreach ($arSections as $section) { $res = CIBlockElement::GetList ( Array("SORT" => "ASC"), Array("IBLOCK_ID" => $IBLOCK_ID, "ACTIVE" => "Y", "SECTION_ID" => $section), false, false, Array('ID') ); while ($arItem = $res->GetNext()) { if (!in_array($arItem['ID'], $arFilterItem)) { $arFilterItem[] = $arItem['ID']; } } } $sort = 'id'; $order = $arFilterItem;
Как видно из кода, теперь у нас есть список товаров, но выводится он именно в том порядке, в котором отсортированы наши разделы.
Каждый раз считать такой объем информации нецелесообразно, поэтому рекомендую повесить данный скрипт на cron и считать раз в сутки порядок товаров. Но это уже, как говорится, другая история 🙂 Сейчас куда важнее уловить суть происходящего.
Код целиком выглядит так:
$res = CIBlockSection::GetList ( Array("SORT" => "ASC"), Array("IBLOCK_ID" => $IBLOCK_ID, "ACTIVE" => "Y"), false, Array('ID') ); while ($arItem = $res->GetNext()) { $arSections[] = $arItem['ID']; } $arFilterItem = []; foreach ($arSections as $section) { $res = CIBlockElement::GetList ( Array("SORT" => "ASC"), Array("IBLOCK_ID" => $IBLOCK_ID, "ACTIVE" => "Y", "SECTION_ID" => $section), false, false, Array('ID') ); while ($arItem = $res->GetNext()) { if (!in_array($arItem['ID'], $arFilterItem)) { $arFilterItem[] = $arItem['ID']; } } } $sort = 'id'; $order = $arFilterItem; .. "ELEMENT_SORT_FIELD" => $sort, "ELEMENT_SORT_ORDER" => $order, ..
Вот и всё, теперь порядок можно использовать не только в своем API, но и в стандартных компонентах.