Информационные блоки

Информационные блоки в режиме мультиязычности

Модуль modulemarket.translator дополняет стандартную модель Информационных блоков в 1С-Битрикс отдельными таблицами переводов. Для одной и той же сущности (тип инфоблока, раздел или элемент) в базе хранится несколько строк — по одной на сочетание языка и сайта. Идентификатор сущности в переводе совпадает с ID записи в штатной ORM-таблице ядра.

Принцип работы — перевод не подменяет строку в b_iblock, b_iblock_section или b_iblock_element, а хранится рядом: при запросе на нужном языке вы читаете из таблицы перевода и при необходимости объединяете данные с основной записью.

Три уровня данных

ORM-класс модуля Таблица переводов Сущность Связь с ядром
Modulemarket\Translator\Iblock\IblockTable fan_translator_iblock Тип инфоблока (имя, описание, активность) Карта полей на основе Bitrix\Iblock\IblockTable
Modulemarket\Translator\Iblock\SectionTable fan_translator_iblock_section Раздел инфоблока Связь SECTIONBitrix\Iblock\SectionTable
Modulemarket\Translator\Iblock\ElementTable fan_translator_iblock_element Элемент инфоблока Связь ELEMENTBitrix\Iblock\ElementTable

Составной ключ и контекст

Во всех трёх таблицах первичный ключ составной: ID (ссылка на сущность ядра) + LANGUAGE_ID (два символа) + SITE_ID (два символа). Поля LANGUAGE_ID и SITE_ID в описании полей имеют значения по умолчанию из констант окружения; в коде выборок и записей надёжнее передавать язык и сайт явно в filter или в массиве полей при add/update.

Примечание — подробные примеры по каждому классу см. в дочерних страницах раздела: IblockTable, SectionTable, ElementTable.

Общий порядок работы в коде

  1. Подключить модули: Loader::includeModule('iblock') и Loader::includeModule('modulemarket.translator').
  2. Знать ID инфоблока, раздела или элемента в основной таблице ядра — он же ID в строке перевода.
  3. Читать перевод: getList() с фильтром '=ID', '=LANGUAGE_ID', '=SITE_ID' и нужным select.
  4. Создавать или менять перевод: add() / update() по первичному ключу; проверять Result::isSuccess().
  5. Для ElementTable можно использовать статический метод translated($id, $languageId), чтобы проверить наличие перевода без разбора выборки.

События и служебная логика

У классов SectionTable и ElementTable обработчики onBeforeAdd и onBeforeUpdate подставляют TIMESTAMP_X, если это поле не передано в сохраняемых данных. У класса IblockTable метод UseForcedUpdates($iblockId) позволяет определить режим принудительных обновлений по константе вида FORCE_TRANSLATE_IB_ID_* (подробности — на странице IblockTable).

Важно! Набор полей в каждой таблице перевода ограничен методом getTranslatableFields() соответствующего класса — не каждая колонка основной ORM-карты попадает в перевод. Перед массовой синхронизацией сверяйте список полей в документации к классу.

Типовой фрагмент (чтение перевода элемента)

Code Copy code Code copied!
1
2
3
4
5
6
7
8
9
10
11
12
13
use Bitrix\Main\Loader;
use Modulemarket\Translator\Iblock\ElementTable;

Loader::includeModule('iblock');
Loader::includeModule('modulemarket.translator');

$row = ElementTable::getRow([
    'filter' => [
        '=ID' => $elementId,
        '=LANGUAGE_ID' => $lang,
        '=SITE_ID' => $site,
    ],
]);

Ссылки по теме

Документация 1С-Битрикс: Bitrix\Iblock\IblockTable

Документация 1С-Битрикс: Bitrix\Iblock\SectionTable

Документация 1С-Битрикс: Bitrix\Iblock\ElementTable

Кратко: зачем три разных класса

Тип инфоблока, раздел и элемент — разные сущности с разными наборами полей и разными таблицами в ядре. Модуль держит для каждого уровня свою таблицу перевода и свой DataManager, чтобы ORM-мапы и валидаторы соответствовали исходным таблицам Информационных блоков.