Реализовать highload-блок в котором будут храниться актуальные свойства инфоблока.
Содержание:
- Вступление
- Создание highload-блока
- Добавление полей highload-блока
- Заполнение highload-блока свойствами инфоблока
- Создание обработчика события
- Заключение
Вступление
Решение будет состоять из 4 этапов:
- Создание highload-блока
- Добавление полей highload-блока
- Заполнение highload-блока свойствами инфоблока
- Создание обработчика события(чтобы новые свойства добавлялись в 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 блок. Тем самым можно ограничить показ свойств на детальной странице элемента.
Примеров использования можно придумать много.
> свойство «Какие свойства показывать»
Не проще сделать пользовательский тип свойства с привязкой к свойствам ИБ?
Да, ваш вариант проще, спасибо за идею!
Если в ИБ 1000+ совойств каталоге, тогда поможет только вынос всех свойств в отедельный HL и кастомной связкой с каталогом.
доброго дня!
как вытащить на детальную страницу товара свойство из highload блоков
есть справочник highload и одно из полей файл (изображение-логотип)
Посмотрите тут http://thisis-blog.ru/elementi-highload-bloka/#getall допилите под своё свойство.
Добавьте код получения поля файла в result_modifier.php(он в папке шаблона) отдельным ключом в массив arResult, и в самом шаблоне вытаскивайте из этой переменной значение.
Спасибо, ушел читать.
Какой любопытный вопрос