diff --git a/common/modules/product/helpers/ProductHelper.php b/common/modules/product/helpers/ProductHelper.php index 96b3f9f..18cbe9a 100755 --- a/common/modules/product/helpers/ProductHelper.php +++ b/common/modules/product/helpers/ProductHelper.php @@ -1,210 +1,295 @@ getTree(); // with('categoryName')-> - } - - public static function getBrands() { - return Brand::find(); // ->with('brandName') - } - - /* - * Return custom filter-option link - * @var array $filter - * @var array $options - * @return array - */ - public static function getFilterForOption($filter, $key, $value, $remove = false) { - $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) { - $result[$key][$value_key][] = $value_item; + + namespace common\modules\product\helpers; + + use common\modules\product\models\Brand; + use common\modules\product\models\Category; + use common\modules\product\models\Product; + use common\modules\product\models\ProductVariant; + use common\modules\product\models\BrandName; + use common\modules\product\models\CategoryName; + use yii\base\Object; + use Yii; + use yii\db\ActiveQuery; + + class ProductHelper extends Object + { + + const PRODUCT_TAX_GROUP_ID_TARGET = 20; + const PRODUCT_TAX_GROUP_ID_YEAR = 21; + const PRODUCT_TAX_GROUP_ID_SEX = 22; + + const PRODUCT_VARIANT_TYPE_COLOR = 1; + const PRODUCT_VARIANT_TYPE_SIZE = 2; + + public static function getCategories() + { + return Category::find() + ->getTree(); // with('categoryName')-> + } + + public static function getBrands() + { + return Brand::find(); // ->with('brandName') + } + + /* + * Return custom filter-option link + * @var array $filter + * @var array $options + * @return array + */ + public static function getFilterForOption($filter, $key, $value, $remove = false) + { + $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) { + $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; + } } } + return $result; } - return $result; - } - - public static function addLastProsucts($product_id) { - $last_products = self::getLastProducts(); - if (!in_array($product_id, $last_products)) { - $last_products[] = intval($product_id); - if (count($last_products) > 16) { - array_shift($last_products); + + public static function addLastProsucts($product_id) + { + $last_products = self::getLastProducts(); + if(!in_array($product_id, $last_products)) { + $last_products[] = intval($product_id); + if(count($last_products) > 16) { + array_shift($last_products); + } + Yii::$app->session->set('last_products', $last_products); } - Yii::$app->session->set('last_products', $last_products); - } - } - - public static function getLastProducts($as_object = false) { - $last_products = Yii::$app->session->get('last_products', []); - if ($as_object) { - $last_products = Product::find()->joinWith(['variant'])->where([Product::tableName() .'.product_id' => $last_products])->andWhere(['!=', ProductVariant::tableName() .'.stock', 0])->all(); } - return array_reverse($last_products); - } - - public static function getSpecialProducts($type, $count, $sort = null) { - switch($type) { - case 'top': - $data = ['is_top' => true]; - break; - case 'new': - $data = ['is_new' => true]; - break; - case 'promo': - $data = ['akciya' => true]; - break; - } - return Product::find()->joinWith('variants')->where($data)->andWhere(['!=', ProductVariant::tableName() .'.stock', 0])->limit($count)/*->orderBy($sort)*/->all(); - } - - public static function getSimilarProducts($product, $count = 10) { - if (!is_object($product)) { - $product = Product::find()->where(['product_id'=>$product])->with('enabledVariants')->one(); - } - - if (!$product->properties) { - return []; + + public static function getLastProducts($as_object = false) + { + $last_products = Yii::$app->session->get('last_products', [ ]); + if($as_object) { + $last_products = Product::find() + ->joinWith([ 'variant' ]) + ->where([ Product::tableName() . '.product_id' => $last_products ]) + ->andWhere([ + '!=', + ProductVariant::tableName() . '.stock', + 0, + ]) + ->all(); + } + return array_reverse($last_products); } - $product_categories = []; - foreach ($product->categories as $category) { - $product_categories[] = $category->category_id; + + public static function getSpecialProducts($type, $count, $sort = NULL) + { + switch($type) { + case 'top': + $data = [ 'is_top' => true ]; + break; + case 'new': + $data = [ 'is_new' => true ]; + break; + case 'promo': + $data = [ 'akciya' => true ]; + break; + } + return Product::find() + ->joinWith('variants') + ->where($data) + ->andWhere([ + '!=', + ProductVariant::tableName() . '.stock', + 0, + ]) + ->limit($count)/*->orderBy($sort)*/ + ->all(); } - $query = Product::find() - ->select('product.product_id') - ->innerJoinWith('variant') - ->joinWith('category') - ->where(['!=', 'product_variant.stock', 0]) - ->andWhere(['product_category.category_id' => $product_categories]); -// $query->andWhere(['>=', 'product_variant.price', $product->enabledVariant->price * 0.7]); -// $query->andWhere(['<=', 'product_variant.price', $product->enabledVariant->price * 1.3]); - foreach($product->properties as $group) { - $where = []; - foreach ($group->_options as $option) { - $where[] = $option->tax_option_id; + + public static function getSimilarProducts($product, $count = 10) + { + if(!is_object($product)) { + $product = Product::find() + ->where([ 'product_id' => $product ]) + ->with('enabledVariants') + ->one(); } - if (!$where) { - continue; + + if(!$product->properties) { + return [ ]; } - $query->innerJoin('product_option to'. $group->tax_group_id, 'to'. $group->tax_group_id .'.product_id = product.product_id'); - $query->andWhere(['to'. $group->tax_group_id .'.option_id' => $where]); - } - $query->andWhere(['!=', 'product.product_id', $product->product_id]); - $query->groupBy('product.product_id'); - $query->limit($count); - $products = $query->asArray()->all(); - foreach ($products as &$_product) { - $_product = Product::findOne($_product['product_id']); - } - return $products; - } - - - - public static function _setQueryParams(&$query, $params, $setPriceLimits = true) { - if (!empty($params['keywords'])) { - if (!is_array($params['keywords'])) { - $params['keywords'] = [$params['keywords']]; + $product_categories = [ ]; + foreach($product->categories as $category) { + $product_categories[] = $category->category_id; } - foreach ($params['keywords'] as $keyword) { - $query->orFilterWhere(['ilike', Product::tableName() .'.name', $keyword]); - $query->orFilterWhere(['ilike', BrandName::tableName() .'.value', $keyword]); - $query->orFilterWhere(['ilike', CategoryName::tableName() .'.value', $keyword]); - $query->orFilterWhere(['ilike', ProductVariant::tableName() .'.sku', $keyword]); + $query = Product::find() + ->select('product.product_id') + ->innerJoinWith('variant') + ->joinWith('category') + ->where([ + '!=', + 'product_variant.stock', + 0, + ]) + ->andWhere([ 'product_category.category_id' => $product_categories ]); + // $query->andWhere(['>=', 'product_variant.price', $product->enabledVariant->price * 0.7]); + // $query->andWhere(['<=', 'product_variant.price', $product->enabledVariant->price * 1.3]); + foreach($product->properties as $group) { + $where = [ ]; + foreach($group->_options as $option) { + $where[] = $option->tax_option_id; + } + if(!$where) { + continue; + } + $query->innerJoin('product_option to' . $group->tax_group_id, 'to' . $group->tax_group_id . '.product_id = product.product_id'); + $query->andWhere([ 'to' . $group->tax_group_id . '.option_id' => $where ]); } - } - - foreach($params as $key => $param){ - - switch ($key) { - case 'special': - foreach($param as $key => $value) { - $query->orFilterWhere([Product::tableName() .'.'. $key => $value]); - } - break; - case 'brands': - $query->andFilterWhere([Product::tableName() .'.brand_id' => $param]); - break; - case 'keywords': - break; - case 'prices': - if ($param['min'] > 0) { - $query->andWhere(['>=', ProductVariant::tableName() .'.price', $param['min']]); - } - if ($param['max'] > 0) { - $query->andWhere(['<=', ProductVariant::tableName() .'.price', $param['max']]); - } - break; - default: - $query->andWhere( - Product::tableName() . '.product_id IN (SELECT product_id AS products FROM product_option INNER JOIN tax_option ON tax_option.tax_option_id = product_option.option_id INNER JOIN tax_group ON tax_group.tax_group_id = tax_option.tax_group_id WHERE tax_group.alias LIKE \''. $key .'\' AND tax_option.alias IN (\'' . implode('\',\'', $param) . '\'))' - ); + $query->andWhere([ + '!=', + 'product.product_id', + $product->product_id, + ]); + $query->groupBy('product.product_id'); + $query->limit($count); + $products = $query->asArray() + ->all(); + foreach($products as &$_product) { + $_product = Product::findOne($_product[ 'product_id' ]); } - + return $products; } - - } - - public static function productCountQuery($category = null, $params, $excludeKeys = []) { - $p = []; - foreach ($params as $key => $param) { - if (in_array($key, $excludeKeys)) { - $p[$key] = $param; + + /** + * @param ActiveQuery $query + * @param $params + * @param bool $setPriceLimits + */ + public static function _setQueryParams(&$query, $params, $setPriceLimits = true) + { + if(!empty( $params[ 'keywords' ] )) { + if(!is_array($params[ 'keywords' ])) { + $params[ 'keywords' ] = [ $params[ 'keywords' ] ]; + } + foreach($params[ 'keywords' ] as $keyword) { + $query->orFilterWhere([ + 'ilike', + Product::tableName() . '.name', + $keyword, + ]); + $query->orFilterWhere([ + 'ilike', + BrandName::tableName() . '.value', + $keyword, + ]); + $query->orFilterWhere([ + 'ilike', + CategoryName::tableName() . '.value', + $keyword, + ]); + $query->orFilterWhere([ + 'ilike', + ProductVariant::tableName() . '.sku', + $keyword, + ]); + } + } + + foreach($params as $key => $param) { + + switch($key) { + case 'special': + foreach($param as $key => $value) { + $query->orFilterWhere([ Product::tableName() . '.' . $key => $value ]); + } + break; + case 'brands': + $query->andFilterWhere([ Product::tableName() . '.brand_id' => $param ]); + break; + case 'keywords': + break; + case 'prices': + if($param[ 'min' ] > 0) { + $query->andWhere([ + '>=', + ProductVariant::tableName() . '.price', + $param[ 'min' ], + ]); + } + if($param[ 'max' ] > 0) { + $query->andWhere([ + '<=', + ProductVariant::tableName() . '.price', + $param[ 'max' ], + ]); + } + break; + default: + $query->andWhere( + Product::tableName() . '.product_id IN ( + SELECT DISTINCT products + FROM ( + SELECT product_id AS products + FROM product_option + INNER JOIN tax_option ON tax_option.tax_option_id = product_option.option_id + INNER JOIN tax_group ON tax_group.tax_group_id = tax_option.tax_group_id + WHERE tax_group.alias LIKE \''. $key .'\' AND tax_option.alias IN (\'' . implode('\',\'', $param) . '\') OR product_id IN ( + (SELECT product_id AS products + FROM product_variant_option + INNER JOIN product_variant ON product_variant_option.product_variant_id = product_variant.product_variant_id + INNER JOIN tax_option ON tax_option.tax_option_id = product_variant_option.option_id + INNER JOIN tax_group ON tax_group.tax_group_id = tax_option.tax_group_id + WHERE tax_group.alias LIKE \''. $key .'\' AND tax_option.alias IN (\'' . implode('\',\'', $param) . '\')) + ) + ) AS table_name + )' + ); + } + } + } - /** @var ActiveQuery $query */ - if (!empty($category)) { - $query = $category->getProducts(); - } else { - $query = Product::find(); + + public static function productCountQuery($category = NULL, $params, $excludeKeys = [ ]) + { + $p = [ ]; + foreach($params as $key => $param) { + if(in_array($key, $excludeKeys)) { + $p[ $key ] = $param; + } + } + /** @var ActiveQuery $query */ + if(!empty( $category )) { + $query = $category->getProducts(); + } else { + $query = Product::find(); + } + ProductHelper::_setQueryParams($query, $params); + $query->select([ 'COUNT(product.product_id)' ]); + + return $query; } - ProductHelper::_setQueryParams($query, $params); - $query->select(['COUNT(product.product_id)']); - - return $query; - } -} \ No newline at end of file + } \ No newline at end of file diff --git a/common/modules/product/models/Category.php b/common/modules/product/models/Category.php index 6dd0781..b692114 100755 --- a/common/modules/product/models/Category.php +++ b/common/modules/product/models/Category.php @@ -10,6 +10,7 @@ use common\modules\rubrication\behaviors\ArtboxSynonymBehavior; use common\modules\rubrication\models\TaxGroup; use Yii; use yii\base\ErrorException; +use yii\db\Query; /** * This is the model class for table "category". @@ -225,5 +226,57 @@ class Category extends \yii\db\ActiveRecord CategoryName::deleteAll(['category_id' => $this->category_id]); return true; } + + public function getActiveFilters() { + $query1 = (new Query()) + ->distinct() + ->select([ + 'option_id', + 'tax_option.*', + 'tax_group.*', + 'tax_option.alias as option_alias', + 'tax_group.alias as group_alias', + 'tax_value_string.value as value', + 'tax_option.sort AS tax_option_sort', + 'tax_group.sort AS tax_group_sort', + ]) + ->from('tax_option') + ->innerJoin('product_variant_option', 'tax_option.tax_option_id = product_variant_option.option_id') + ->innerJoin('tax_group', 'tax_group.tax_group_id = tax_option.tax_group_id') + ->innerJoin('product_variant', 'product_variant.product_variant_id = product_variant_option.product_variant_id') + ->innerJoin('product', 'product.product_id = product_variant.product_id') + ->innerJoin('product_category', 'product_category.product_id = product.product_id') + ->innerJoin('tax_value_string', 'tax_value_string.tax_option_id = tax_option.tax_option_id') + ->where(['product_category.category_id' => $this->category_id]) + ->andWhere(['!=', 'product_variant.stock', 0]); + + $query2 = (new Query()) + ->distinct() + ->select([ + 'option_id', + 'tax_option.*', + 'tax_group.*', + 'tax_option.alias as option_alias', + 'tax_group.alias as group_alias', + 'tax_value_string.value as value', + 'tax_option.sort AS tax_option_sort', + 'tax_group.sort AS tax_group_sort', + ]) + ->from('tax_option') + ->innerJoin('product_option', 'tax_option.tax_option_id = product_option.option_id') + ->innerJoin('tax_group', 'tax_group.tax_group_id = tax_option.tax_group_id') + ->innerJoin('product', 'product.product_id = product_option.product_id') + ->innerJoin('product_category', 'product_category.product_id = product.product_id') + ->innerJoin('product_variant', 'product_variant.product_id = product.product_id') + ->innerJoin('tax_value_string', 'tax_value_string.tax_option_id = tax_option.tax_option_id') + ->where(['product_category.category_id' => $this->category_id]) + ->andWhere(['!=', 'product_variant.stock', 0]) + ->orderBy('tax_group_sort, tax_option_sort'); + $query3 = (new Query()) + ->select('*') + ->from(['subquery' => $query1->union($query2)]) + ->orderBy('tax_group_sort, tax_option_sort'); + return $query3; + } } diff --git a/common/modules/product/models/Product.php b/common/modules/product/models/Product.php index 125ace4..daa7958 100755 --- a/common/modules/product/models/Product.php +++ b/common/modules/product/models/Product.php @@ -262,6 +262,20 @@ class Product extends \yii\db\ActiveRecord } return $groups; } + + public function getActiveProperties() { + $groups = $options = []; + foreach ($this->options as $option) { + $options[$option->tax_group_id][] = $option; + } + foreach (TaxGroup::find()->where(['tax_group_id' => array_keys($options), 'display' => TRUE])->all() as $group) { + if (!empty($options[$group->tax_group_id])) { + $group->_options = $options[$group->tax_group_id]; + $groups[] = $group; + } + } + return $groups; + } public function getStocks() { return $this->hasMany(Stock::className(), ['stock_id' => 'stock_id'])->viaTable(ProductStock::tableName(), ['product_id' => 'product_id']); diff --git a/common/modules/rubrication/models/TaxGroup.php b/common/modules/rubrication/models/TaxGroup.php index 0f1ec51..ca4f842 100755 --- a/common/modules/rubrication/models/TaxGroup.php +++ b/common/modules/rubrication/models/TaxGroup.php @@ -17,6 +17,8 @@ use Yii; * @property string $settings * @property boolean $is_filter * @property integer $level + * @property integer $sort + * @property boolean $display * @property TaxGroupToGroup[] $taxGroupToGroups * @property TaxGroupToGroup[] $taxGroupToGroups0 * @property TaxOption[] $taxOptions @@ -62,8 +64,8 @@ class TaxGroup extends \yii\db\ActiveRecord return [ [['name', 'module'], 'required'], [['description', 'settings'], 'string'], - [['hierarchical', 'is_filter'], 'boolean'], - [['level'], 'integer'], + [['hierarchical', 'is_filter', 'display'], 'boolean'], + [['level', 'sort'], 'integer'], [['alias', 'module'], 'string', 'max' => 50], [['name'], 'string', 'max' => 255], [['group_to_category'], 'safe'] @@ -84,6 +86,8 @@ class TaxGroup extends \yii\db\ActiveRecord 'hierarchical' => 'Hierarchical', // 'settings' => 'Settings', 'is_filter' => 'Use in filter', + 'sort' => 'Sort', + 'display' => 'Display', ]; } diff --git a/common/modules/rubrication/views/tax-group/_form.php b/common/modules/rubrication/views/tax-group/_form.php index 689d32f..d2b44e7 100755 --- a/common/modules/rubrication/views/tax-group/_form.php +++ b/common/modules/rubrication/views/tax-group/_form.php @@ -35,6 +35,10 @@ use common\components\artboxtree\ArtboxTreeHelper; field($model, 'hierarchical')->checkbox()*/ ?> = $form->field($model, 'is_filter')->checkbox() ?> + + = $form->field($model, 'display')->checkbox() ?> + + = $form->field($model, 'sort')->textInput() ?>
Бренд: = $product->brand->name ?>
- properties as $group): ?> + activeProperties as $group): ?>= $group->name ?> _options as $option) : ?> = $option->ValueRenderHTML ?>