From dc6b03e48b2d2b7d3df97a07ab98ae32c98f1517 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 6 Dec 2016 16:07:35 +0200 Subject: [PATCH] add variantSku --- helpers/FilterHelper.php | 706 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- models/ProductFrontendSearch.php | 29 ++++++++++++++--------------- 2 files changed, 381 insertions(+), 354 deletions(-) diff --git a/helpers/FilterHelper.php b/helpers/FilterHelper.php index a199a5c..a046eb7 100755 --- a/helpers/FilterHelper.php +++ b/helpers/FilterHelper.php @@ -1,396 +1,424 @@ joinWith('lang') - ->where([ 'is_filter' => 'TRUE' ]) - ->all(), - 'lang.alias' - ); - } else { - return static::$optionsList; - } - } + public static $optionsList = []; - /** - * Return custom filter-option link - * - * @param array $filter - * @param string $key - * @param mixed $value - * @param bool $remove - * - * @return array - */ - public static function getFilterForOption(array $filter, string $key, $value, bool $remove = false) - { + /** + * Get TaxGroups + * + * @return array + */ + public static function optionsTemplate() + { + if (empty( static::$optionsList )) { + return static::$optionsList = ArrayHelper::getColumn( + TaxGroup::find() + ->joinWith('lang') + ->where([ 'is_filter' => 'TRUE' ]) + ->all(), + 'lang.alias' + ); + } else { + return static::$optionsList; + } - $optionsTemplate = self::optionsTemplate(); - array_unshift($optionsTemplate, "special", "brands"); + } + + /** + * Return custom filter-option link + * + * @param array $filter + * @param string $key + * @param mixed $value + * @param bool $remove + * + * @return array + */ + public static function getFilterForOption(array $filter, string $key, $value, bool $remove = false) + { - $result = $filter; + $optionsTemplate = self::optionsTemplate(); + array_unshift($optionsTemplate, "special", "brands"); - if (is_array($value)) { - foreach ($value as $value_key => $value_items) { - if (!is_array($value_items)) { - $value_items = [ $value_items ]; - } - foreach ($value_items as $value_item) { - if ($remove && isset( $result[ $key ] ) && ( $i = array_search( - $value_item, - $result[ $key ][ $value_key ] - ) ) !== false - ) { - unset( $result[ $key ][ $value_key ][ $i ] ); - if (empty( $result[ $key ][ $value_key ] )) { - unset( $result[ $key ][ $value_key ] ); - } - } else { - if (!isset( $result[ $key ][ $value_key ] ) || array_search( + $result = $filter; + + if (is_array($value)) { + foreach ($value as $value_key => $value_items) { + if (!is_array($value_items)) { + $value_items = [ $value_items ]; + } + foreach ($value_items as $value_item) { + if ($remove && isset( $result[ $key ] ) && ( $i = array_search( $value_item, $result[ $key ][ $value_key ] - ) === false + ) ) !== false ) { - $result[ $key ][ $value_key ][] = $value_item; + unset( $result[ $key ][ $value_key ][ $i ] ); + if (empty( $result[ $key ][ $value_key ] )) { + unset( $result[ $key ][ $value_key ] ); + } + } else { + if (!isset( $result[ $key ][ $value_key ] ) || array_search( + $value_item, + $result[ $key ][ $value_key ] + ) === false + ) { + $result[ $key ][ $value_key ][] = $value_item; + } } } } - } - } else { - if ($remove && isset( $result[ $key ] ) && ( $i = array_search($value, $result[ $key ]) ) !== false) { - unset( $result[ $key ][ $i ] ); - if (empty( $result[ $key ] )) { - unset( $result[ $key ] ); - } } else { - if (!isset( $result[ $key ] ) || array_search($value, $result[ $key ]) === false) { - $result[ $key ][] = $value; + if ($remove && isset( $result[ $key ] ) && ( $i = array_search($value, $result[ $key ]) ) !== false) { + unset( $result[ $key ][ $i ] ); + if (empty( $result[ $key ] )) { + unset( $result[ $key ] ); + } + } else { + if (!isset( $result[ $key ] ) || array_search($value, $result[ $key ]) === false) { + $result[ $key ][] = $value; + } } } - } - $filterView = []; + $filterView = []; + + foreach ($optionsTemplate as $optionKey) { + if (isset( $result[ $optionKey ] )) { + $filterView[ $optionKey ] = $result[ $optionKey ]; + } - foreach ($optionsTemplate as $optionKey) { - if (isset( $result[ $optionKey ] )) { - $filterView[ $optionKey ] = $result[ $optionKey ]; } + return $filterView; } - return $filterView; - } + /** + * select options for product variants with selected category + * + * @param integer $categoryId + * @param integer $langId + * @return mixed + */ + public static function getProductVariantOptions($categoryId,$langId){ + $cacheKey = [ + 'OptionsForFilter', + 'categoryId' => $categoryId, + 'langId' =>$langId + ]; + if (!$OptionsForFilter = \Yii::$app->cache->get($cacheKey)) { + $OptionsForFilter = ( 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(); + $OptionsForFilter = ArrayHelper::getColumn($OptionsForFilter,'alias'); + \Yii::$app->cache->set($cacheKey, $OptionsForFilter, 3600 * 24); + } + + return $OptionsForFilter; + } - 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; + /** + * Fill query with filter conditions + * + * @param ActiveQuery $query + * @param array $params + * @param integer $categoryId + * @param integer $langId + */ + 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; + + } } + if(!empty($params)){ + self::filterOptions($params, $productVariantOptions, $query); + } + } - } - /** - * @param $key - * @param array $param - * @param ActiveQuery $query - */ - 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 - )' - ); + /** + * Tax Option filter + * + * @param string[] $params + * @param string[] $productVariantOptions + * @param \yii\db\Query|null $query + * @param bool $in_stock + * + * @return \yii\db\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'); + $variantSearch = false; + foreach ($params as $key=>$param){ + if(in_array($key, $productVariantOptions)){ + $variantSearch = true; + 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($variantSearch){ + if($in_stock) { + $variant_query->andWhere(['!=', 'product_variant.stock', 0]); + } + + + $query->andWhere([ 'product.id' => $variant_query ]); - /** - * Fill query with filter conditions - * - * @param ActiveQuery $query - * @param array $params - */ - public static function setQueryParams(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: - $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 ]); - } - } - /** - * Tax Option filter - * - * @param string[] $params - * @param \yii\db\Query|null $last_query - * @param bool $in_stock - * - * @return \yii\db\Query - */ - private static function filterOptions(array $params, Query $last_query = null, bool $in_stock = true): Query - { + if(!empty($params)) { + $product_query = ( new Query() )->distinct() + ->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 ]); + + } + $query->andWhere([ 'product.id' => $product_query ]); + } + - $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 ]); - 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 ]); } - return $query; - } - /** - * Fill $query with special filters (used in Product) - * - * @param array $params - * @param \yii\db\ActiveQuery $query - */ - private static function filterSpecial(array $params, ActiveQuery $query) - { - $conditions = []; + + /** - * @var string $key + * Fill $query with special filters (used in Product) + * + * @param array $params + * @param \yii\db\ActiveQuery $query */ - foreach ($params as $key => $param) { - $conditions[] = [ - '=', - Product::tableName() . '.' . $key, - $param, - ]; - } - /* If 2 or more special conditions get all that satisfy at least one of them. */ - if (count($conditions) > 1) { - array_unshift($conditions, 'or'); - } else { - $conditions = $conditions[ 0 ]; + private static function filterSpecial(array $params, ActiveQuery $query) + { + $conditions = []; + /** + * @var string $key + */ + foreach ($params as $key => $param) { + $conditions[] = [ + '=', + Product::tableName() . '.' . $key, + $param, + ]; + } + /* If 2 or more special conditions get all that satisfy at least one of them. */ + if (count($conditions) > 1) { + array_unshift($conditions, 'or'); + } else { + $conditions = $conditions[ 0 ]; + } + $query->andFilterWhere($conditions); } - $query->andFilterWhere($conditions); - } - /** - * Fill query with brands filter - * - * @param int[] $param - * @param \yii\db\ActiveQuery $query - */ - private static function filterBrands(array $param, ActiveQuery $query) - { - $query->andFilterWhere([ Product::tableName() . '.brand_id' => $param ]); - } + /** + * Fill query with brands filter + * + * @param int[] $param + * @param \yii\db\ActiveQuery $query + */ + private static function filterBrands(array $param, ActiveQuery $query) + { + $query->andFilterWhere([ Product::tableName() . '.brand_id' => $param ]); + } - /** - * Fill query with keywords filter - * - * @param array $params - * @param \yii\db\ActiveQuery $query - */ - private static function filterKeywords(array $params, ActiveQuery $query) - { - $conditions = []; - if (!empty( $params )) { - if (!is_array($params)) { - $params = [ $params ]; - } - /** - * @var string $param Inputed keyword - */ - foreach ($params as $param) { - - if(iconv_strlen($param) >= 3){ - $conditions[] = [ - 'or', - [ - 'ilike', - ProductLang::tableName() . '.title', - $param, - ], - [ - 'ilike', - BrandLang::tableName() . '.title', - $param, - ], - [ - 'ilike', - CategoryLang::tableName() . '.title', - $param, - ], - [ - 'ilike', - ProductVariantLang::tableName() . '.title', - $param, - ], - [ - 'ilike', - ProductVariant::tableName() . '.sku', - $param, - ] - - ]; + /** + * Fill query with keywords filter + * + * @param array $params + * @param \yii\db\ActiveQuery $query + */ + private static function filterKeywords(array $params, ActiveQuery $query) + { + $conditions = []; + if (!empty( $params )) { + if (!is_array($params)) { + $params = [ $params ]; } + /** + * @var string $param Inputed keyword + */ + foreach ($params as $param) { + + if(iconv_strlen($param) >= 3){ + $conditions[] = [ + 'or', + [ + 'ilike', + ProductLang::tableName() . '.title', + $param, + ], + [ + 'ilike', + BrandLang::tableName() . '.title', + $param, + ], + [ + 'ilike', + CategoryLang::tableName() . '.title', + $param, + ], + [ + 'ilike', + ProductVariantLang::tableName() . '.title', + $param, + ], + [ + 'ilike', + ProductVariant::tableName() . '.sku', + $param, + ] + + ]; + } + } } + if (count($conditions) > 1) { + array_unshift($conditions, 'or'); + } else { + $conditions = $conditions[ 0 ]; + } + $query->andFilterWhere($conditions); } - if (count($conditions) > 1) { - array_unshift($conditions, 'or'); - } else { - $conditions = $conditions[ 0 ]; - } - $query->andFilterWhere($conditions); - } - /** - * Fill query with price limits filter - * - * @param array $params - * @param \yii\db\ActiveQuery $query - */ - private static function filterPrices(array $params, ActiveQuery $query) - { - $conditions = []; - if (!empty( $params[ 'min' ] ) && $params[ 'min' ] > 0) { - $conditions[] = [ - '>=', - ProductVariant::tableName() . '.price', - $params[ 'min' ], - ]; - } - if (!empty( $params[ 'max' ] ) && $params[ 'max' ] > 0) { - $conditions[] = [ - '<=', - ProductVariant::tableName() . '.price', - $params[ 'max' ], - ]; - } - if (count($conditions) > 1) { - array_unshift($conditions, 'and'); - } else { - $conditions = $conditions[ 0 ]; + /** + * Fill query with price limits filter + * + * @param array $params + * @param \yii\db\ActiveQuery $query + */ + private static function filterPrices(array $params, ActiveQuery $query) + { + $conditions = []; + if (!empty( $params[ 'min' ] ) && $params[ 'min' ] > 0) { + $conditions[] = [ + '>=', + ProductVariant::tableName() . '.price', + $params[ 'min' ], + ]; + } + if (!empty( $params[ 'max' ] ) && $params[ 'max' ] > 0) { + $conditions[] = [ + '<=', + ProductVariant::tableName() . '.price', + $params[ 'max' ], + ]; + } + if (count($conditions) > 1) { + array_unshift($conditions, 'and'); + } else { + $conditions = $conditions[ 0 ]; + } + $query->andFilterWhere($conditions); } - $query->andFilterWhere($conditions); - } -} + } \ No newline at end of file diff --git a/models/ProductFrontendSearch.php b/models/ProductFrontendSearch.php index d77832c..cd13d35 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; @@ -117,22 +118,18 @@ 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(); + $query = $category->getProducts(); - } else { - $query = Product::find() - ->joinWith( - [ - 'category.lang', - ] - ); - } $query->select([ 'product.*' ]); $query->joinWith( @@ -176,7 +173,8 @@ ] ); - FilterHelper::setQueryParams($query, $params); + $lang = Language::getCurrent(); + FilterHelper::setQueryParams($query, $params, $category->id, $lang->id); return $query; } @@ -202,7 +200,8 @@ // 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