SectionTable – класс для работы с таблицей разделов инфоблоков на D7 в 1С-Битрикс

В 1С-Битрикс одним из ключевых инструментов для организации и структурирования контента является модуль «Информационные блоки» (инфоблоки). С их помощью можно хранить и группировать данные, создавать удобную структуру для товаров, статей, новостей и многого другого. В инфоблоках предусмотрено деление на разделы и элементы, что позволяет выстраивать иерархию данных.

\Bitrix\Iblock\SectionTable - работаем с таблицей разделов

Для работы с таблицей разделов инфоблоков в ядре продукта предусмотрен специальный класс \Bitrix\Iblock\SectionTable, который упрощает доступ к соответствующей таблице в базе данных и обеспечивает стандартные методы выборки, добавления, обновления и удаления записей.

С технической точки зрения, SectionTable является наследником класса:

  • \Bitrix\Main\ORM\Data\DataManager (начиная с версии 18.0.2 модуля Main),
  • \Bitrix\Main\Entity\DataManager (в более ранних версиях).

Это означает, что все методы базового класса для работы с ORM в Битриксе (например, getList(), add(), update(), delete(), а также сервисные методы getMap(), getTableName() и пр.) доступны и в SectionTable, дополняясь специфическими свойствами для инфоблоков.

Основные задачи SectionTable

  1. Отражение структуры таблицы разделов. В классе описано, с какой таблицей в БД он работает, а также какие поля в этой таблице доступны для выборки и модификации.
  2. CRUD-операции (Create, Read, Update, Delete). С помощью методов add(), getList(), update(), delete() можно управлять записями о разделах инфоблоков на уровне базы данных.
  3. Валидация и фильтрация. Благодаря функционалу ORM можно накладывать фильтры по нужным полям, задавать сортировку, лимиты и т.д.

Структура и основные поля таблицы

Обычно в таблице разделов инфоблоков (в Битриксе она называется b_iblock_section) можно встретить поля:

  • ID (integer) – уникальный идентификатор раздела.
  • IBLOCK_ID (integer) – идентификатор инфоблока, к которому относится раздел.
  • NAME (string) – название раздела.
  • CODE (string) – символьный код.
  • XML_ID (string) – внешний код раздела (используется для интеграций).
  • ACTIVE (char) – признак активности раздела (Y или N).
  • SORT (integer) – поле сортировки, определяет порядок отображения.
  • PICTURE (integer) – ID главной картинки раздела в модуле «Файлы».
  • DESCRIPTION (text) – описание раздела.
  • DETAIL_PICTURE (integer) – ID детальной картинки раздела (при наличии).
  • LEFT_MARGIN, RIGHT_MARGIN, DEPTH_LEVEL – служебные поля для работы с иерархией разделов.
  • IBLOCK_SECTION_ID (integer) – ID родительского раздела (если раздел вложен).

В классе SectionTable эти поля задаются в методе getMap(), который возвращает массив описаний полей (их тип, дополнительные настройки, связи с другими сущностями и т. п.).

public static function getMap()
{
    return [
        new Main\Entity\IntegerField('ID', [
            'primary' => true,
            'autocomplete' => true,
        ]),
        new Main\Entity\IntegerField('IBLOCK_ID'),
        new Main\Entity\StringField('NAME'),
        new Main\Entity\StringField('CODE'),
        new Main\Entity\StringField('XML_ID'),
        new Main\Entity\BooleanField('ACTIVE', [
            'values' => ['N', 'Y']
        ]),
        new Main\Entity\IntegerField('SORT'),
        new Main\Entity\IntegerField('PICTURE'),
        new Main\Entity\TextField('DESCRIPTION'),
        new Main\Entity\IntegerField('DETAIL_PICTURE'),
        new Main\Entity\IntegerField('IBLOCK_SECTION_ID'),
        // ... и т.д.
    ];
}

Все эти поля далее доступны в запросах и при модификациях.

Методы класса SectionTable

getTableName()

Возвращает название таблицы в базе данных, с которой работает данный класс, – обычно это b_iblock_section.

$tableName = \Bitrix\Iblock\SectionTable::getTableName();
echo $tableName; // Выведет "b_iblock_section"

getMap()

Возвращает описание полей таблицы (массив объектов \Bitrix\Main\Entity\Field). Чаще всего используется внутренней логикой ORM, вручную вызывать этот метод приходится редко (например, при отладке, чтобы посмотреть структуру).

getList(array $parameters)

Основной метод для получения списка разделов инфоблоков из таблицы. В параметрах можно передавать filter, select, order, limit, offset и пр.

use Bitrix\Iblock\SectionTable;

$result = SectionTable::getList([
    'select' => ['ID', 'NAME', 'ACTIVE', 'SORT'],
    'filter' => [
        '=IBLOCK_ID' => 5,
        '=ACTIVE' => 'Y'
    ],
    'order' => ['SORT' => 'ASC'],
]);

while ($row = $result->fetch())
{
    echo "ID: {$row['ID']} - Название: {$row['NAME']} - Сортировка: {$row['SORT']}
"; }

Здесь:

  • 'select' определяет, какие поля нужно получить;
  • 'filter' накладывает условия (равенство ID инфоблока 5 и активность равна Y);
  • 'order' указывает, как сортировать.

Результат выполнения будет HTML-список разделов с их ID, названием и сортировкой.

add(array $data)

Позволяет добавить новую запись (раздел) в таблицу. На вход принимает массив, где ключи соответствуют названиям полей в getMap().

use Bitrix\Iblock\SectionTable;

$addResult = SectionTable::add([
    'IBLOCK_ID' => 5,
    'NAME' => 'Новый раздел',
    'ACTIVE' => 'Y',
    'SORT' => 500,
]);

if ($addResult->isSuccess())
{
    $newId = $addResult->getId();
    echo "Новый раздел успешно добавлен. ID = ".$newId;
}
else
{
    $errors = $addResult->getErrorMessages();
    echo "Ошибка при добавлении раздела: ".implode(', ', $errors);
}

Результат – либо ID нового раздела, либо сообщение об ошибке (например, если не заполнены обязательные поля или нарушены какие-то правила).

update($primary, array $data)

Обновляет существующую запись (раздел). В первом параметре передаётся первичный ключ (обычно ID записи), во втором – массив с новыми значениями полей.

use Bitrix\Iblock\SectionTable;

$updateResult = SectionTable::update(10, [
    'NAME' => 'Обновлённый раздел',
    'CODE' => 'updated-section'
]);

if ($updateResult->isSuccess())
{
    echo "Раздел успешно обновлён.";
}
else
{
    $errors = $updateResult->getErrorMessages();
    echo "Ошибка при обновлении: ".implode(', ', $errors);
}

delete($primary)

Удаляет запись (раздел) из таблицы. Если у раздела имеются вложенные подразделы или элементы, стоит учитывать системные настройки инфоблока (вложенные разделы могут также удалиться рекурсивно или вызвать ошибки целостности данных).

use Bitrix\Iblock\SectionTable;

$deleteResult = SectionTable::delete(10);
if ($deleteResult->isSuccess())
{
    echo "Раздел успешно удалён.";
}
else
{
    $errors = $deleteResult->getErrorMessages();
    echo "Ошибка при удалении: ".implode(', ', $errors);
}

Особенности наследования от DataManager

Поскольку SectionTable наследуется от DataManager, ему доступны все базовые возможности ORM:

  • Поддержка фильтров (filter).
  • Гибкие способы сортировки и группировки (order, group).
  • Постраничная навигация (limit, offset).
  • Объединение с другими таблицами через связи (Join, ReferenceField).
  • События (OnBeforeAdd, OnAfterAdd, OnBeforeUpdate и т.д.).

В более старых версиях Битрикс (до модуля Main 18.0.2) SectionTable наследовался от \Bitrix\Main\Entity\DataManager, что фактически предоставляло сходный функционал. Разница между \Bitrix\Main\ORM\Data\DataManager и \Bitrix\Main\Entity\DataManager главным образом заключается в доработках и улучшениях ORM-слоя, введённых в новых версиях. Однако ключевые методы add(), update(), delete(), getList() и прочие остались аналогичными.

Практический пример: вывод дерева разделов

Нередко при работе с инфоблоками требуется вывести дерево разделов на сайте (например, меню категорий). Можно написать функцию, которая получает все разделы определённого инфоблока и строит из них иерархическую структуру.

use Bitrix\Iblock\SectionTable;

/**
 * Получаем дерево разделов инфоблока
 * @param int $iblockId
 * @return array
 */
function getSectionsTree($iblockId)
{
    $sections = [];

    // Выбираем все разделы
    $result = SectionTable::getList([
        'select' => [
            'ID',
            'IBLOCK_SECTION_ID',
            'NAME',
            'LEFT_MARGIN',
            'RIGHT_MARGIN',
            'DEPTH_LEVEL'
        ],
        'filter' => [
            '=IBLOCK_ID' => $iblockId,
            '=ACTIVE' => 'Y'
        ],
        'order' => [
            'LEFT_MARGIN' => 'ASC'
        ]
    ]);

    while ($row = $result->fetch())
    {
        $sections[$row['ID']] = $row;
    }

    // Теперь строим дерево
    $tree = [];
    foreach ($sections as $id => &$section)
    {
        if (!empty($section['IBLOCK_SECTION_ID']) && isset($sections[$section['IBLOCK_SECTION_ID']]))
        {
            $parentId = $section['IBLOCK_SECTION_ID'];
            $sections[$parentId]['CHILDREN'][$id] = &$section;
        }
        else
        {
            // Это корневой раздел
            $tree[$id] = &$section;
        }
    }

    return $tree;
}

// Пример использования:
$tree = getSectionsTree(5);

// Рекурсивно выводим дерево
function printSectionsTree($sections, $level = 0)
{
    foreach ($sections as $section)
    {
        echo str_repeat('-', $level*3) // Для отступа
             .$section['NAME']." (ID={$section['ID']})
"; if (!empty($section['CHILDREN'])) { printSectionsTree($section['CHILDREN'], $level + 1); } } } printSectionsTree($tree);

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

Когда и зачем использовать SectionTable

  • Прямой доступ к разделам инфоблока. Если нужно получить данные не через высокоуровневые API (например, CIBlockSection), а посредством ORM-запросов.
  • Сложные выборки. Когда требуется составить нестандартные условия фильтрации, сортировки, использовать джойны с другими таблицами.
  • Высокая производительность. ORM может быть быстрее при правильном построении запросов, чем работа с методами высокого уровня, которые могут тянуть «лишнее».
  • Удобство и гибкость. ORM даёт единообразие во всём проекте. Вместо процедурного API (которое характерно для классов инфоблоков из старого ядра) мы используем объектный подход.

При этом следует иметь в виду:

  • Если у вас простой сценарий, не требующий сложных выборок, вы можете обойтись методами CIBlockSection для единообразия с остальной частью проекта.
  • При работе с ORM нужно следить за правильностью указания кодировок, типов полей, а также за актуальностью версий Битрикса (старые версии могут работать несколько иначе).

Вывод

Класс \Bitrix\Iblock\SectionTable — удобный инструмент для работы с разделами инфоблоков на уровне базы данных с использованием ORM. Он является наследником базового класса \Bitrix\Main\ORM\Data\DataManager (в более ранних версиях – \Bitrix\Main\Entity\DataManager), что даёт доступ ко всем типовым методам для управления данными (CRUD) и гибким возможностям фильтрации и сортировки.

Основные преимущества использования SectionTable:

  1. Единый интерфейс для всех операций над разделами (получение списка, добавление, обновление, удаление).
  2. Гибкие возможности фильтрации, сортировки и группировки, позволяющие строить достаточно сложные запросы к БД.
  3. Гибкая структура полей, описанная в getMap(), упрощающая понимание и расширение функционала.
  4. Совместимость с другими ORM-классами (например, ElementTable для работы с элементами).

Если вы используете современные версии 1С-Битрикс, SectionTable станет незаменимым инструментом при разработке сайтов и решений, где необходимо взаимодействовать с разделами инфоблоков через ORM.

Теги:  D7, справочник

Интернет-магазин от 120 000 руб., срок от 4 недель

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

Корпоративный сайт от 60 000 руб., срок от 3 недель

Готовый информационный ресурс, включающий лицензию на 1С-Битрикс «Стандарт», технологию «Композитный сайт».

Лендинг от 25 000 руб., срок от 2 недель

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