Телеграм: @bazarow_ru Почта: mihail@bazarow.ru

Цвета торговых предложений из Highload инфоблоков в списке товаров

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

Подвернулся на доработку очень старый сайт, работал еще на 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;?>
 
Михаил Базаров 16.08.2017
Нужно перенести это свойство в тип Справочник и прицепить к нему HL блок с цветами. Соответсвенно загрузить примеры цветов в этот HL
Nikita Androsov 16.08.2017
Цитата
Михаил Базаров пишет:
Нужно перенести это свойство в тип Справочник и прицепить к нему HL блок с цветами. Соответсвенно загрузить примеры цветов в этот HL
Ну так и есть, я создал у инфоблока свойство справочник, к свойству прицепил HL блок, в HL блок накидал цветов, т.е. в карточке товара цвета отображаются нормально (Не текстом).
Интересует отображение цветов именно при добавление товара.
Допустим цвет "coffee [25]", нужно что бы отображался сам цвет или название+цвет, или цвет вместо [ай ди] элемента.
Михаил Базаров 16.08.2017
Цитата
Nikita Androsov написал:
Ну так и есть, я создал у инфоблока свойство справочник, к свойству прицепил HL блок, в HL блок накидал цветов, т.е. в карточке товара цвета отображаются нормально (Не текстом).
Интересует отображение цветов именно при добавление товара.
Допустим цвет "coffee [25]", нужно что бы отображался сам цвет или название+цвет, или цвет вместо [ай ди] элемента.
Да, не правиьно понял вопрос- штатно ни как. Не штатно, не смогу в рамках форума объяснить, да и не к чему это- только нагрузка на ровном месте создается
chybakabra 17.08.2017
Всем привет! Михаил, а можно вместо названия цвета вывести не названием а цветом, точнее я знаю, что можно, просто, как правильнее?
tos995 03.11.2017
Сделал все как вы описали - не выводится ничего)) все проверил, менял айди hl все копипастил - все равно не выводится))
Андрей Колчанов 26.03.2018
Михаил, в Варианте 2 ошибочка в коде:

<?}?>
<?endforeach:?>
<?endforeach;?>

у вас стоит двоеточие.
Михаил Базаров 26.03.2018
Цитата
Андрей Колчанов пишет:
Михаил, в Варианте 2 ошибочка в коде:

<?}?>
<?endforeach : ?>
<?endforeach;?>

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

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

Или этот третий блок нужно оборачивать в цикл?