#инфоблоки

Советы с тегом "инфоблоки"

1 совет

Избавляемся от ID инфоблока при работе с разделами

Избавляемся от ID инфоблока при работе с разделами

Проблема

В типичном проекте на 1С-Битрикс код работы с разделами напрямую взаимодействует с ID инфоблока. При каждом запросе к SectionTable или CIBlockSection приходится явно указывать фильтр по инфоблоку. Если нужно изменить ID инфоблока или перенести код на другой проект — начинается ад с поиском и заменой всех вхождений.

Решение

Класс Bitrix\Iblock\Model\Section предоставляет метод compileEntityByIblock(), который создаёт специализированный класс для работы с разделами конкретного инфоблока. Все запросы через этот класс автоматически фильтруются по нужному IBLOCK_ID без явного указания.

Было: магические числа везде

use Bitrix\Iblock\SectionTable;

// Приходится каждый раз указывать IBLOCK_ID
$sections = SectionTable::getList([
    'select' => ['ID', 'NAME', 'CODE'],
    'filter' => [
        'IBLOCK_ID' => 10, // Что это за инфоблок?
        'ACTIVE' => 'Y'
    ]
])->fetchAll();

// И снова тот же ID в другом месте
$section = SectionTable::getByPrimary(25, [
    'filter' => ['IBLOCK_ID' => 10] // Дублирование!
])->fetch();

Стало: чистый код без дублирования

use Bitrix\Iblock\Model\Section;

// Один раз создаём класс для инфоблока по API_CODE
$catalogSectionEntity = Section::compileEntityByIblock('catalog');

// IBLOCK_ID больше не нужен - всё фильтруется автоматически
$sections = $catalogSectionEntity::getList([
    'select' => ['ID', 'NAME', 'CODE'],
    'filter' => ['ACTIVE' => 'Y']
])->fetchAll();

Бонус: автоматическая связь с родителем

Помимо избавления от IBLOCK_ID, получаем ещё и связь PARENT_SECTION для работы с иерархией:

$catalogSectionEntity = Section::compileEntityByIblock('catalog');

// Получаем раздел с данными родителя одним запросом
$section = $catalogSectionEntity::getList([
    'filter' => ['=CODE' => 'laptops'],
    'select' => ['ID', 'NAME', 'PARENT_SECTION.NAME']
])->fetchObject();

echo $section->getName(); // "Ноутбуки"
echo $section->getParentSection()?->getName(); // "Компьютеры"

Практический пример: хлебные крошки без IBLOCK_ID

use Bitrix\Iblock\Model\Section;

// Инициализируем класс для каталога
$catalogSectionEntity = Section::compileEntityByIblock('catalog');

$section = $catalogSectionEntity::query()
    ->setSelect([
        'ID', 
        'NAME',
        'CODE',
        'PARENT_SECTION.NAME',
        'PARENT_SECTION.PARENT_SECTION.NAME'
    ])
    ->where('CODE', 'gaming-laptops')
    ->exec()
    ->fetchObject();

// Строим хлебные крошки рекурсивно
$breadcrumbs = [];
$current = $section;

while ($current) {
    $breadcrumbs[] = [
        'name' => $current->getName(),
        'code' => $current->getCode()
    ];
    $current = $current->getParentSection();
}

$breadcrumbs = array_reverse($breadcrumbs);

Что получаем

  1. Нет магических чисел: IBLOCK_ID указан один раз при создании класса
  2. Переносимость: изменили ID инфоблока — код работает без изменений
  3. Читаемость: не нужно помнить, что 10 — это каталог, а 15 — новости
  4. Меньше ошибок: невозможно забыть добавить фильтр по IBLOCK_ID
  5. Связь с родителем: автоматическая PARENT_SECTION для иерархии