Правка структуры разделов - перенос, слияние, удаление
Перекраиваем дерево разделов на живом каталоге: переносим ветки, разводим товары и удаляем лишнее, не теряя элементы и не роняя адреса из поисковой выдачи.
Решение
Переносим раздел в другую ветку:
$section = new CIBlockSection();$section->Update($sectionId, [ 'IBLOCK_SECTION_ID' => $newParentId, // новый родитель, 0 - корень 'SORT' => 100,]);// адреса раздела и его товаров меняются вместе с веткойПереезд ветки меняет адреса и самого раздела, и всех его подразделов с товарами. Это главное следствие: страницы, собранные по коду раздела, после переноса отвечают по новым адресам, а старые перестают существовать.
Перекидываем элементы между разделами:
CIBlockElement::SetElementSection($elementId, [$newSectionId], false);// третий аргумент отвечает за проверку прав, false ускоряет массовую правку$el = new CIBlockElement();$el->Update($elementId, ['IBLOCK_SECTION_ID' => $newSectionId]); // основная привязкаПривязка к разделам и основная привязка элемента - разные вещи. Первая задаёт, где товар показывается, вторая - по какому разделу собирается его адрес, и править обычно нужно обе.
Удаляем раздел осознанно:
$res = CIBlockElement::GetList([], ['IBLOCK_ID' => 5, 'SECTION_ID' => $sectionId, 'INCLUDE_SUBSECTIONS' => 'Y'], []);printf("в разделе элементов: %d\n", $res);// удаление раздела удаляет и эти элементы: сначала переносим, потом удаляемCIBlockSection::Delete($sectionId);Удаление раздела уносит все его элементы вместе с ним. Порядок безопасной чистки один: сначала пересчитать и перенести товары, потом убедиться, что раздел пуст, и только затем удалять.
Проверяем адреса после переезда:
$res = CIBlockSection::GetList([], ['IBLOCK_ID' => 5, 'ID' => $sectionId], false, ['ID', 'NAME', 'SECTION_PAGE_URL', 'DEPTH_LEVEL']);$row = $res->GetNext();printf("%s -> %s (уровень %d)\n", $row['NAME'], $row['SECTION_PAGE_URL'], $row['DEPTH_LEVEL']);Новый адрес собирается из шаблона адреса и кода раздела. Старые адреса при этом никуда не переезжают сами: переходы со старых на новые ставят руками, иначе выдача приводит посетителей на страницу с ошибкой.
Обмен с учётной системой вернёт правленую структуру обратно. Если разделы приезжают из неё, перекладывать дерево нужно на её стороне, а не на сайте, иначе первый же ночной сеанс отменит всю работу.
Правку структуры стоит делать в тихие часы и с готовой копией базы. Дерево разделов держит на себе адреса, фильтр и обмен, и ошибка в нём задевает сразу весь каталог, а не одну страницу.
После правки структуры обязательно пересобирают кэш и фасетный индекс. Витрина иначе показывает прежние ветки, а фильтр - прежние количества товаров по разделам.
Типичные проблемы
Вместе с разделом пропали все товары.
Удаление раздела удаляет вместе с ним и его элементы. Товары переносят в другой раздел до удаления, а не после него.
Ссылки из поиска ведут на страницу с ошибкой.
После переезда ветки адреса сменились, а переходы со старых не поставлены. Их прописывают вместе с самим переносом раздела.
Товар виден в разделе, но его адрес прежний.
Правилась привязка к разделам, а основная привязка осталась прежней. Адрес элемента собирается именно по основной привязке.
Наутро дерево вернулось к прежнему виду.
Разделы приезжают из учётной системы и переписываются при обмене. Структуру в этом случае правят на её стороне.
Фильтр показывает товары в старых разделах.
Фасетный индекс не пересобран после правки структуры каталога. Он хранит готовую связку значения свойства с разделом.
Частые вопросы
Как объединить два раздела?
Перенести элементы в один, проверить, что второй пуст, и удалить его. Прямого слияния разделов нет.
Можно ли держать товар сразу в нескольких разделах?
Да, привязок может быть несколько. Адрес при этом собирается по основной, а остальные влияют на показ в списках.
Что будет с сортировкой после переноса?
Значение поля сортировки остаётся прежним, а соседи меняются. Порядок в новой ветке обычно приходится задавать заново.
Как перенести сотню разделов сразу?
Скриптом по отбору с обходом порциями. Через интерфейс это делается по одному разделу.
Смежное
- Разделы изнутри: дерево, ключи, привязки элементов - что пересчитывается при переезде ветки
- Разделы инфоблока - оглавление подтемы
- Раздел не выводится: разбор причин - что ломается после правки структуры
- Вывод разделов: дерево, подразделы, адреса - как выводится сама структура
- Редиректы внутри сайта: 301 на раздел, https и старые адреса - переходы со старых адресов
- Структура каталога при выгрузке из 1С - когда дерево приезжает из учётной системы
- Инфоблоки - устройство хранилища целиком
- Товар в нескольких разделах: привязки, адрес, дубли в списках - привязки товара к нескольким разделам
- Запись в инфоблок через ORM - почему раздел удаляют только старым ядром