Перейти к содержимому

Фильтр по свойствам предложений - настройка, индекс, вывод

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

Что нужно знать заранее

Свойства предложений живут в отдельном инфоблоке. Фильтр по ним - это отбор товаров, у которых есть хотя бы одно подходящее предложение, а не отбор самих предложений.

Фасетный индекс строится по каждому инфоблоку каталога отдельно и независимо. Каталог с предложениями требует индекса для обоих, иначе числа рядом со значениями будут неверными или не появятся вовсе.

Свойство участвует в фильтре только после отметки в настройках самого свойства. Отметка стоит в свойствах инфоблока предложений, а не в параметрах компонента витрины.

Шаги

  1. Отметить нужные свойства инфоблока предложений как участвующие в умном фильтре.
  2. Построить фасетный индекс отдельно для инфоблока товаров и для инфоблока предложений.
  3. Передать компоненту фильтра оба инфоблока и одинаковое имя фильтра со списком.
  4. Проверить выдачу фильтра: числа рядом со значениями и состав отобранных товаров.
  5. Настроить пересборку индекса после обмена и после массовых правок каталога скриптом.

Решение

Отмечаем свойство предложений для фильтра:

$prop = \CIBlockProperty::GetList([], ['IBLOCK_ID' => $offersIblockId,
'CODE' => 'SIZE'])->Fetch();
(new \CIBlockProperty())->Update($prop['ID'], ['SMART_FILTER' => 'Y',
'DISPLAY_TYPE' => 'F']); // F - флажки, A - ползунок для чисел
// без этой отметки свойство в фильтре не появится ни при каких параметрах

Тип отображения выбирают по смыслу свойства. Флажки подходят для размеров и цветов, ползунок - для чисел вроде объёма памяти, а список - для длинных справочников.

Строим фасетный индекс для обоих инфоблоков:

foreach ([$catalogIblockId, $offersIblockId] as $id) {
$storage = new \Bitrix\Iblock\PropertyIndex\Manager();
\Bitrix\Iblock\PropertyIndex\Manager::markAsInvalid($id);
// сама сборка запускается из настроек инфоблока или агентом платформы
}

Индекс инфоблока предложений забывают чаще всего. Симптом узнаваемый: фильтр по размеру показывает нули рядом со всеми значениями, хотя товары с такими размерами в каталоге есть.

Подключаем фильтр с обоими инфоблоками:

$APPLICATION->IncludeComponent('bitrix:catalog.smart.filter', '', [
'IBLOCK_ID' => $catalogIblockId,
'FILTER_NAME' => 'arrFilter', // то же имя, что и у списка товаров
'PRICE_CODE' => ['BASE'],
'SAVE_IN_SESSION' => 'N',
]);

Имя фильтра связывает компонент отбора и компонент списка. Разные имена - самая частая причина того, что фильтр отправляется, а список товаров не меняется.

Проверяем, что отбор действительно работает:

$rs = \CIBlockElement::GetList([], ['IBLOCK_ID' => $catalogIblockId,
'ACTIVE' => 'Y', 'PROPERTY_CML2_LINK.PROPERTY_SIZE_VALUE' => 'XL'],
false, ['nTopCount' => 5], ['ID', 'NAME']);
while ($row = $rs->Fetch()) { printf("%d %s\n", $row['ID'], $row['NAME']); }
// выборка идёт от предложения к товару через свойство привязки

Пересобираем индекс после обмена:

/local/php_interface/init.php
\Bitrix\Main\EventManager::getInstance()->addEventHandler('catalog',
'OnSuccessCatalogImport1C', static fn() =>
\Bitrix\Iblock\PropertyIndex\Manager::markAsInvalid($offersIblockId));
// обмен меняет предложения пачками, и индекс после него устаревает

Типичные проблемы

Рядом со значениями фильтра стоят нули.

Фасетный индекс построен только для инфоблока товаров, а свойства живут у предложений. Индекс строят для обоих инфоблоков каталога и пересобирают его после каждого обмена.

Свойство предложения не появляется в фильтре.

У свойства не стоит отметка об участии в умном фильтре в настройках инфоблока. Отметку ставят именно у свойства инфоблока предложений, а не у товара.

Фильтр отправляется, а список товаров не меняется.

У компонента фильтра и у списка товаров разные имена фильтра в параметрах. Имя фильтра обязано совпадать в обоих вызовах компонентов до последнего символа.

После обмена фильтр показывает старые значения.

Обмен меняет предложения пачками, а фасетный индекс после него не пересобирается. Пересборку индекса вешают на событие завершения обмена с учётной системой.

В выдачу попадают товары без подходящих предложений.

Отбор идёт по свойству товара с тем же названием, а не по свойству предложения. Проверяют, у какого именно инфоблока каталога заведено это нужное свойство.

Частые вопросы

Почему фильтр по размеру показывает нули?

Не построен фасетный индекс инфоблока предложений. Индекс строится по каждому инфоблоку отдельно, и каталог с предложениями требует обоих.

Фильтр отбирает товары или предложения?

Товары, у которых есть хотя бы одно подходящее предложение. Поэтому в карточке отобранного товара будут видны и остальные его варианты.

Можно ли показывать в списке только подходящий вариант?

Штатный компонент так не умеет: он отдаёт товар целиком. Вывод конкретного варианта делают своим шаблоном, разбирая параметры запроса.

Как часто пересобирать индекс?

После каждой массовой правки каталога и после обмена с учётной системой. Точечные правки в интерфейсе индекс догоняет сам.

Работает ли фильтр по цене предложений?

Да, цена берётся из предложений, и диапазон считается по ним. Товар без цен у предложений в такой фильтр не попадает вовсе.

Смежное

Первоисточник