Highload-блоки в 1С-Битрикс: создание, поля, работа через API

Просмотров: 7

Highload-блоки (они же HL-блоки) - штука удобная, когда нужно хранить справочные данные: бренды, цвета, города, валюты, курсы и прочую мелкую, но важную информацию. HL-блоки не создают таблицы для свойств, а хранят все данные в одной таблице напрямую. Это быстрее, проще и удобнее для небольших справочников.

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

Подключаем модуль highloadblock

Перед работой нужно убедиться, что модуль highloadblock подключен:

Bitrix\Main\Loader::includeModule('highloadblock');

use Bitrix\Highloadblock\HighloadBlockTable;

Создаем Highload-блок

Для создания используется метод HighloadBlockTable::add(). Ему нужно передать всего два параметра: NAME (имя класса, латиницей) и TABLE_NAME (имя таблицы в базе).

$result = HighloadBlockTable::add([
    'NAME' => 'Brands',
    'TABLE_NAME' => 'hl_brands',
]);

if ($result->isSuccess())
{
    $hlblockId = $result->getId();
    echo "HL-блок создан, ID = " . $hlblockId;
}
else
{
    print_r($result->getErrors());
}

NAME будет использоваться как имя класса для ORM (например, BrandsTable). TABLE_NAME - это физическое имя таблицы в MySQL. Его можно указать любое, но принято использовать префикс hl_.

Добавляем поля через API

Сам по себе HL-блок бесполезен - у него есть только ID. Нужно добавить пользовательские поля. Для этого используется класс CUserTypeEntity.

Строка (string)

Допустим, наш HL-блок для брендов. Добавим строковое поле "Название":

$userField = new CUserTypeEntity();

$fieldId = $userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_NAME',
    'USER_TYPE_ID' => 'string',
    'MANDATORY' => 'Y',
    'EDIT_FORM_LABEL' => ['ru' => 'Название бренда', 'en' => 'Brand name'],
    'LIST_COLUMN_LABEL' => ['ru' => 'Название', 'en' => 'Name'],
    'LIST_FILTER_LABEL' => ['ru' => 'Название', 'en' => 'Name'],
    'SETTINGS' => [
        'SIZE' => 50,
        'MIN_LENGTH' => 1,
        'MAX_LENGTH' => 255,
        'DEFAULT_VALUE' => '',
    ],
]);

if ($fieldId)
{
    echo "Поле UF_NAME добавлено, ID = " . $fieldId;
}

ENTITY_ID собирается из префикса "HLBLOCK_" и ID вашего HL-блока. Это обязательное условие, иначе Битрикс не поймет, к какому HL-блоку относится поле.

Целое число (integer)

Добавим числовое поле "Сортировка":

$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_SORT',
    'USER_TYPE_ID' => 'integer',
    'EDIT_FORM_LABEL' => ['ru' => 'Сортировка'],
    'SETTINGS' => [
        'DEFAULT_VALUE' => 500,
        'MIN_VALUE' => 0,
        'MAX_VALUE' => 10000,
    ],
]);

Дробное число (double)

Если нужно число с плавающей точкой, например, курс валюты:

$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_RATE',
    'USER_TYPE_ID' => 'double',
    'EDIT_FORM_LABEL' => ['ru' => 'Курс'],
    'SETTINGS' => [
        'PRECISION' => 4, // количество знаков после запятой
        'DEFAULT_VALUE' => 0,
    ],
]);

Да/Нет (boolean)

Поле-флажок. Например, "Активность":

$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_ACTIVE',
    'USER_TYPE_ID' => 'boolean',
    'EDIT_FORM_LABEL' => ['ru' => 'Активность'],
    'SETTINGS' => [
        'DEFAULT_VALUE' => 1,
        'DISPLAY' => 'CHECKBOX',
    ],
]);

Дата (date) и Дата со временем (datetime)

Например, дата создания или дата проведения мероприятия:

// Только дата
$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_DATE',
    'USER_TYPE_ID' => 'date',
    'EDIT_FORM_LABEL' => ['ru' => 'Дата проведения'],
]);

// Дата и время
$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_DATETIME',
    'USER_TYPE_ID' => 'datetime',
    'EDIT_FORM_LABEL' => ['ru' => 'Дата и время создания'],
]);

Список (enumeration)

Поле с выпадающим списком. Например, "Статус" со значениями "Активен", "Неактивен", "В архиве".

// Сначала добавляем само поле
$fieldId = $userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_STATUS',
    'USER_TYPE_ID' => 'enumeration',
    'EDIT_FORM_LABEL' => ['ru' => 'Статус'],
    'SETTINGS' => [
        'DISPLAY' => 'LIST', // LIST, CHECKBOX, UI_BOOLEAN
        'LIST_HEIGHT' => 1,
    ],
]);

// Теперь добавляем варианты списка
$enums = new CUserFieldEnum();
$enums->SetEnumValues($fieldId, [
    ['VALUE' => 'Активен', 'SORT' => 10, 'XML_ID' => 'active', 'DEF' => 'Y'],
    ['VALUE' => 'Неактивен', 'SORT' => 20, 'XML_ID' => 'inactive', 'DEF' => 'N'],
    ['VALUE' => 'В архиве', 'SORT' => 30, 'XML_ID' => 'archived', 'DEF' => 'N'],
]);

Файл (file)

Поле для загрузки файла. Например, логотип бренда:

$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_LOGO',
    'USER_TYPE_ID' => 'file',
    'EDIT_FORM_LABEL' => ['ru' => 'Логотип'],
    'SETTINGS' => [
        'SIZE' => 20, // размер поля ввода
        'LIST_WIDTH' => 100,
        'LIST_HEIGHT' => 100,
        'MAX_SHOW_SIZE' => 0,
        'MAX_ALLOWED_SIZE' => 5242880, // 5 MB
    ],
]);

Привязка к другому Highload-блоку (hlblock)

Допустим, у нас есть HL-блок "Бренды" (Brands) и HL-блок "Товары" (Products). В товарах нужно указать бренд.

// Сначала узнаем ID HL-блока Products
$hlProducts = HighloadBlockTable::query()
    ->addSelect('ID')
    ->where('NAME', 'Products')
    ->exec()
    ->fetch();

if ($hlProducts)
{
    $userField->Add([
        'ENTITY_ID' => 'HLBLOCK_' . $hlProducts['ID'],
        'FIELD_NAME' => 'UF_BRAND',
        'USER_TYPE_ID' => 'hlblock',
        'EDIT_FORM_LABEL' => ['ru' => 'Бренд'],
        'SETTINGS' => [
            'HLBLOCK_ID' => $hlblockId, // ID HL-блока Brands
            'DISPLAY' => 'LIST',
            'LIST_HEIGHT' => 1,
        ],
    ]);
}

Добавляем свои типы полей через UF

На самом деле типов полей для HL-блоков гораздо больше. Вот полный список USER_TYPE_ID, которые вы можете использовать:

  • string - строка
  • integer - целое число
  • double - дробное число
  • boolean - да/нет
  • date - дата
  • datetime - дата со временем
  • file - файл
  • enumeration - список
  • hlblock - привязка к элементам highload-блоков
  • iblock_element - привязка к элементам инфоблоков
  • iblock_section - привязка к разделам инфоблоков
  • employee - привязка к сотруднику
  • crm - привязка к элементам CRM
  • money - деньги
  • url - ссылка
  • address - адрес
  • video - видео

Работа с данными: добавление записи

После того как HL-блок создан и поля добавлены, нужно скомпилировать ORM-класс и работать с ним.

$hlblock = HighloadBlockTable::getById($hlblockId)->fetch();
$entity = HighloadBlockTable::compileEntity($hlblock);
$entityDataClass = $entity->getDataClass();

// Добавляем новую запись
$result = $entityDataClass::add([
    'UF_NAME' => 'Sony',
    'UF_SORT' => 100,
    'UF_ACTIVE' => 1,
    'UF_DATE' => new Bitrix\Main\Type\Date(),
    'UF_STATUS' => 'active',
]);

if ($result->isSuccess())
{
    $newId = $result->getId();
    echo "Добавлена запись с ID = " . $newId;
}

Выборка записей

Работает так же, как и с обычными ORM-сущностями. Можно фильтровать, сортировать, ограничивать выборку.

$hlblock = HighloadBlockTable::getById($hlblockId)->fetch();
$entity = HighloadBlockTable::compileEntity($hlblock);
$entityDataClass = $entity->getDataClass();

// Выбрать все активные записи, отсортированные по сортировке
$records = $entityDataClass::getList([
    'select' => ['*'],
    'filter' => ['UF_ACTIVE' => 1],
    'order' => ['UF_SORT' => 'ASC'],
    'limit' => 10,
]);

while ($record = $records->fetch())
{
    echo $record['UF_NAME'] . ' - ' . $record['UF_SORT'] . '
'; }

Обновление и удаление записей

// Обновление
$entityDataClass::update($id, [
    'UF_NAME' => 'Sony Updated',
    'UF_SORT' => 200,
]);

// Удаление
$entityDataClass::delete($id);

Реальный пример целиком

Допустим, нам нужно создать HL-блок "Валюты" с полями: код, название, курс, активность, логотип флага. Вот как это выглядит целиком:

Bitrix\Main\Loader::includeModule('highloadblock');
Bitrix\Main\Loader::includeModule('main');

use Bitrix\Highloadblock\HighloadBlockTable;

// 1. Создаем HL-блок
$result = HighloadBlockTable::add([
    'NAME' => 'Currencies',
    'TABLE_NAME' => 'hl_currencies',
]);

if (!$result->isSuccess())
{
    die('Ошибка создания HL-блока');
}

$hlblockId = $result->getId();

// 2. Добавляем поля
$userField = new CUserTypeEntity();

// Код валюты (строка, обязательное)
$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_CODE',
    'USER_TYPE_ID' => 'string',
    'MANDATORY' => 'Y',
    'EDIT_FORM_LABEL' => ['ru' => 'Код валюты'],
    'SETTINGS' => ['SIZE' => 10, 'MAX_LENGTH' => 3],
]);

// Название (строка)
$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_TITLE',
    'USER_TYPE_ID' => 'string',
    'EDIT_FORM_LABEL' => ['ru' => 'Название'],
    'SETTINGS' => ['SIZE' => 50, 'MAX_LENGTH' => 255],
]);

// Курс (дробное число)
$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_RATE',
    'USER_TYPE_ID' => 'double',
    'EDIT_FORM_LABEL' => ['ru' => 'Курс к рублю'],
    'SETTINGS' => ['PRECISION' => 4, 'DEFAULT_VALUE' => 0],
]);

// Активность (да/нет)
$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_ACTIVE',
    'USER_TYPE_ID' => 'boolean',
    'EDIT_FORM_LABEL' => ['ru' => 'Активна'],
    'SETTINGS' => ['DEFAULT_VALUE' => 1, 'DISPLAY' => 'CHECKBOX'],
]);

// Флаг (файл)
$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_FLAG',
    'USER_TYPE_ID' => 'file',
    'EDIT_FORM_LABEL' => ['ru' => 'Флаг'],
]);

// Дата обновления курса (дата со временем)
$userField->Add([
    'ENTITY_ID' => 'HLBLOCK_' . $hlblockId,
    'FIELD_NAME' => 'UF_UPDATED_AT',
    'USER_TYPE_ID' => 'datetime',
    'EDIT_FORM_LABEL' => ['ru' => 'Дата обновления курса'],
]);

// 3. Добавляем данные
$entity = HighloadBlockTable::compileEntity($hlblockId);
$entityDataClass = $entity->getDataClass();

// Добавляем доллар
$entityDataClass::add([
    'UF_CODE' => 'USD',
    'UF_TITLE' => 'Доллар США',
    'UF_RATE' => 75.5,
    'UF_ACTIVE' => 1,
]);

// Добавляем евро
$entityDataClass::add([
    'UF_CODE' => 'EUR',
    'UF_TITLE' => 'Евро',
    'UF_RATE' => 85.2,
    'UF_ACTIVE' => 1,
]);

// 4. Выбираем только активные валюты
$currencies = $entityDataClass::getList([
    'select' => ['UF_CODE', 'UF_TITLE', 'UF_RATE'],
    'filter' => ['UF_ACTIVE' => 1],
    'order' => ['UF_SORT' => 'ASC'],
]);

echo '';
echo '';
while ($currency = $currencies->fetch())
{
    echo '';
    echo '';
    echo '';
    echo '';
    echo '';
}
echo '
КодНазваниеКурс
' . $currency['UF_CODE'] . '' . $currency['UF_TITLE'] . '' . $currency['UF_RATE'] . '
';

Шпаргалка: что использовать для каких данных

Коротко по типам полей, чтобы не лазить каждый раз в документацию:

  • Справочник (список значений) - string (если простой список городов/брендов) или enumeration (если нужны варианты)
  • Цены, курсы, рейтинги - double
  • Количество, ID, сортировка - integer
  • Флаги, переключатели - boolean
  • События, даты рождения - date
  • Точное время создания - datetime
  • Картинки, документы - file
  • Связь с другим HL-блоком - hlblock
  • Связь с инфоблоком - iblock_element / iblock_section

Пишите свои примеры в комментариях - лучшие добавим в заметку. Особенно интересны кейсы со связями между разными HL-блоками и нестандартным использованием.

Стоимость разработки на 1С-Битрикс:

Индивидуальная разработка магазина

от 350 000 руб. от 5-ти недель

Разработка магазина на 1С-Битрикс с нуля. Дизайн, сборка и оптимизация производительности под конкретный проект и требования. Реализация любого функционала без ограничений готовых решений.

Запуск сайта на готовом решении

от 150 000 руб. от 7-ми дней

Вариант для тех, кто не хочет тратить много средств на индивидуальный проект, и не имеет серьезных требований к сайту. Магазин, быстро запускается на базе одного из 200-та готовых решений.

Мобильное приложение

от 400 000 руб. от 5-ти недель

Разработка кроссплатформенного мобильного приложения, которое не уступает нативным решениям как в производительности, так и пользовательском опыте. Публикуется в AppStore, GooglePlay и RuStore

Сайт компании

от 300 000 руб. от 2-х недель

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

Инфоресурс

от 300 000 руб. от 4-х недель

Информационный ресурс любой сложности. Сайт для СМИ, городской портал или многопользовательская доска объявлений. Внутренние форумы, блоги- по необходимости.

3D‑моделирование, визуализация

от 25 000 руб. от 3-х дней

По вашим фото, чертежам или описанию создадим 3D‑модели и отрендерим набор изображений для каталога товаров: общий вид, крупные планы и технические ракурсы или 360°‑обзор товара.