Поиск по заголовкам (search.title) дополнить свойствами (напр. поиск по Артикулу)

ОБРАТИТЕ ВНИМАНИЕ: Событие “BeforeIndex“ вызывается перед индексацией поиска а не при поисковом запросе

В файл /bitrix/php_interface/init.php добавим поиск по артикулу, или любому другому свойству.

Старый метод

AddEventHandler("search", "BeforeIndex", "BeforeIndexHandler");
function BeforeIndexHandler($arFields){
   if(!CModule::IncludeModule("iblock"))
   return $arFields;
      if($arFields["MODULE_ID"] == "iblock"){
         $db_props = CIBlockElement::GetProperty( 
         $arFields["PARAM2"],         
         $arFields["ITEM_ID"],
      array("sort" => "asc"),
      Array("ID" =>[22, 32, 66, 70, 14,])); // тут перечисляем id свойств
      while($ar_props = $db_props->Fetch()){
         $arFields["TITLE"] .= " ".$ar_props["VALUE"];
         }
      }
   return $arFields;
}

И последний штрих:

  1. Включить у требуемых свойств участие в поиске
  2. Полная переиндексация сайта (Настройки продукта > Поиск > Переиндексация)

D7

$eventManager = \Bitrix\Main\EventManager::getInstance();

$eventManager->addEventHandlerCompatible('search', 'BeforeIndex',    ['\\CatalogProductIndexer','handleBeforeIndex']);

class CatalogProductIndexer
{
    /**
     * @var int Идентификатор инфоблока каталога 
     */
    const IBLOCK_ID = '30';

    /**
     * Дополняет индексируемый массив нужными значениями
     * подписан на событие BeforeIndex модуля search
     * @param array $arFields 
     * @return array
     */
    public static function handleBeforeIndex( $arFields = [] )
    {

        if ( !static::isInteresting( $arFields ) )
        {
            return $arFields;
        }

        /**
         * @var array Массив полей элемента, которые нас интересуют
         */
        $arSelect = [
            'ID',
            'IBLOCK_ID',
            'PROPERTY_TEST1',
            'PROPERTY_TEST2'
        ];

        /**
         * @var CIblockResult Массив описывающий индексируемый элемент
         */
        $resElements = \CIBlockElement::getList(
            [],
            [
                'IBLOCK_ID' => $arFields['PARAM2'],
                'ID'        => $arFields['ITEM_ID']
            ],
            false,
            [
                'nTopCount'=>1
            ],
            $arSelect
        );

        /**
         * В случае, если элемент найден мы добавляем нужные поля 
         * в соответствующие столбцы поиска
         */
        if ( $arElement = $resElements->fetch() )
        {
            $arFields['TITLE'] .= ' '.$arElement['PROPERTY_TEST1_VALUE'];
            $arFields['BODY'] .= ' '.$arElement['PROPERTY_TEST2_VALUE'];
        }

        // Отладка если потребуется
        // \Bitrix\Main\Diag\Debug::dumpToFile($arFields, 'Массив $arFields', 'search.log');

        return $arFields;
    }

    /**
     * Возвращает true, если это интересующий нас элемент
     * @param array $fields 
     * @return boolean
     */
    public static function isInteresting( $fields = [] )
    {
        return ( $fields["MODULE_ID"] == "iblock" && $fields['PARAM2'] == static::IBLOCK_ID );
    }

}

И последний штрих:

  1. Включить у требуемых свойств участие в поиске
  2. Полная переиндексация сайта (Настройки продукта > Поиск > Переиндексация)

ПЕРЕИНДЕКСАЦИЯ ОБЯЗАТЕЛЬНА !


Собрать артикулы из описаний файлов во множественном свойстве тип файл

<?php

namespace Helper;

class SearchIndexHelper
{
    /**
     * @var int Идентификатор инфоблока каталога
     */
    private const IBLOCK_ID = '7';

    private const PROPERTY_ID_PALETTE = '23'; // Палитра цветов

    // '\x1F'
    public static string $delimiter = ConfigHelper::DELIMITER;

    /**
     * Дополняет индексируемый массив нужными значениями
     * подписан на событие BeforeIndex модуля search
     *
     * @param array $arFields
     *
     * @return array
     */
    public static function handleBeforeIndex(array $arFields = []): array
    {
        if (!static::isInteresting($arFields)) {
            return $arFields;
        }

        // Добавляем Артикулы из описаний файлов PALETTE
        $catNumbersString = self::getCatNumbersFromPalette($arFields['ITEM_ID']);

        if (!empty($catNumbersString)) {
            $arFields['TITLE'] .= ' ' . self::$delimiter . ' ' . $catNumbersString;
        }

        // Отладка если потребуется
        // \Bitrix\Main\Diag\Debug::dumpToFile($arFields, 'Массив $arFields', 'search.log');

        return $arFields;
    }

    /**
     * Возвращает true, если это интересующий нас элемент
     *
     * @param array $fields
     *
     * @return boolean
     */
    public static function isInteresting(array $fields = []): bool
    {
        return ($fields["MODULE_ID"] == "iblock" && $fields['PARAM2'] == static::IBLOCK_ID);
    }

    /**
     * Получаем артикулы цветов из свойства тип файл,
     * артикулы хранятся в описании файлов.
     */
    private static function getCatNumbersFromPalette(string $elementId): string
    {
        // \Bitrix\Main\Loader::includeModule('iblock');
        $catNumbers = [];
        $resString = '';
        $arRowProp = \Bitrix\Iblock\ElementPropertyTable::getList([
            'filter' => [
                'IBLOCK_ELEMENT_ID' => $elementId,
                'IBLOCK_PROPERTY_ID' => self::PROPERTY_ID_PALETTE,
            ],
        ])->fetchAll();

        if (!empty($arRowProp)) {
            foreach ($arRowProp as $row) {
                $catNumbers[] = $row['DESCRIPTION'];
            }

            $resString = implode(',', $catNumbers);
        }

        return $resString;
    }
}
/**
 * Обрезаем строку по заданному разделителю.
 */
public static function cutStringByDelimiter(string $str, string $delimiter): string
{
    $pos = strpos($str, $delimiter);

    if ($pos === false) {
        // Разделитель не найден - возвращаем исходную строку
        return $str;
    }

    // Обрезаем до разделителя (исключая сам разделитель)
    return substr($str, 0, $pos);
}