+7 495 008 8452
  • Загрузка
Выберите ваш цвет

Поиск по каталогу, включая торговые предложения

Если у вас возникли какие либо вопросы которые вы не смогли решить по нашим публикациям самостоятельно,
то ждем ваше обращение в нашей службе тех поддержки.


Варианты решения: поиск по каталогу, включая торговые предложения.

Для поиска по каталогу товаров на сайте используем компонент «Поиск по каталогу» (bitrix:catalog.search). Компонент выводит результаты поиска по элементам каталога с указанным набором свойств, цен и т.д., является стандартным. В качестве параметров компоненту указываются тип инфо-блоков и ID инфобока, по которому будет производится поиск.
http://dev.1c-bitrix.ru/user_help/con...search.php

Но выяснилась одна очень важная деталь, при поиске по свойствам/описанию торговых предложений, компонент их не выводит. Рассмотрев детально код (основной код компонента сосредоточен в шаблоне), выяснили, что компонент выполняет поиск по заданному инфоблоку поисковой фразы с помощью bitrix:search.page, а затем выводит элементы инфоблока с помощью bitrix:catalog.section.
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?
$arElements = $APPLICATION->IncludeComponent(
  "bitrix:search.page",
  ".default",
  Array(
    ...
    "arrFILTER" => array("iblock_".$arParams["IBLOCK_TYPE"]),
    "arrFILTER_iblock_".$arParams["IBLOCK_TYPE"] => array($arParams["IBLOCK_ID"]),
    ...
  ),
  $component
);
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" => $arParams["IBLOCK_ID"],
      "FILTER_NAME" => "searchFilter",
      ...
    ),
    $arResult["THEME_COMPONENT"]
  );
} else {
  echo GetMessage("CT_BCSE_NOT_FOUND");
}
?>
Немного подправив код, можно указать компоненту bitrix:search.page, что искать нужно не только в инфоблоке основного каталога товаров, но и в инфоблоке торговых предложений. Т. к. для вывода товарных позиций в bitrix:catalog.section необходимо указывать ID элемента торгового каталога, то для торговых предложений необходимо выполнить дополнительно подзапрос к инфоблоку торговых предложений.

Для этого сначала в файле result_modifier.php с помощью метода CCatalogSKU::GetInfoByProductIBlock() определяем наличие инфоблока торговых предложений и его параметры. Определяем тип этого инфоблока и по идентификатору свойства-связки символьный код этого свойства.
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();?>
<?php
$arSKU = CCatalogSKU::GetInfoByProductIBlock($arParams["IBLOCK_ID"]);
if (is_array($arSKU)) {
  $arResult["ORLND"]["SKU_IBLOCK_ID"] = $arSKU["IBLOCK_ID"];
  
  $rsIBlock = CIBlock::GetByID($arSKU["IBLOCK_ID"]);
  if ($arIBlock = $rsIBlock->GetNext())
    $arResult["ORLND"]["SKU_IBLOCK_TYPE"] = $arIBlock["IBLOCK_TYPE_ID"];
  
  $rsProperty = CIBlockProperty::GetByID($arSKU["SKU_PROPERTY_ID"], $arSKU["IBLOCK_ID"]);
  if ($arProperty = $rsProperty->GetNext())
    $arResult["ORLND"]["SKU_PROPERTY_SID"] = $arProperty["CODE"];
}
Получается, что массив arResult пополняется новыми полями:
array(2) {
...
["ORLND"]=>
  array(3) {
    ["SKU_IBLOCK_ID"]=>
    int(...)
    ["SKU_IBLOCK_TYPE"]=>
    string(8) "..."
    ["SKU_PROPERTY_SID"]=>
    string(9) "..."
  }
}
Теперь модифицируем template.php. В случае, если типы инфоблоков торгового каталога и торговых предложений совпадают, формируется массив из идентификаторов этих инфоблоков.
<?php
if (isset($arResult["ORLND"]["SKU_IBLOCK_ID"]) && isset($arResult["ORLND"]["SKU_IBLOCK_TYPE"]) && ($arResult["ORLND"]["SKU_IBLOCK_TYPE"] == $arParams["IBLOCK_TYPE"]))
  $arIBlockList = array($arParams["IBLOCK_ID"], $arResult["ORLND"]["SKU_IBLOCK_ID"]);
else
  $arIBlockList = array($arParams["IBLOCK_ID"]);

$arElements = array();
$arOffers = array();
?>
<div class="catalog-search">
  <?php
  $arElements = $APPLICATION->IncludeComponent("bitrix:search.page", ".default", array(
      ...
      "arrFILTER" => array("iblock_" . $arParams["IBLOCK_TYPE"]),
      "arrFILTER_iblock_" . $arParams["IBLOCK_TYPE"] => $arIBlockList,
      ...
    ),
    $component
  );
  ?>
Если типы инфоблоков не совпадают, выполняем дополнительно поиск по инфоблоку торговых предложений.
<?php if (isset($arResult["ORLND"]["SKU_IBLOCK_TYPE"]) && ($arResult["ORLND"]["SKU_IBLOCK_TYPE"] != $arParams["IBLOCK_TYPE"])):?>
  <div style="display: none;">
    <?php
    $arOffers = $APPLICATION->IncludeComponent("bitrix:search.page", ".default", array(
        ...
        "arrFILTER" => array("iblock_" . $arResult["ORLND"]["SKU_IBLOCK_TYPE"]),
        "arrFILTER_iblock_" . $arResult["ORLND"]["SKU_IBLOCK_TYPE"] => array($arResult["ORLND"]["SKU_IBLOCK_ID"]),
        ...
      ),
      $component
    );
    ?>
  </div>
<?php endif;?>
Далее остаётся сформировать фильтр с подзапросом для использования в bitrix:catalog.section.
<?php
if ((is_array($arElements) && !empty($arElements)) || (isset($arOffers) && is_array($arOffers) && !empty($arOffers))) {
  global $searchFilter;
  
  $searchFilter = array("=ID" => $arElements);
  
  if (isset($arResult["ORLND"]["SKU_IBLOCK_ID"]) && isset($arResult["ORLND"]["SKU_PROPERTY_SID"])) {
    if (isset($arResult["ORLND"]["SKU_IBLOCK_TYPE"]) && ($arResult["ORLND"]["SKU_IBLOCK_TYPE"] == $arParams["IBLOCK_TYPE"])) {
      $searchFilter = array(
        array(
          "LOGIC" => "OR",
          array("=ID" => $arElements),
          array("=ID" => CIBlockElement::SubQuery("PROPERTY_" . $arResult["ORLND"]["SKU_PROPERTY_SID"], array("IBLOCK_ID" => $arResult["ORLND"]["SKU_IBLOCK_ID"], "=ID" => $arElements)))
        )
      );
    } elseif (isset($arResult["ORLND"]["SKU_IBLOCK_TYPE"]) && ($arResult["ORLND"]["SKU_IBLOCK_TYPE"] != $arParams["IBLOCK_TYPE"]) && isset($arOffers)) {
      $searchFilter = array(
        array(
          "LOGIC" => "OR",
          array("=ID" => $arElements),
          array("=ID" => CIBlockElement::SubQuery("PROPERTY_" . $arResult["ORLND"]["SKU_PROPERTY_SID"], array("IBLOCK_ID" => $arResult["ORLND"]["SKU_IBLOCK_ID"], "=ID" => $arOffers)))
        )
      );
    }
  }
  
  $APPLICATION->IncludeComponent("bitrix:catalog.section", ".default", array(
      "IBLOCK_TYPE" => $arParams["IBLOCK_TYPE"],
      "IBLOCK_ID" => $arParams["IBLOCK_ID"],
      ...
      "FILTER_NAME" => "searchFilter",
      ...
    ),
    $arResult["THEME_COMPONENT"]
  );
}
Таким образом, мы с помощью подзапроса CIBlockElement::SubQuery() получаем элементы основного каталога товаров, торговые предложения которых были найдены.

 

 

Источник: https://dev.1c-bitrix.ru/community/webdev/user/172310/blog/12201/

Назад в раздел

Подписаться на новые материалы раздела:
Загрузка...