From 9ebdab4fd42c0c4b1fd17c3968322cfa9e78ddfb Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 6 Dec 2016 17:03:15 +0200 Subject: [PATCH] add variantSku --- helpers/FilterHelper.php | 706 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- models/ProductFrontendSearch.php | 29 +++++++++++++++-------------- 2 files changed, 354 insertions(+), 381 deletions(-) diff --git a/helpers/FilterHelper.php b/helpers/FilterHelper.php index a046eb7..96993df 100755 --- a/helpers/FilterHelper.php +++ b/helpers/FilterHelper.php @@ -1,424 +1,396 @@ joinWith('lang') - ->where([ 'is_filter' => 'TRUE' ]) - ->all(), - 'lang.alias' - ); - } else { - return static::$optionsList; - } - + if (empty( static::$optionsList )) { + return static::$optionsList = ArrayHelper::getColumn( + TaxGroup::find() + ->joinWith('lang') + ->where([ 'is_filter' => 'TRUE' ]) + ->all(), + 'lang.alias' + ); + } else { + return 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) - { + } - $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( + $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 + ) { + 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 + ) === 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( - $value_item, - $result[ $key ][ $value_key ] - ) === false - ) { - $result[ $key ][ $value_key ][] = $value_item; - } + $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 ($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 (!isset( $result[ $key ] ) || array_search($value, $result[ $key ]) === false) { + $result[ $key ][] = $value; } } + } - $filterView = []; - - foreach ($optionsTemplate as $optionKey) { - if (isset( $result[ $optionKey ] )) { - $filterView[ $optionKey ] = $result[ $optionKey ]; - } + $filterView = []; + 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; - } - /** - * 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); + 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 + */ + 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 ]); + } + } - 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 ]); - } - + /** + * 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 + { + $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]); } - - - - /** - * 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 - */ - 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); + $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 = []; /** - * Fill query with brands filter - * - * @param int[] $param - * @param \yii\db\ActiveQuery $query + * @var string $key */ - private static function filterBrands(array $param, ActiveQuery $query) - { - $query->andFilterWhere([ Product::tableName() . '.brand_id' => $param ]); + 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); + } - /** - * 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 ]; + /** + * 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 && $param != preg_match ('/^20[\d]{2}$/',$param, $matches)){ + $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, + ] + + ]; } - /** - * @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); } - - /** - * 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); + 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 ]; + } + $query->andFilterWhere($conditions); } + +} \ No newline at end of file diff --git a/models/ProductFrontendSearch.php b/models/ProductFrontendSearch.php index cd13d35..d77832c 100755 --- a/models/ProductFrontendSearch.php +++ b/models/ProductFrontendSearch.php @@ -4,7 +4,6 @@ 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; @@ -118,18 +117,22 @@ return $dataProvider; } - - /** - * @param Category $category - * @param array $params - * @param bool $in_stock - * @return mixed - */ - public function getSearchQuery($category, $params = [], $in_stock = true) + public function getSearchQuery($category = null, $params = [], $in_stock = true) { - $query = $category->getProducts(); + if (!empty( $category )) { + /** @var ActiveQuery $query */ + /**@var Category $category * */ + $query = $category->getProducts(); + } else { + $query = Product::find() + ->joinWith( + [ + 'category.lang', + ] + ); + } $query->select([ 'product.*' ]); $query->joinWith( @@ -173,8 +176,7 @@ ] ); - $lang = Language::getCurrent(); - FilterHelper::setQueryParams($query, $params, $category->id, $lang->id); + FilterHelper::setQueryParams($query, $params); return $query; } @@ -200,8 +202,7 @@ // Price filter fix unset( $params[ 'prices' ] ); - $lang = Language::getCurrent(); - FilterHelper::setQueryParams($query, $params, $category->id, $lang->id); + FilterHelper::setQueryParams($query, $params); $query->andWhere( [ '>=', -- libgit2 0.21.4