Битрикс: Поиск по свойствам торговых предложений
В данном примере рассмотрим простой способ осуществления поиска по свойствам торговых предложений.
Данный пример написан на коленке за 10 минут и предоставляется как есть =).
Очень часто необходимо осуществить поиск по свойствам, которые принадлежат не товару, а торговому предложению. По умолчанию поиск по каталогу битрикса - осуществляется по товару, или по свойствам товара, для которых указано значение "Свойство учавствует в поиске". Поиск по свойствам, которые принадлежат торговым предложениям не возможен.
Рассмотри одно из возможных решений для данной задачи, при которой работает пагинация и все хорошо с кешированием
Суть метода заключается в поиске нужных свойств в инфоблоке торговых предложений и выдаче этих результатов в результаты поиска.
Для начала создадим файл result_modifier.php в шаблоне компонента catalog.search, который расположен в шаблоне используемого каталога
пример адреса: /bitrix/templates/!название_вашего_шаблона!/components/bitrix/catalog/!название_шаблона_каталога!/bitrix/catalog.search/.default/
В данном файле нам нужно проверить есть ли инфоблок с товарными предложениями для инфоблока с товарами
Если такой инфоблок есть, с помощью GetList получить элементы, которые удовлетворяют поисковому запросу. После этого нужно получить привязанные товары к данным торговым предложениям и сделать array_unique()
Пример файла result_modifier.php
<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();?>
<?
//проверяем есть ли инфоблок с торговыми предложениями для инфоблока с товарами
$arSKU = CCatalogSKU::GetInfoByProductIBlock($arParams["IBLOCK_ID"]);
if (is_array($arSKU)){
//Выбираем свойства, которые удовлетворяют результатам поиска
$arSelect = Array("ID", "IBLOCK_ID", "NAME", "DATE_ACTIVE_FROM");
$arFilter = Array(
"IBLOCK_ID"=>$arSKU["IBLOCK_ID"],
"ACTIVE"=>"Y",
//Используем логику "ИЛИ" для поиска по нескольким свойствам
array(
//Вместо "tpPromo" - символьный код нужного свойства
// В данном случае используется поиск с маской по двум свойствам
"LOGIC" => "OR",
array("PROPERTY_tpPromo" => $_GET["q"]."%"),
array("=PROPERTY_tpSale" => substr($_GET["q"], 0, -1)),
)
);
//Получаем результаты поиска
$res = CIBlockElement::GetList(Array(), $arFilter, false, Array("nPageSize"=>5000), $arSelect);
while($ob = $res->GetNextElement()) {
$arProps = $ob->GetProperties();
//Записываем ID товара к которому привязано торговое предложение
$tmp[] = $arProps["CML2_LINK"]["VALUE"];
}
$tmp = array_unique($tmp);
//Возвращаем в arResult полученный массив
$arResult["ADDED_ITEMS_IDS"] = $tmp;
}
?>
После этого у нас в arResult появился массив ADDED_ITEMS_IDS - id товаров для товарных предложений которых были найдены соответсвия.
Далее нужно дописать пару строчек в template.php этого же компонента
В шаблоне компонента мы видим что массив $arElements - передается в $searchFilter, наша задача добавить туда id найденных товаров
$arElements = $APPLICATION->IncludeComponent(
"bitrix:search.page",
".default",
Array(
"RESTART" => $arParams["RESTART"],
...
"PAGER_TEMPLATE" => "N",
),
$component,
array('HIDE_ICONS' => 'Y')
);
if (!empty($arElements) && is_array($arElements))
{
global $searchFilter;
$searchFilter = array(
"=ID" => $arElements,
);
$APPLICATION->IncludeComponent(
"bitrix:catalog.section",
".default",
array(
"IBLOCK_TYPE" => $arParams["IBLOCK_TYPE"],
"IBLOCK_ID" => $arPa
Добавим такие строки перед условием:
...
$component,
array('HIDE_ICONS' => 'Y')
);
foreach ($arResult["ADDED_ITEMS_IDS"] as $tp) {
$arElements[] = $tp;
}
if (!empty($arElements) && is_array($arElements))
{
global $searchFilter
...
таким образом добавим в массив найденных товаров, те товары у которых в торговых предложениях найдены соответствия поисковому запросу.
Чтобы избежать возможного дублирования после добавленного цикла можно добавить
$arElements = array_unique($arElements)
на этом все, теперь поиск работает по заданным свойствам торговых предложений.
В дальнейшем возможно модифицировать компонент поиска по каталогу добавив параметры для поиска по торговым предложениям в массив arParams и составлять логику фильтра в цикле или по признаку "Участвует в поиске"