Товар в нескольких разделах - привязки, адрес, дубли в списках
Кладём товар сразу в несколько разделов: разбираем, где он покажется, какой адрес получит и откуда в списках берутся повторы одной и той же позиции.
Решение
Смотрим все привязки элемента:
$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]);// адрес соберётся по этому разделу, остальные привязки на него не влияютАдрес страницы собирается по основной привязке, и он всегда один. Товар, доступный из трёх разделов, имеет один канонический адрес, а ссылки из других разделов ведут на него же - это правильное поведение, а не ошибка настройки.
Дополнительные разделы стоит заводить вполне осознанно, а не «на всякий случай». Каждая лишняя привязка удорожает выборку и добавляет работы фасетному индексу, а покупателю от товара в семи разделах пользы не прибавляется.
Обмен с учётной системой переписывает эти привязки целиком. Раздел, добавленный руками на сайте, исчезает после ближайшего сеанса, если учётная система об этом разделе не знает.
Фасетный индекс хранит готовую связку значения свойства с разделом. После перекладывания товаров по разделам фильтр показывает прежние количества до пересборки индекса.
Типичные проблемы
Товар пропал из прежних разделов.
В вызов передан только один новый раздел. Список привязок записывается сразу целиком, а вовсе не дополняется по одной записи.
В списке один товар выводится несколько раз.
У него несколько привязок к разделам одной ветки. Выборка даёт по отдельной строке результата на каждую такую привязку.
Ссылки на товар из разных разделов разные.
Адрес собирается по основной привязке и всегда остаётся один. Разные адреса означают, что их собирает шаблон сайта, а вовсе не платформа.
После обмена товар снова в одном разделе.
Учётная система передаёт свой список разделов и переписывает им прежний целиком. Ручные привязки разделов в такой схеме попросту не живут.
Фильтр не находит товар в дополнительном разделе.
Фасетный индекс не пересобран после смены привязок товара. Он хранит готовую связку значения свойства с конкретным разделом.
Частые вопросы
Сколько разделов можно назначить товару?
Сколько угодно, ограничения нет. Дороже становится выборка: каждая привязка добавляет строку в результат.
Как показать товары бренда из всех подразделов?
Выборкой по корневому разделу с включением подразделов и отбором по свойству бренда. Перебирать подразделы по одному не нужно.
Влияют ли дополнительные разделы на поиск?
На поиск по сайту - да, товар находится в каждом из них. На адрес страницы - нет, он остаётся один.
Что делать, если структура приезжает из учётной системы?
Заводить дополнительные разделы там же либо держать вторую привязку своим свойством, которое обмен не трогает.
Смежное
- Разделы изнутри: дерево, ключи, привязки элементов - где хранятся дополнительные привязки
- Каталог товаров - оглавление подтемы
- Витрина каталога: список товаров, разделы и постраничная навигация - как выводится список
- Правка структуры разделов: перенос, слияние, удаление - когда меняется само дерево
- Выборки из инфоблоков: GetList, ORM и разделы - почему строк больше, чем товаров
- Каталог и продажи - устройство магазина целиком
- Дубли страниц каталога: канонический адрес, пагинация, фильтр - один основной адрес товара