Highload блок с актуальными свойствами инфоблока

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

Содержание:

  1. Вступление
  2. Создание highload-блока
  3. Добавление полей highload-блока
  4. Заполнение highload-блока свойствами инфоблока
  5. Создание обработчика события
  6. Заключение

Вступление

Решение будет состоять из 4 этапов:

  1. Создание highload-блока
  2. Добавление полей highload-блока
  3. Заполнение highload-блока свойствами инфоблока
  4. Создание обработчика события(чтобы новые свойства добавлялись в highload block)

1 и 2 этапы можно выполнить в админке. Тогда сразу переходите к 3-ему этапу.

Создание highload-блока программно

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

<?php
use Bitrix\Highloadblock\HighloadBlockTable as HLBT;
CModule::IncludeModule('highloadblock');

$highloadBlockData = array ( 'NAME' => 'Props', 'TABLE_NAME' => 'my_table_props' );
$result = HLBT::add($highloadBlockData);
$highLoadBlockId = $result->getId();
//если произошла ошибка выведем её
if(!$highLoadBlockId){
    var_dump($result->getErrorMessages());
}
?>

Переменная highLoadBlockId — это ID созданного highload-блока, его вы можете использовать в дальнейшем.

Добавление полей highload-блока

Добавление полей (свойств) highload-блока заключается в создании пользовательских свойств. Чтобы они стали полями именно нашего инфоблока, нужно при их создании поле ‘ENTITY_ID’ заполнить по следующему правилу:
‘ENTITY_ID’ = > ‘HLBLOCK_3’
3 — ID highload-блока

Создаём пользовательские поля

Подробнее о создании пользовательских свойств программно можно узнать в документации.
Первое пользовательское свойство NAME, второе ID:

<?php
$highLoadBlockId = 3;
$userTypeEntity    = new CUserTypeEntity();

$userTypeData    = array(
    'ENTITY_ID'         => 'HLBLOCK_'.$highLoadBlockId,
    'FIELD_NAME'        => 'UF_NAME',
    'USER_TYPE_ID'      => 'string',
'XML_ID'            => 'XML_ID_NAME',
'SORT'              => 500,
'MULTIPLE'          => 'N',
    'MANDATORY'         => 'Y',
    'SHOW_FILTER'       => 'N',
    'SHOW_IN_LIST'      => '',
    'EDIT_IN_LIST'      => '',
    'IS_SEARCHABLE'     => 'N',
    'SETTINGS'          => array(
        'DEFAULT_VALUE' => '',
        'SIZE'          => '20',
        'ROWS'          => '1',
        'MIN_LENGTH'    => '0',
        'MAX_LENGTH'    => '0',
        'REGEXP'        => '',
),
    'EDIT_FORM_LABEL'   => array(
        'ru'    => 'Название свойства',
        'en'    => 'Property name',
    ),
    'LIST_COLUMN_LABEL' => array(
        'ru'    => 'Название свойства',
        'en'    => 'Property name',
    ),
    'LIST_FILTER_LABEL' => array(
        'ru'    => 'Название свойства',
'en'    => 'Property name',
),
    'ERROR_MESSAGE'     => array(
        'ru'    => 'Ошибка при заполнении пользовательского свойства <Названия свойства>',
        'en'    => 'An error in completing the user field <Property name>',
),
    'HELP_MESSAGE'      => array(
        'ru'    => '',
'en'    => '',
    ),
);

$userTypeData2    = array(
    'ENTITY_ID'         => 'HLBLOCK_'.$highLoadBlockId,
    'FIELD_NAME'        => 'UF_XML_ID',
    'USER_TYPE_ID'      => 'integer',
'XML_ID'            => 'XML_ID_ID',
'SORT'              => 500,
'MULTIPLE'          => 'N',
    'MANDATORY'         => 'Y',
    'SHOW_FILTER'       => 'N',
    'SHOW_IN_LIST'      => '',
    'EDIT_IN_LIST'      => '',
    'IS_SEARCHABLE'     => 'N',
    'SETTINGS'          => array(
        'DEFAULT_VALUE' => '',
),
    'EDIT_FORM_LABEL'   => array(
        'ru'    => 'ID свойства',
        'en'    => 'Property ID',
    ),
    'LIST_COLUMN_LABEL' => array(
        'ru'    => 'ID свойства',
        'en'    => 'Property ID',
    ),
    'LIST_FILTER_LABEL' => array(
        'ru'    => 'ID свойства',
'en'    => 'Property ID',
),
    'ERROR_MESSAGE'     => array(
        'ru'    => 'Ошибка при заполнении пользовательского свойства <ID свойства>',
        'en'    => 'An error in completing the user field <Property ID>',
),
    'HELP_MESSAGE'      => array(
        'ru'    => '',
'en'    => '',
    ),
);

$userTypeId = $userTypeEntity->Add($userTypeData);
$userTypeId2 = $userTypeEntity->Add($userTypeData2);
?>

Заполнение highload-блока свойствами инфоблока

Для начала напишем вспомогательный класс CatalogHelper по адресу /bitrix/php_interface/init.php. В этом классе определим функцию GetEntityDataClass (про неё я рассказывал в предыдущей статье) и будущий обработчик события OnAfterIBlockPropertyAddHandler, но о нем чуть позже.

<?php
use Bitrix\Highloadblock\HighloadBlockTable as HLBT;
CModule::IncludeModule('highloadblock');

// регистрируем обработчик события, который выполняется после добавления нового свойства инфоблока
AddEventHandler('iblock', 'OnAfterIBlockPropertyAdd', ['CatalogHelper', 'OnAfterIBlockPropertyAddHandler']);

class CatalogHelper{
    // id инфоблока, свойства которого будет добавлять
    const IBLOCK_ID = 1;
    // id созданного highload-блока
    const HL_BLOCK_ID = 3;

    public static function GetEntityDataClass($HlBlockId) {
		if (empty($HlBlockId) || $HlBlockId < 1)
		{
			return false;
		}
		$hlblock = HLBT::getById($HlBlockId)->fetch();
		$entity = HLBT::compileEntity($hlblock);
		$entity_data_class = $entity->getDataClass();
		return $entity_data_class;
    }

    public static function OnAfterIBlockPropertyAddHandler(&$arFields) {
        if ($arFields['ID'] > 0 && $arFields['IBLOCK_ID'] == self::IBLOCK_ID)
        {
            $entity_data_class = self::GetEntityDataClass(self::HL_BLOCK_ID);
            $entity_data_class::add([
                'UF_NAME' => $arFields['NAME'],
                'UF_XML_ID' => $arFields['ID']
            ]);
        }
    }
}
?>

Код довольно простой, если вам знакома работа с классами.

Теперь непосредственно сам код заполнения хайлоад блока свойствами инфоблока с использованием объявленной в init.php функции GetEntityDataClass

<?php

        $entity_data_class = CatalogHelper::GetEntityDataClass(CatalogHelper::HL_BLOCK_ID);
        $arFilterProp = [];
        $rsData = $entity_data_class::getList([
                    "select" => ['*'],
                    "order" => ["UF_NAME" => "ASC"]
        ]);
        while ($arRes = $rsData->Fetch())
        {
            $arFilterProp[] = $arRes['UF_XML_ID'];
        }
        $properties = CIBlockProperty::GetList([], ["ACTIVE" => "Y", "IBLOCK_ID" => CatalogHelper::IBLOCK_ID]);
        while ($res_arr = $properties->Fetch())
        {
            $arIDs[] = $res_arr['ID'];
            if (!in_array($res_arr['ID'], $arFilterProp))
            {
                $item = ['UF_NAME' => $res_arr['NAME'], 'UF_XML_ID' => $res_arr['ID']];
                $resultAdd = $entity_data_class::add($item);
            }
        }
?>

$arFilterProp — массив будет хранить свойства, которые уже добавлены в highloadblock, чтобы не добавлять свойство повторно.
Т.е. данный код сначала узнает, какие свойства уже добавлены в хайлоад блок. Далее получает свойства нужно инфоблока, и если его нет в массиве $arFilterProp, то добавляет в highload блок.

Создание обработчика события

Для того, чтобы при при создании новых свойств инфоблока они добавлялись в highload block, зарегистрировал(функция AddEventHandler()) обработчик события OnAfterIBlockPropertyAdd.
Код обработчика вы можете увидеть в классе CatalogHelper.
Единственное, что поясню: в функции OnAfterIBlockPropertyAddHandler идет проверка $arFields[‘IBLOCK_ID’] == self::IBLOCK_ID, чтобы добавление свойства срабатывало только для инфоблока, ID которого равен константе IBLOCK_ID.

Заключение

Теперь в хайлоад блоке имеются все актуальные свойства нужного инфоблока.
Пример использования: например добавить в инофблок свойство «Какие свойства показывать» типа «Справочник». Выбрать созданный highload блок. Тем самым можно ограничить показ свойств на детальной странице элемента.
Примеров использования можно придумать много.

5 комментариев

  • nook:

    > свойство «Какие свойства показывать»
    Не проще сделать пользовательский тип свойства с привязкой к свойствам ИБ?

  • exzo:

    доброго дня!
    как вытащить на детальную страницу товара свойство из highload блоков
    есть справочник highload и одно из полей файл (изображение-логотип)

    • Жора:

      Посмотрите тут http://thisis-blog.ru/elementi-highload-bloka/#getall допилите под своё свойство.
      Добавьте код получения поля файла в result_modifier.php(он в папке шаблона) отдельным ключом в массив arResult, и в самом шаблоне вытаскивайте из этой переменной значение.

Оставить комментарий