Yandex Metrika
sanches.free 20 просмотров

Настройки свойств элементов по разделам: SectionPropertyTable и умный фильтр

Задача

В каталоге свойство может участвовать в умном фильтре не глобально, а только в выбранных разделах: отдельная таблица хранит режим отображения и подсказку. В ядре это закрывает класс \Bitrix\Iblock\SectionPropertyTable — составной ключ IBLOCK_ID + SECTION_ID + PROPERTY_ID. Перенос между контурами проще строить через XML_ID у свойств и разделов: числовые ключи на новом сайте другие, а внешние идентификаторы при аккуратном импорте совпадают.

Подключите модуль iblock до любых вызовов.

Выгрузка строк с включённым умным фильтром

Ниже — условный идентификатор источника $exportIblockPk. Условие '>SECTION_ID' => 0 отсекает «корень» без привязки к конкретной ветке. В выборку добавлены человекочитаемые имена и XML_ID связанных записей через runtime-связи ORM — их удобно сериализовать в JSON или сразу записать массив в PHP-файл миграции.

use Bitrix\Main\Loader;
use Bitrix\Iblock\SectionPropertyTable;

if (!Loader::includeModule('iblock')) {
    return;
}

$exportIblockPk = 42;

$rowset = SectionPropertyTable::getList([
    'filter' => [
        '=IBLOCK_ID' => $exportIblockPk,
        '=SMART_FILTER' => 'Y',
        '>SECTION_ID' => 0,
    ],
    'select' => [
        '*',
        'PROPERTY_XML_ID' => 'PROPERTY.XML_ID',
        'SECTION_XML_ID' => 'SECTION.XML_ID',
        'PROPERTY_NAME' => 'PROPERTY.NAME',
        'SECTION_NAME' => 'SECTION.NAME',
    ],
]);

$dump = [];
while ($tuple = $rowset->fetch()) {
    $dump[] = $tuple;
}

// сохраните $dump во временный файл или var_export для переноса

Восстановление на целевом инфоблоке

Следующий фрагмент читает заранее подготовленный массив $importRows — теми же элементами, что собрали на предыдущем шаге (поля вроде DISPLAY_EXPANDED, DISPLAY_TYPE, FILTER_HINT понадобятся без изменений). Для каждой строки находим свойство и раздел целевого инфоблока $importIblockPk по XML_ID; при существующей связке выполняют update, иначе add. Счётчики пропусков помогают быстро заметить обрыв импорта свойств или дерева разделов.

use Bitrix\Main\Loader;
use Bitrix\Iblock\PropertyTable;
use Bitrix\Iblock\SectionTable;
use Bitrix\Iblock\SectionPropertyTable;

if (!Loader::includeModule('iblock')) {
    return;
}

$importIblockPk = 17;

/** @var array $importRows элементы массива — строки из выгрузки */
$importRows = [];

$missProps = 0;
$missSections = 0;

foreach ($importRows as $payload) {
    $property = PropertyTable::getList([
        'filter' => [
            '=IBLOCK_ID' => $importIblockPk,
            '=XML_ID' => $payload['PROPERTY_XML_ID'],
        ],
        'select' => ['ID', 'NAME'],
        'limit' => 1,
    ])->fetch();

    if (!$property) {
        $missProps++;
    }

    $branch = SectionTable::getList([
        'filter' => [
            '=IBLOCK_ID' => $importIblockPk,
            '=XML_ID' => $payload['SECTION_XML_ID'],
        ],
        'select' => ['ID', 'NAME'],
        'limit' => 1,
    ])->fetch();

    if (!$branch) {
        $missSections++;
    }

    if (!$property || !$branch) {
        continue;
    }

    $hit = SectionPropertyTable::getList([
        'filter' => [
            '=IBLOCK_ID' => $importIblockPk,
            '=SECTION_ID' => $branch['ID'],
            '=PROPERTY_ID' => $property['ID'],
        ],
        'select' => ['*'],
        'limit' => 1,
    ])->fetch();

    $facetPatch = [
        'SMART_FILTER' => 'Y',
        'DISPLAY_EXPANDED' => $payload['DISPLAY_EXPANDED'],
        'DISPLAY_TYPE' => $payload['DISPLAY_TYPE'],
        'FILTER_HINT' => $payload['FILTER_HINT'],
    ];

    if ($hit) {
        SectionPropertyTable::update(
            [
                'IBLOCK_ID' => $hit['IBLOCK_ID'],
                'SECTION_ID' => $hit['SECTION_ID'],
                'PROPERTY_ID' => $hit['PROPERTY_ID'],
            ],
            $facetPatch
        );
    } else {
        SectionPropertyTable::add(array_merge([
            'IBLOCK_ID' => $importIblockPk,
            'SECTION_ID' => $branch['ID'],
            'PROPERTY_ID' => $property['ID'],
        ], $facetPatch));
    }
}

Что проверить вручную

  • У свойств и разделов должны быть заполнены стабильные XML_ID — иначе сопоставление на новом контуре превращается в гадание по названиям.
  • После массовых правок фасета пересмотрите индекс умного фильтра той же секцией каталога, где он строился изначально — иначе витрина может не совпасть с админкой.
  • Глобальные флаги «в списке» и «на детальной» у свойств задаются другим слоем (PropertyFeature); наш сценарий не заменяет их, а дополняет разрез по разделам.

Итог

SectionPropertyTable — точка входа для чтения и записи конфигурации умного фильтра на стыке «раздел + свойство». Выгрузка с PROPERTY.XML_ID и SECTION.XML_ID, затем восстановление через add/update, закрывают типовую миграцию каталога между сайтами. Про глобальные признаки показа свойств см. также статью о PropertyFeature для списка и детальной.

Не хотите копаться сами?

Починю за 1-3 дня. Без предоплаты — оплата по результату.

15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии