Битрикс: получение ближайших по цене товаров из категории


В некоторых случаях в интернет-магазине необходимо вывести блок с товарами, которые максимально близки к данному по цене и привязаны к той же категории (например, в карточке товара, блок “Возможно вам также будет интересно”). Для реализации подобного функционала можно использовать следующий PHP код (разместить его можно шаблоне компонента детальной страницы товара).

// $arParams['ID'] - ID товара текущего товара, по которому ищутся ближайшие по цене
// CATALOG_PRICE_1 -  идентификатор цены, используемой для каталога

// $arParams['ID'] = 999;

$categoryProducts = array(); 

if ($arParams['ID']) { 

    $currentProduct = CIBlockElement::GetByID($arParams['ID']); 

    if ($arCurrentProduct = $currentProduct->GetNext()) { 

        if ($arCurrentProduct['IBLOCK_SECTION_ID']) { 

            $currentProductPrice = CPrice::GetList( 

            array(), 

            array( 

                "PRODUCT_ID" => $arParams['ID'], 

                // "CATALOG_GROUP_ID" => CATALOG_PRICE_1 

            ) 

            ); 

            if ($arPrices = $currentProductPrice->GetNext()) { 

                $currentProductPrice = (int)$arPrices['PRICE'];              

                $currentCategoryProducts = CIBlockElement::GetList( 

                    Array(),  

                    Array('IBLOCK_ID'=>$arCurrentProduct['IBLOCK_ID'], 'IBLOCK_SECTION_ID'=>$arCurrentProduct['IBLOCK_SECTION_ID'], 'ACTIVE'=>'Y', '!ID'=>$arParams['ID']),  

                    false,  

                    false,  

                    Array('ID', 'NAME', 'CATALOG_PRICE_1') 

                ); 

                $categoryProductsCheaper = array(); 

                $categoryProductsExpensive = array(); 

                while ($currentCategoryProduct = $currentCategoryProducts->GetNext()) { 

                    if ((int)$currentCategoryProduct['CATALOG_PRICE_1'] < $currentProductPrice) { 

                        $categoryProductsCheaper[] = array( 

                            'ID' => $currentCategoryProduct['ID'], 

                            'PRICE' => (int)$currentCategoryProduct['CATALOG_PRICE_1'], 

                        ); 

                    } else { 

                        $categoryProductsExpensive[] = array( 

                            'ID' => $currentCategoryProduct['ID'], 

                            'PRICE' => (int)$currentCategoryProduct['CATALOG_PRICE_1'], 

                        ); 

                    } 

                } 

                usort($categoryProductsCheaper, function ($item1, $item2) { 

                    if ($item1['PRICE'] == $item2['PRICE']) return 0; 

                    return $item1['PRICE'] > $item2['PRICE'] ? -1 : 1; 

                }); 

                usort($categoryProductsExpensive, function ($item1, $item2) { 

                    if ($item1['PRICE'] == $item2['PRICE']) return 0; 

                    return $item1['PRICE'] < $item2['PRICE'] ? -1 : 1; 

                }); 

                if (count($categoryProductsCheaper) < count($categoryProductsExpensive)) { 

                    $categoryProductsCheaper = array_slice($categoryProductsCheaper, 0, 2); 

                    $categoryProductsTemp = array_merge($categoryProductsCheaper, $categoryProductsExpensive); 

                } else { 

                    $categoryProductsExpensive = array_slice($categoryProductsExpensive, 0, 2); 

                    $categoryProductsTemp = array_merge($categoryProductsExpensive, $categoryProductsCheaper); 

                } 

                $categoryProductsTemp = array_slice($categoryProductsTemp, 0, 4); 

                foreach ($categoryProductsTemp as $categoryProduct) { 

                    $categoryProducts[] = $categoryProduct['ID']; 

                } 

            } 

        } 

    } 

} 

if (!empty($categoryProducts)) { 

    print_r($categoryProducts); 

}