Реализовать 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, и в самом шаблоне вытаскивайте из этой переменной значение.
Спасибо, ушел читать.
Какой любопытный вопрос