====== Фильтрация по цене модификаций ====== В некоторых интернет-магазинах описание товаров предполагает активное использование модификаций, товары в этом случае задают базовое название и описание продукции, а модификации расширяют эти данные, дополняя различными характеристиками, например, объемом, весом, размером и т.д. Как правило, модификации в этом случае будут иметь различную стоимость, а базовые товары получат стоимость равную нулю. При наличии большого количества таких товаров стоит задача правильной организации фильтрации в интернет-магазине. Стандратный фильтр позволяет организовать подход, при котором модификации выводятся на одном уровне с базовыми товарами, для этого необходимо задать: $Shop_Controller_Show->modificationsList(TRUE); В этом случае фильтрация товаров по цене будет работать корректно, но такой подход не всегда применителен. Иногда требуется подключить к фильтрации цены модификаций, но не выводить их на том же уровне, что и основные товары, реализация такого механизма есть в [[private:market:extended_filters:programmist|адаптивных фильтрах]]. Если требуется организовать фильтрацию товаров по цене модификации без применения адаптивных фильтров, то можно использовать нижеприведенное решение, для его установки необходимо выполнить следующие шаги: - Для вывода правильных пределов в фильтре заменить:$Shop_Controller_Show->addMinMaxPrice();На:// Добавляем пределы для выборки цен с учетом модификаций $Shop_Controller_Show ->modificationsList(TRUE) ->addMinMaxPrice() ->modificationsList(FALSE); - В коде фильтра в ТДС ''Интернет-магазин'' перед выборкой ''absolute_price'' добавить следующий код, он повторяет выборку товаров, но теперь выбирается цена модификации, попадающая в заданный фильтром интервал:// Выбираем цену модификации, попадающую в нужный предел $oModificationsWithPrice = Core_QueryBuilder::select() ->select(array(Core_QueryBuilder::expression(str_replace('shop_items', 'modifications', $query_currency_switch)), 'absolute_price')) ->from(array('shop_items', 'modifications')) ->leftJoin('shop_item_discounts', 'modifications.id', '=', 'shop_item_discounts.shop_item_id') ->leftJoin('shop_discounts', 'shop_item_discounts.shop_discount_id', '=', 'shop_discounts.id', array( array('AND ' => array('shop_discounts.active', '=', 1)), array('AND ' => array('shop_discounts.deleted', '=', 0)), array('AND' => array('shop_discounts.start_datetime', '<=', $current_date)), array('AND (' => array('shop_discounts.end_datetime', '>=', $current_date)), array('OR' => array('shop_discounts.end_datetime', '=', '0000-00-00 00:00:00')), array(')' => NULL) )) ->where('modifications.modification_id', '=', Core_QueryBuilder::expression('`shop_items`.`id`')) ->groupBy('modifications.id') ->limit(1) ; if ($price_from) { $oModificationsWithPrice->having('absolute_price', '>=', $price_from); } if ($price_to) { $oModificationsWithPrice->having('absolute_price', '<=', $price_to); } // Добавляем кастомный столбец $Shop_Controller_Show->shopItems() ->queryBuilder() ->select(array($oModificationsWithPrice, 'modification_price')); // Функция обратного вызова для кастомного столбца class Shop_Item_Observer_ModificationPrice { static public function onCallmodification_price() { } } Core_Event::attach('shop_item.onCallmodification_price', array('Shop_Item_Observer_ModificationPrice', 'onCallmodification_price')); - Затем после установки условий на выборку цены добавить такой код:if ($price_from || $price_to) { $Shop_Controller_Show->shopItems()->queryBuilder() ->having('absolute_price', '>', 0) ->setOr() ->having('modification_price', '>', 0); } - Ниже для корректной сортировки после:->orderBy('absolute_price', $sorting == 1 ? 'ASC' : 'DESC')Добавить:->orderBy('modification_price', $sorting == 1 ? 'ASC' : 'DESC') Страницу создал Максим Засорин 23.12.16 в 11:05