Перейти к содержимому

Highload-блок на практике - создание, поля, привязка к свойству

Заводим справочник в highload-блоке: создаём блок и поля, получаем класс для запросов и привязываем всё это к свойству товара.

Решение

Создаём блок и его поля:

use Bitrix\Highloadblock\HighloadBlockTable;
$result = HighloadBlockTable::add(['NAME' => 'Brands', 'TABLE_NAME' => 'vendor_brands']);
$hlId = $result->getId();
// имя сущности пишется с большой буквы и без пробелов: по нему собирается класс
// имя таблицы - строчными буквами, оно попадает прямо в базу данных

Имя сущности и имя таблицы задаются при создании и потом не меняются. По имени сущности платформа собирает класс, поэтому переименование блока на живом проекте ломает весь код, который к нему обращается.

Получаем класс сущности для запросов:

$hlblock = HighloadBlockTable::getById($hlId)->fetch();
$entity = HighloadBlockTable::compileEntity($hlblock);
$dataClass = $entity->getDataClass();
$dataClass::add(['UF_NAME' => 'Пример', 'UF_XML_ID' => 'primer']);
$rows = $dataClass::getList(['select' => ['ID', 'UF_NAME'], 'limit' => 20])->fetchAll();

Класс сущности собирается на лету по идентификатору блока. Готового имени класса в коде нет, поэтому обращение к справочнику всегда начинается с этих двух строк, и их удобно спрятать в свой метод.

Привязываем справочник к свойству товара:

$prop = new CIBlockProperty();
$prop->Update($propertyId, [
'USER_TYPE' => 'directory',
'USER_TYPE_SETTINGS' => ['TABLE_NAME' => 'vendor_brands'],
]);
// свойство хранит внешний код записи, а показывает её название

Свойство типа «справочник» хранит внешний код записи, а не её название. Отсюда требование к данным: у каждой записи должен быть заполнен внешний код, иначе свойство сохранит пустоту.

Переносим данные между стендами:

foreach ($dataClass::getList(['select' => ['*']])->fetchAll() as $row) {
// выгружаем в файл и загружаем на другом стенде по внешнему коду
printf("%s;%s\n", $row['UF_XML_ID'], $row['UF_NAME']);
}

Структуру блока переносят вместе с кодом, а записи - отдельно. Справочник, существующий только на боевом сайте, превращает стенд разработчика в место, где половина товаров без брендов.

Обёртку над получением класса стоит написать один раз и держать в своём модуле. Иначе две строки сборки сущности расползаются по проекту, а при переименовании блока их приходится искать по всему коду.

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

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

Highload-блок не заменяет инфоблок там, где нужны разделы, права на записи и привязка файлов. Он выигрывает на однотипных данных, и именно этим и стоит руководствоваться при выборе.

Типичные проблемы

Код перестал находить справочник.

Изменилось имя сущности блока. Класс собирается по этому имени, и переименование ломает все обращения.

Свойство товара сохраняет пустоту.

У записей справочника не заполнен внешний код. Свойство хранит именно его, а не название записи.

На стенде товары без значений свойства.

Записи справочника остались на боевом сайте. Структура переносится с кодом, данные - отдельно.

Фильтр не показывает новые значения.

Фасетный индекс не пересобран после заливки справочника. Он хранит готовые связки значений с разделами.

В справочнике не хватает разделов и прав.

Их у highload-блока нет по устройству. Для таких данных берут инфоблок.

Частые вопросы

Как быстро наполнить справочник?

Скриптом с обходом файла и записью через класс сущности. Через интерфейс это разумно только для десятков записей.

Можно ли хранить картинки в справочнике?

Да, полем типа файл: так делают справочники брендов с логотипами. Множественные галереи лучше держать в инфоблоке.

Как показать название вместо кода?

Через свойство типа «справочник»: компонент сам подставит название. При своей выборке название запрашивают у сущности.

Есть ли ограничение по числу записей?

Практически нет: хранилище рассчитано на большие справочники. Ограничивает скорее интерфейс правки, чем сама таблица.

Смежное

Первоисточник