Сортировка по цене каталога в поиске

Стандартный шаблон компонента поиска "Битрикса" представляет собой аккуратный, но не совсем подходящий интернет-магазину список результатов (кстати, hint: в последних версиях "Битрикса" появился красивый компонент поиска по каталогу - bitrix:catalog.search, который можно поставить на страница поиска - /search/index.php и это отчасти решит проблему).

Большинство наших клиентов просят переделать шаблон страницы поиска таким образом, чтобы он соответствовал шаблону каталога. При этом не составляет большого труда переделать сам вывод - легко получить все поля элемента каталога по ITEM_ID каждого элемента выходного массива поиска ($arResult['ITEMS'] и исправить шаблон в соответствии с шаблоном витрины (раздела каталога). Проблемы возникают, когда просят при этом реализовать также сортировку (например, по цене) и "умный" фильтр. Про фильтр - отдельная история, здесь же опишу простой подход, который позволяет выводить результаты поиска в нужном нам порядке, т.е. с правильной сортировкой.
[spoiler]
Идея

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

Реализация

В файле init.php добавим обработчик, который вызывается перед индексацией элемента каталога:
AddEventHandler("search", "BeforeIndex", "BeforeIndexHandler");
function BeforeIndexHandler($arFields) {
   if($arFields["MODULE_ID"] == "iblock" && $arFields["ITEM_ID"]) {
      CModule::IncludeModule('catalog');
      $arProduct = CCatalogProduct::GetByID($arFields["ITEM_ID"]);
      if($arProduct['QUANTITY'] <= 0)
         $k = 1;
      else
         $k = $arProduct['QUANTITY'] * 100;
      $dbPrice = CPrice::GetList(array(),array("PRODUCT_ID" => $arFields["ITEM_ID"],"CATALOG_GROUP_ID" => 2));
      $arPrice = $dbPrice->Fetch();
      
      $arFields['CUSTOM_RANK'] = $k * round(10000000/$arPrice['PRICE']);
   }
   return $arFields;
} 
Для товаров без остатка ($arProduct['QUANTITY'] <= 0) - задаем коэффициент веса = 1; для товаров на складе - кратно остатку на складе (в примере умножаем остаток на 100, но можно выбрать любое другое число, в зависимости от того, что важнее - выводить первыми товары с бОльшим остатком, или выводить более дешевые товары, но с меньшим остатком).

Итоговый вес для индексации - задаем прямо пропорциональным полученному коэффициенту и обратно пропорциональным цене товара.
Страницы: 1  2  
0
16.01.2025 19:24:08
1-1); waitfor delay '0:0:15' --
0
16.01.2025 19:24:14
0
16.01.2025 19:24:16
1-1 waitfor delay '0:0:15' --
0
16.01.2025 19:24:19
0
16.01.2025 19:24:23
1w2GredvN'; waitfor delay '0:0:15' --
0
16.01.2025 19:24:32
0
16.01.2025 19:24:35
1-1 OR 708=(SEL ECT 708 FR OM PG_SLEEP(15))--
0
16.01.2025 19:24:39
0
16.01.2025 19:24:42
1-1) OR 836=(SEL ECT 836 FR OM PG_SLEEP(15))--
0
16.01.2025 19:24:46
0
16.01.2025 19:24:53
1-1)) OR 885=(SEL ECT 885 FR OM PG_SLEEP(15))--
0
16.01.2025 19:25:00
0
16.01.2025 19:25:06
1kSTSGgli' OR 713=(SEL ECT 713 FR OM PG_SLEEP(15))--
0
16.01.2025 19:25:11
0
16.01.2025 19:25:14
1J2sxTMhb') OR 189=(SEL ECT 189 FR OM PG_SLEEP(15))--
0
16.01.2025 19:25:21
0
16.01.2025 19:25:23
1HOQATG3M')) OR 820=(SEL ECT 820 FR OM PG_SLEEP(15))--
0
16.01.2025 19:25:30
0
16.01.2025 19:25:32
1*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15)
0
16.01.2025 19:25:39
0
16.01.2025 19:25:41
1'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||'
0
16.01.2025 19:25:41
0
16.01.2025 19:25:41
????%2527%2522\'\"
0
16.01.2025 19:25:42
0
16.01.2025 19:25:47

Страницы: 1  2