diff --git a/helpers/FilterHelper.php b/helpers/FilterHelper.php index 61839d7..a8158f3 100755 --- a/helpers/FilterHelper.php +++ b/helpers/FilterHelper.php @@ -111,66 +111,40 @@ - - - public static function setNewQueryParams(ActiveQuery $query, array $params) - { - $last_query = null; - foreach ($params as $key => $param) { - switch ($key) { - case 'special': - self::filterSpecial($param, $query); - break; - case 'brands': - self::filterBrands($param, $query); - break; - case 'keywords': - self::filterKeywords($param, $query); - break; - case 'prices': - self::filterPrices($param, $query); - break; - default: - self::filterNewOptions($key, $param, $query); - break; - } - } - } - - /** - * @param $key - * @param array $param - * @param ActiveQuery $query + * select options for product variants with selected category + * + * @param integer $categoryId + * @param integer $langId + * @return mixed */ - private static function filterNewOptions($key, array $param, &$query) - { - $query->andWhere( - 'product.id IN ( - SELECT DISTINCT products - FROM ( - SELECT id AS products FROM product WHERE id IN( - SELECT product_id FROM product_option - INNER JOIN tax_option ON tax_option.id = product_option.option_id - INNER JOIN tax_group ON tax_group.id = tax_option.tax_group_id - INNER JOIN tax_group_lang ON tax_group.id = tax_group_lang.tax_group_id - INNER JOIN tax_option_lang ON tax_option.id = tax_option_lang.tax_option_id - WHERE tax_group_lang.alias = \''. $key .'\' AND tax_option_lang.alias IN (\'' . implode('\',\'', $param) . '\')) - OR id IN ( - (SELECT product_id AS products - FROM product_variant_option - INNER JOIN product_variant ON product_variant_option.product_variant_id = product_variant.id - INNER JOIN tax_option ON tax_option.id = product_variant_option.option_id - INNER JOIN tax_group ON tax_group.id = tax_option.tax_group_id - INNER JOIN tax_group_lang ON tax_group.id = tax_group_lang.tax_group_id - INNER JOIN tax_option_lang ON tax_option.id = tax_option_lang.tax_option_id - WHERE tax_group_lang.alias = \''. $key .'\' AND tax_option_lang.alias IN (\'' . implode('\',\'', $param) . '\')) - ) - ) AS table_name - )' - ); - - + public static function getProductVariantOptions($categoryId,$langId){ + $result = \Yii::$app->db->cache(function () use($categoryId,$langId) { + return ( new Query() )->distinct()->select('tax_group_lang.alias') + ->from('product_variant_option') + ->innerJoin( + 'tax_option', + 'product_variant_option.option_id = tax_option.id' + ) + ->innerJoin( + 'tax_group', + 'tax_group.id = tax_option.tax_group_id' + ) + ->innerJoin( + 'tax_group_lang', + 'tax_group_lang.tax_group_id = tax_group.id' + ) + ->innerJoin( + 'tax_group_to_category', + 'tax_group_to_category.tax_group_id = tax_group.id' + ) + ->where([ + 'tax_group_lang.language_id' => $langId, + 'tax_group_to_category.category_id' => $categoryId, + 'tax_group.is_filter' => true + ])->all(); + },60*60*24); + return ArrayHelper::getColumn($result,'alias'); } @@ -179,87 +153,119 @@ * * @param ActiveQuery $query * @param array $params + * @param integer $categoryId + * @param integer $langId */ - public static function setQueryParams(ActiveQuery $query, array $params) + public static function setQueryParams(ActiveQuery $query, array $params, $categoryId, $langId) { $last_query = null; + $productVariantOptions = self::getProductVariantOptions($categoryId,$langId); foreach ($params as $key => $param) { switch ($key) { case 'special': + unset($params[$key]); self::filterSpecial($param, $query); break; case 'brands': + unset($params[$key]); self::filterBrands($param, $query); break; case 'keywords': + unset($params[$key]); self::filterKeywords($param, $query); break; case 'prices': + unset($params[$key]); self::filterPrices($param, $query); break; - default: - $last_query = self::filterOptions($param, $last_query); - break; + } } - // If tax option filters were provided filter query with them - if (!empty( $last_query )) { - $query->andWhere([ 'product.id' => $last_query ]); - } + self::filterOptions($params, $productVariantOptions, $query); } - + /** * Tax Option filter * * @param string[] $params - * @param \yii\db\Query|null $last_query + * @param string[] $productVariantOptions + * @param \yii\db\Query|null $query * @param bool $in_stock * * @return \yii\db\Query */ - private static function filterOptions(array $params, Query $last_query = null, bool $in_stock = true): Query + private static function filterOptions(array $params,$productVariantOptions, Query &$query = null, bool $in_stock = true) { - $variant_query = ( new Query() )->distinct() - ->select('product_variant.product_id as products') - ->from('product_variant_option') - ->innerJoin( - 'product_variant', - 'product_variant_option.product_variant_id = product_variant.id' - ) - ->innerJoin( - 'tax_option', - 'tax_option.id = product_variant_option.option_id' - ) - ->innerJoin( - 'tax_option_lang', - 'tax_option_lang.tax_option_id = tax_option.id' - ) - ->where([ 'tax_option_lang.alias' => $params ]); + ->select('product_variant.product_id as products') + ->from('product_variant'); + + foreach ($params as $key=>$param){ + if(in_array($key, $productVariantOptions)){ + unset($params[$key]); + $product_variant_id = ( new Query() )->distinct()->select('product_variant_option.product_variant_id as id') + ->from('product_variant_option') + ->innerJoin( + 'tax_option', + 'tax_option.id = product_variant_option.option_id' + ) + ->innerJoin( + 'tax_option_lang', + 'tax_option_lang.tax_option_id = tax_option.id' + ) + ->innerJoin( + 'tax_group', + 'tax_group.id = tax_option.tax_group_id' + ) + ->innerJoin( + 'tax_group_lang', + 'tax_group_lang.tax_group_id = tax_group.id' + ) + ->where([ 'tax_group_lang.alias' => $key ]) + ->andWhere([ 'tax_option_lang.alias' => $param ]); + $variant_query->andWhere(['product_variant.id'=>$product_variant_id]); + } + + } + + if($in_stock) { $variant_query->andWhere(['!=', 'product_variant.stock', 0]); } $product_query = ( new Query() )->distinct() - ->select('product_option.product_id as products') - ->from('product_option') - ->innerJoin('tax_option', 'product_option.option_id = tax_option.id') - ->innerJoin( - 'tax_option_lang', - 'tax_option_lang.tax_option_id = tax_option.id' - ) - ->where( - [ 'tax_option_lang.alias' => $params ] - ) - ->union($variant_query); - $query = ( new Query() )->select('products') - ->from([ 'result_table' => $product_query ]); - if (!empty( $last_query )) { - $query->andWhere([ 'product.id' => $last_query ]); + ->select('product_option.product_id as products') + ->from('product_option') + ->innerJoin( + 'tax_option', + 'tax_option.id = product_option.option_id' + ) + ->innerJoin( + 'tax_option_lang', + 'tax_option_lang.tax_option_id = tax_option.id' + ) + ->innerJoin( + 'tax_group', + 'tax_group.id = tax_option.tax_group_id' + ) + ->innerJoin( + 'tax_group_lang', + 'tax_group_lang.tax_group_id = tax_group.id' + ); + foreach ($params as $key=>$param){ + $product_query + ->where([ 'tax_group_lang.alias' => $key ]) + ->andWhere([ 'tax_option_lang.alias' => $param ]); + } - return $query; + + $query->andWhere([ 'product.id' => $product_query ]); + $query->andWhere([ 'product.id' => $variant_query ]); + } + + /** * Fill $query with special filters (used in Product) diff --git a/models/ProductFrontendSearch.php b/models/ProductFrontendSearch.php index 1356eef..f1b3914 100755 --- a/models/ProductFrontendSearch.php +++ b/models/ProductFrontendSearch.php @@ -4,6 +4,7 @@ use artweb\artbox\ecommerce\helpers\FilterHelper; use artweb\artbox\ecommerce\models\Category; + use artweb\artbox\language\models\Language; use yii\base\Model; use yii\data\ActiveDataProvider; use yii\data\ArrayDataProvider; @@ -116,23 +117,17 @@ return $dataProvider; } - - public function getSearchQuery($category = null, $params = [], $in_stock = true) + + /** + * @param Category $category + * @param array $params + * @param bool $in_stock + * @return mixed + */ + public function getSearchQuery($category, $params = [], $in_stock = true) { - - if (!empty( $category )) { - /** @var ActiveQuery $query */ - /**@var Category $category * */ - $query = $category->getProducts(); - - } else { - $query = Product::find() - ->joinWith( - [ - 'category.lang', - ] - ); - } + + $query = $category->getProducts(); $query->select([ 'product.*' ]); $query->joinWith( @@ -175,9 +170,9 @@ 'product_variant.price', ] ); - - FilterHelper::setQueryParams($query, $params); - + + $lang = Language::getCurrent(); + FilterHelper::setQueryParams($query, $params, $category->id, $lang->id); return $query; } @@ -189,21 +184,16 @@ public function priceLimits($category = null, $params = []) { - if (!empty( $category )) { - /** @var ActiveQuery $query */ - // $query = $category->getRelations('product_categories'); - $query = $category->getProducts(); - } else { - $query = Product::find(); - } + $query = $category->getProducts(); $query->select(['MAX('.ProductVariant::tableName() . '.price) as max', 'MIN('.ProductVariant::tableName() . '.price) as min']); $query->joinWith('variant'); // Price filter fix unset( $params[ 'prices' ] ); - - FilterHelper::setQueryParams($query, $params); + + $lang = Language::getCurrent(); + FilterHelper::setQueryParams($query, $params, $category->id, $lang->id); $query->andWhere( [ '>=', -- libgit2 0.21.4