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

Товар в нескольких разделах - привязки, адрес, дубли в списках

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

Решение

Смотрим все привязки элемента:

$groups = CIBlockElement::GetElementGroups($elementId, true);
while ($g = $groups->Fetch()) {
printf("раздел=%d %s\n", $g['ID'], $g['NAME']);
}
$el = CIBlockElement::GetByID($elementId)->Fetch();
printf("основная привязка=%s\n", $el['IBLOCK_SECTION_ID']);

У элемента два разных понятия: список разделов и основная привязка. Первый решает, где товар показывается, вторая - по какому разделу собирается его адрес, и путать их - источник половины вопросов про пропавшие страницы.

Добавляем товар во второй раздел:

$current = [];
$res = CIBlockElement::GetElementGroups($elementId, true);
while ($g = $res->Fetch()) { $current[] = $g['ID']; }
CIBlockElement::SetElementSection($elementId, array_merge($current, [$newSectionId]));
// вызов заменяет весь список: старые привязки нужно передать заново

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

Убираем дубли в выборке:

$res = CIBlockElement::GetList(['SORT' => 'ASC'],
['IBLOCK_ID' => 5, 'SECTION_ID' => $sectionId, 'INCLUDE_SUBSECTIONS' => 'Y'],
false, false, ['ID', 'NAME']);
// без группировки товар с тремя привязками придёт тремя строками
$seen = [];
while ($row = $res->Fetch()) { $seen[$row['ID']] = $row; }

Несколько привязок дают несколько строк выборки на один товар. Штатные компоненты разводят это сами, а своя выборка - нет, и повторы в списке появляются ровно там, где товар положили во второй раздел.

Решаем, какой адрес у товара главный:

$el = new CIBlockElement();
$el->Update($elementId, ['IBLOCK_SECTION_ID' => $mainSectionId]);
// адрес соберётся по этому разделу, остальные привязки на него не влияют

Адрес страницы собирается по основной привязке, и он всегда один. Товар, доступный из трёх разделов, имеет один канонический адрес, а ссылки из других разделов ведут на него же - это правильное поведение, а не ошибка настройки.

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

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

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

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

Товар пропал из прежних разделов.

В вызов передан только один новый раздел. Список привязок записывается сразу целиком, а вовсе не дополняется по одной записи.

В списке один товар выводится несколько раз.

У него несколько привязок к разделам одной ветки. Выборка даёт по отдельной строке результата на каждую такую привязку.

Ссылки на товар из разных разделов разные.

Адрес собирается по основной привязке и всегда остаётся один. Разные адреса означают, что их собирает шаблон сайта, а вовсе не платформа.

После обмена товар снова в одном разделе.

Учётная система передаёт свой список разделов и переписывает им прежний целиком. Ручные привязки разделов в такой схеме попросту не живут.

Фильтр не находит товар в дополнительном разделе.

Фасетный индекс не пересобран после смены привязок товара. Он хранит готовую связку значения свойства с конкретным разделом.

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

Сколько разделов можно назначить товару?

Сколько угодно, ограничения нет. Дороже становится выборка: каждая привязка добавляет строку в результат.

Как показать товары бренда из всех подразделов?

Выборкой по корневому разделу с включением подразделов и отбором по свойству бренда. Перебирать подразделы по одному не нужно.

Влияют ли дополнительные разделы на поиск?

На поиск по сайту - да, товар находится в каждом из них. На адрес страницы - нет, он остаётся один.

Что делать, если структура приезжает из учётной системы?

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

Смежное

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