Сортировка по SECTION_ID

Рейтинг: 1.0329  
Внедрено
Предложил Пользователь 32599 18.08.2014 15:54:00

Сортировка по SECTION_ID

Стоит следующая задача: отсортировать элементы, полученные в стандартном компоненте bitrix:catalog по полю IBLOCK_SECTION_ID.
Как оказалось, штатной такой возможности нет, в методе CAllIBlockElement::PrepareGetList() не предусмотрено соответствующего правила.
[spoiler]
Казалось бы, обычная задача: имеем N разделов, M подразделов, вручную установлена сортировка от 10 до 100 у элементов, у схожих в рамках одного подраздела элементов сортировка одинаковая.
При заходе на страницу подраздела всё работает как надо - сначала идут элементы с SORT 10, затем 20 и т.д.

Однако если зайти на страницу родительского раздела, то элементы сортируются следующим образом:
из ВСЕХ подразделов выбираются элементы с SORT 10, затем 20 и т.д.

А нужно - чтобы сначала из одного подраздела SORT-10,20,30..., затем из второго и так до конца.

Если мы в CAllIBlockElement::PrepareGetList() добавим нужное правило, такая логика станет возможной. Но, как известно, модифицировать ядро нехорошо.

Поэтому идея:
в файле /bitrix/modules/iblock/classes/general/iblockelement.php
в методе CAllIBlockElement::PrepareGetList() начиная со строки 2589 по строку 2609 идет следующий код, в котором на наш взгляд не хватает последней выделенной строчки

if($by == "ID") $arSqlOrder[$by] = CIBlock::_Order("BE.ID", $order, "desc", false);
    elseif($by == "NAME") $arSqlOrder[$by] = CIBlock::_Order("BE.NAME", $order, "desc", false);
    elseif($by == "STATUS") $arSqlOrder[$by] = CIBlock::_Order("BE.WF_STATUS_ID", $order, "desc");
    elseif($by == "XML_ID") $arSqlOrder[$by] = CIBlock::_Order("BE.XML_ID", $order, "desc");
    elseif($by == "CODE") $arSqlOrder[$by] = CIBlock::_Order("BE.CODE", $order, "desc");
    elseif($by == "TAGS") $arSqlOrder[$by] = CIBlock::_Order("BE.TAGS", $order, "desc");
    elseif($by == "TIMESTAMP_X") $arSqlOrder[$by] = CIBlock::_Order("BE.TIMESTAMP_X", $order, "desc");
    elseif($by == "CREATED") $arSqlOrder[$by] = CIBlock::_Order("BE.DATE_CREATE", $order, "desc");
    elseif($by == "CREATED_DATE") $arSqlOrder[$by] = CIBlock::_Order($DB->DateFormatToDB("YYYY.MM.DD", "BE.DATE_CREATE"), $order, "desc");
    elseif($by == "IBLOCK_ID") $arSqlOrder[$by] = CIBlock::_Order("BE.IBLOCK_ID", $order, "desc");
    elseif($by == "MODIFIED_BY") $arSqlOrder[$by] = CIBlock::_Order("BE.MODIFIED_BY", $order, "desc");
    elseif($by == "ACTIVE") $arSqlOrder[$by] = CIBlock::_Order("BE.ACTIVE", $order, "desc");
    elseif($by == "ACTIVE_FROM") $arSqlOrder[$by] = CIBlock::_Order("BE.ACTIVE_FROM", $order, "desc");
    elseif($by == "ACTIVE_TO") $arSqlOrder[$by] = CIBlock::_Order("BE.ACTIVE_TO", $order, "desc");
    elseif($by == "SORT") $arSqlOrder[$by] = CIBlock::_Order("BE.SORT", $order, "desc");
    elseif($by == "SHOW_COUNTER") $arSqlOrder[$by] = CIBlock::_Order("BE.SHOW_COUNTER", $order, "desc");
    elseif($by == "SHOW_COUNTER_START") $arSqlOrder[$by] = CIBlock::_Order("BE.SHOW_COUNTER_START", $order, "desc");
    elseif($by == "RAND") $arSqlOrder[$by] = CIBlockElement::GetRandFunction(true);
    elseif($by == "SHOWS") $arSqlOrder[$by] = CIBlock::_Order(CIBlockElement::GetShowedFunction(), $order, "desc", false);
    elseif($by == "HAS_PREVIEW_PICTURE") $arSqlOrder[$by] = CIBlock::_Order(CIBlock::_NotEmpty("BE.PREVIEW_PICTURE"), $order, "desc", false);
    elseif($by == "HAS_DETAIL_PICTURE") $arSqlOrder[$by] = CIBlock::_Order(CIBlock::_NotEmpty("BE.DETAIL_PICTURE"), $order, "desc", false); 
>>>>>>>>>>>>>>>>>>>>>>>>>
    elseif($by == "SECTION_ID") $arSqlOrder[$by] = CIBlock::_Order("BE.IBLOCK_SECTION_ID", $order, "desc", false);
<<<<<<<<<<<<<<<<<<<<<<<<<

В таблице b_iblock_elements присутствует поле IBLOCK_SECTION_ID, непонятно почему про это забыли в данном методе.
Рейтинг: 0  
Ответил Жуков Евгений 15.10.2014 17:00:14
iblock 15.0.0

Рейтинг: 0  
Пользователь 32599 18.08.2014 16:00:50
Саппорт подтвердил - тикет 519778 - "В продукте не предусмотрена сортировка элементов по полю IBLOCK_SECTION_ID."
Рейтинг: 0  
Пользователь 114664 21.08.2014 17:52:11
Боже мой:o, программисты битрикс знают про:


switch ($i) {
    case 0:
     echo "i равно 0";
     break;
    case 1:
     echo "i равно 1";
     break;
    case 2:
     echo "i равно 2";
     break;
}
 
На таком количестве условий разница во времени уже заметна!