Подвернулся на доработку очень старый сайт, работал еще на 11-ой версии Битрикс. Выполнили обновление до 16-ой версии и попутно возникла доработка. Нужно было вывести цвета торговых предложений в виде цветных картинок. Коли уж скоро, Битрикс обновлен и получен функционал Highload инфоблоков, решил ими и воспользоваться
Переводить шаблоны каталога на современные, переверстывать под текущий дизайн сайта - слишком трудоемкая и долгая процедура. Да и не имеет практического смыла. Решил добавить вывод цветов прямо в старом шаблоне
Создание инфоблока и добавление в товары
Для начала создаем Highload инфоблок - COLOR и накидываем в него элементы. По сути, просто квадратики с картинками.


Далее, создаем в инфоблоке каталога свойство "Цвет", типа "Справочник" и в настройках выбираем созданный ранее Highload инфоблок. PS: Кстати, создать его можно прямо отсюда, просто выбираем "Создать новый" вместо выбора имеющегося.

Далее, в товарах выбираем это новое свойство, просто указываем какие цвета есть у торговых предложений. В настройках компонента каталога, выбираем новое свойство как параметр вывода/отбора предложений

Вывод картинок и фильтрация элементов Higload инфоблока
Теперь, само интересное: открываем на редактирование шаблон любого компонента каталога (например catalog.top). Общий смысл работы, заключается в выводе модуля highload инфоблоков в шаблоне компонета. Само собой, нам вывалит все элементы справочника, наша задача отфильтровать только нужные- актуальные для конкретного товара, элементы.
Для этого, сначала выведем foreach со всеми торговыми предложениями данного товара и занесем данные в переменную. То есть, мы просто собираем пречисление всех названий цветов в одну строку
<?
foreach($arElement["OFFERS"] as $arOffer):
foreach($arOffer["DISPLAY_PROPERTIES"] as $pid=>$arProperty):
$color .= '\''.$arProperty["DISPLAY_VALUE"].'\',';
break;endforeach;
endforeach;?>
Если сейчас, в любом месте шаблона вывести <?echo $color?> - получим простую строку с перечислением цветов предложений- типа "Синий,Красный,красный,черный,черный,синий" - то, что я повторяю цвета в строке, это не ошибка. Да- нам выдаст все предложения, даже их повторения (например: у вас есть ботинки синие-44 рзмер, синие-45 ый И так далее - вывалит все вариации). Но это не страшно, решим дальше.
Теперь нам нужно эту строку превратить в массив array- используем eval, для этих целей. Не все его любят, но в данном случае вполне уместен.
<?
eval('$fofilter=array('.$color.');');
extract($fofilter);
?>
Все, теперь в переменной $fofilter у нас массив вида array(Синий,Красный,красный,черный,черный,синий)
Теперь самое сложное: подключаем модуль "highloadblock" и сразу выводим в нем только картинки элементов. Причем картинкой, воспользовавшись API CFile::GetPath. Комментарии по коду:
<?
if (!CModule::IncludeModule('highloadblock')) //ПОДКЛЮЧАЕМ МОДУЛЬ
continue;
$ID = 3; //СЮДА ID ВАШЕГО HL ИНФОБЛОКА
$hldata = Bitrix\Highloadblock\HighloadBlockTable::getById($ID)->fetch();
$hlentity = Bitrix\Highloadblock\HighloadBlockTable::compileEntity($hldata);
$hlDataClass = $hldata['NAME'].'Table';
//СОЗДАЕМ МАССИВ ФИЛЬТРА, В НЕМ УКАЗЫВАЕМ ЛОГИКУ ОТБОРА И (обязательно, иначе будет ИЛИ и отфильтрует только один цвет)
$arFilter = Array(
Array(
"LOGIC"=>"AND",
Array(
"UF_NAME"=> $fofilter //НАШ МАССИВ С ЦВЕТАМИ
)
)
);
$result = $hlDataClass::getList(array(
'select' => array('UF_FILE','UF_NAME'),//НАМ НУЖНЫ ТОЛЬКО НАЗВАНИЕ И КАРТИНКА
'order' => array('UF_NAME' =>'ASC'),
'filter' => $arFilter //ПРИМЕНЯМ СОЗДАННЫЙ ВЫШЕ ФИЛЬТР));
while($res = $result->fetch()){
$img_path = CFile::GetPath($res["UF_FILE"]); //ПОЛУЧАЕМ ПУСТЬ К КАРТИНКЕ
echo '<img src="'.$img_path.'"/>'; //ВЫВОДИМ КАРТИНКУ
}
?>
Вот и все, нам выведет все цвета, присущие только торговым предложениям данного товара. при этом по одному разу. Немного избыточно, так как в фильтр могут попадать одни и те же параметры (Синий, синий, синий)- но интерпритируется только один запрос и не получится нескольких синих квадратов.
Однако, проверил нагрузку на карточке товара. Данное решение срабатывает быстро, при условии что у конкретного товара около 15-ти расцветок, а в HL блоках около 200-от записей. Запросов к базе данных мало, отрабатываются моментально. На-то они и Highload блоки.
Добавлено позже: Вариант 2 "Просто в лоб"
Если вам достаточно просто циклически перебрать и вывести вообще все цвета (не обращая внимания на повторения цветов), можете решить задачу "в лоб". Просто перебираем все цвета в foreach и для каждого выводим HL запись с помощью API Битрикс
<?
foreach($arElement["OFFERS"] as $arOffer):?>
<?foreach($arOffer["DISPLAY_PROPERTIES"] as $pid=>$arProperty):?>
<? if($pid =="TSVET"){?>
<?
$color = $arProperty["DISPLAY_VALUE"];
if (!CModule::IncludeModule('highloadblock'))
continue;
$ID = 3;
$hldata = Bitrix\Highloadblock\HighloadBlockTable::getById($ID)->fetch();
$hlentity = Bitrix\Highloadblock\HighloadBlockTable::compileEntity($hldata);
$hlDataClass = $hldata['NAME'].'Table';
$arFilter = Array(
Array(
"LOGIC"=>"AND",Array(
"UF_NAME"=> $color //НАШ МАССИВ С ЦВЕТАМИ
)
)
);
$result = $hlDataClass::getList(array(
'select' => array('UF_FILE','UF_NAME'),
'order' => array('UF_NAME' =>'ASC'),
'filter' => $arFilter
));
while($res = $result->fetch()){
$img_path = CFile::GetPath($res["UF_FILE"]); //ПОЛУЧАЕМ ПУСТЬ К КАРТИНКЕ
echo '<img src="'.$img_path.'" width="20"/>'; //ВЫВОДИМ КАРТИНКУ
}?>
<?}?>
<?endforeach;?>
<?endforeach;?>

Цитата |
---|
Михаил Базаров пишет: Нужно перенести это свойство в тип Справочник и прицепить к нему HL блок с цветами. Соответсвенно загрузить примеры цветов в этот HL |
Интересует отображение цветов именно при добавление товара.
Допустим цвет "coffee [25]", нужно что бы отображался сам цвет или название+цвет, или цвет вместо [ай ди] элемента.

Цитата |
---|
Nikita Androsov написал: Ну так и есть, я создал у инфоблока свойство справочник, к свойству прицепил HL блок, в HL блок накидал цветов, т.е. в карточке товара цвета отображаются нормально (Не текстом). Интересует отображение цветов именно при добавление товара. Допустим цвет "coffee [25]", нужно что бы отображался сам цвет или название+цвет, или цвет вместо [ай ди] элемента. |


<?}?>
<?endforeach:?>
<?endforeach;?>
у вас стоит двоеточие.

Цитата |
---|
Андрей Колчанов пишет: Михаил, в Варианте 2 ошибочка в коде: <?}?> <?endforeach : ?> <?endforeach;?> у вас стоит двоеточие. |

Если делать торговые предложения по всем свойствам: размер, с ПМ или без ПМ и цвету(материалу) то получается 360 торговых предложения только на одну модель.
Рационально было бы сделать торговые предложения только по свойству: размер, с ПМ и без ПМ, а свойство цвет вывести как просто справочник.
Вообще это нормально 360 торговых предложений только лишь на один товар, мне кажется это создает избыточную нагрузку на БД или я ошибаюсь?

Цитата |
---|
Антон Сурнин написал: Как лучше поступить? Есть торговое предложения Кровать оно имеет характеристики: размер, с Подъемным Механизмом или без ПМ , и цвет(материал). По свойствам: размер, с ПМ или без ПМ цены разные, но цена не изменчива от цвета(материала). Если делать торговые предложения по всем свойствам: размер, с ПМ или без ПМ и цвету(материалу) то получается 360 торговых предложения только на одну модель. Рационально было бы сделать торговые предложения только по свойству: размер, с ПМ и без ПМ, а свойство цвет вывести как просто справочник. Вообще это нормально 360 торговых предложений только лишь на один товар, мне кажется это создает избыточную нагрузку на БД или я ошибаюсь? |
У Вас (в примере) получается всего два предложения с ПМ или без ПМ - все остальные параметры товара это свойства конкретного товара (предложения).
На стандартном шаблоне сделать не получится.
Если доработаете/адаптируете его:
Покупатель выбирает ПМ или БПМ - дальше довыбирает цвет и прочие параметры, которые не относятся к предложению, а именно к товару.

В первом варианте реализации у меня выбивает ошибку на continue;
Пишет что оно обязательно должно находится в цикле. У вас же оно не в цикле.
Или этот третий блок нужно оборачивать в цикл?