Доброго времени суток. Просмотрел все темы, выдаваемые гуглом по этому вопросу. Однозначного варианта решения нет.
Используется 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. Возможно имеется более изящный способ реализации.
Заранее спасибо за ответы.
