Доброго времени суток. Просмотрел все темы, выдаваемые гуглом по этому вопросу. Однозначного варианта решения нет.
Используется 1С-Битрикс: Управление сайтом 17.5.4. Редакция продукта: Бизнес
Задача состоит в том, чтобы при добавлении GET параметра sale в нужной каталоге показывались только товары, имеющие скидки
Т.е. в каталоге Аксессуары порядка 2000 позиций, но скидка действует только на 50 товаров. Как их выбрать корректно?
В данный момент реализовал следующим образом:
1. Делаю выборку ID и цены для всех товаров нужного каталога:
2. Затем в цикле получаю для каждого товара цену с учетом скидки и сравниваю с базовой ценой, и если цены отличаются (действует скидка), то добавляю ID товара в массив.
3. Получив массив ID продуктов со скидкой делаю выборку товаров из каталога:
В каталогах, в которых товаров 200-300 всё работает великолепно, но вот в таких как Аксессуары (больше 2000) начались проблемы. Цикл обрабатывается очень долго. Примерно 1 минуту "залипа".
Решил эту проблему кэшированием с временем сутки. Итоговый код выглядит следующим образом:
Но сам факт того, что раз в сутки возникает нагрузка - напрягает. Да и сам по себе код не очень легкий. Слишком много обращений к БД.
Возник резонный вопрос, реально ли упростить этот код?
1. Возможно ли в CIBlockElement::GetList получить помимо базовой цены ещё и цену со скидкой, чтобы не запрашивать её на втором шаге?
2. Реально ли получить какой-то параметр, говорящий, что на товар действует скидка, чтобы не вытягивать цены, а просто отбросить товары без скидки?
3. Возможно имеется более изящный способ реализации.
Заранее спасибо за ответы.
Используется 1С-Битрикс: Управление сайтом 17.5.4. Редакция продукта: Бизнес
Задача состоит в том, чтобы при добавлении GET параметра sale в нужной каталоге показывались только товары, имеющие скидки
Т.е. в каталоге Аксессуары порядка 2000 позиций, но скидка действует только на 50 товаров. Как их выбрать корректно?
В данный момент реализовал следующим образом:
1. Делаю выборку ID и цены для всех товаров нужного каталога:
Код |
---|
$myarSelect = Array("ID","CATALOG_GROUP_5"); $products = CIBlockElement::GetList( array(), array( "IBLOCK_ID" => $arParams["IBLOCK_ID"], "SECTION_ID" => $arParams['SECTION_ID'], "INCLUDE_SUBSECTIONS" => "Y", "CATALOG_AVAILABLE" => "Y", "ACTIVE" => "Y", ), false, false, $myarSelect ); |
Код |
---|
while ($arProductDiscounts = $products->Fetch()) { $price = CCatalogProduct::GetOptimalPrice($arProductDiscounts['ID'], 1, $USER->GetUserGroupArray(), 'N'); $arProductDiscounts['DISCOUNT'] = $price['RESULT_PRICE']['DISCOUNT_PRICE']; if ((float)$arProductDiscounts['DISCOUNT'] != (float)$arProductDiscounts['CATALOG_PRICE_5']) { $arIBlockListID[]=$arProductDiscounts['ID']; } } $GLOBALS['arrFilterAkcii'] = array("ID"=>$arIBlockListID); // сохраняю массив ID в фильтр для выборки |
Код |
---|
$APPLICATION->IncludeComponent( "bitrix:catalog.section", "template", array( //... "FILTER_NAME" => "arrFilterAkcii", //... ), ); |
В каталогах, в которых товаров 200-300 всё работает великолепно, но вот в таких как Аксессуары (больше 2000) начались проблемы. Цикл обрабатывается очень долго. Примерно 1 минуту "залипа".
Решил эту проблему кэшированием с временем сутки. Итоговый код выглядит следующим образом:
Код |
---|
<? if (isset($_GET['sale']) AND (int)$_GET['sale']==1) { $cntIBLOCK_List = $arParams["SECTION_ID"]; $cache = new CPHPCache(); $cache_time = 86400; $cache_id = 'arIBlockListID'.$cntIBLOCK_List; $cache_path = 'arIBlockListID'; if ($cache_time > 0 && $cache->InitCache($cache_time, $cache_id, $cache_path)) { $res = $cache->GetVars(); if (is_array($res["arIBlockListID"]) && (count($res["arIBlockListID"]) > 0)) $arIBlockListID = $res["arIBlockListID"]; } if (!is_array($arIBlockListID)) { $myarSelect = Array("ID","CATALOG_GROUP_5"); $products = CIBlockElement::GetList( array(), array( "IBLOCK_ID" => $arParams["IBLOCK_ID"], "SECTION_ID" => $arParams["SECTION_ID"], "INCLUDE_SUBSECTIONS" => "Y", "CATALOG_AVAILABLE" => "Y", "ACTIVE" => "Y", ), false, false, $myarSelect ); while ($arProductDiscounts = $products->Fetch()) { $price = CCatalogProduct::GetOptimalPrice($arProductDiscounts['ID'], 1, $USER->GetUserGroupArray(), 'N'); $arProductDiscounts['DISCOUNT'] = $price['RESULT_PRICE']['DISCOUNT_PRICE']; if ((float)$arProductDiscounts['DISCOUNT'] != (float)$arProductDiscounts['CATALOG_PRICE_5']) { $arIBlockListID[]=$arProductDiscounts['ID']; } } if ($cache_time > 0) { $cache->StartDataCache($cache_time, $cache_id, $cache_path); $cache->EndDataCache(array("arIBlockListID"=>$arIBlockListID)); } } if (empty($arIBlockListID)) { $arIBlockListID = 1; } $GLOBALS['arrFilterAkcii'] = array("ID"=>$arIBlockListID); } $APPLICATION->IncludeComponent( "bitrix:catalog.section", "template", array( //... "FILTER_NAME" => "arrFilterAkcii", //... ), ); ?> |
Возник резонный вопрос, реально ли упростить этот код?
1. Возможно ли в CIBlockElement::GetList получить помимо базовой цены ещё и цену со скидкой, чтобы не запрашивать её на втором шаге?
2. Реально ли получить какой-то параметр, говорящий, что на товар действует скидка, чтобы не вытягивать цены, а просто отбросить товары без скидки?
3. Возможно имеется более изящный способ реализации.
Заранее спасибо за ответы.