Commit 6fa713cab9dd74a8008022c7b7703bb1099e8b30
1 parent
7450652a
Catalog v 1.2
Showing
20 changed files
with
1165 additions
and
454 deletions
Show diff stats
.gitignore
common/components/artboxtree/ArtboxTreeBehavior.php
... | ... | @@ -102,6 +102,7 @@ class ArtboxTreeBehavior extends Behavior { |
102 | 102 | return $this->buildTree($query->all(), $this->owner->getAttribute($this->keyNameId)); |
103 | 103 | } |
104 | 104 | |
105 | + // @todo Check algorytm | |
105 | 106 | public function buildTree(array $data, $parentId = 0) { |
106 | 107 | $result = []; |
107 | 108 | foreach ($data as $key => $element) { | ... | ... |
common/config/main.php
... | ... | @@ -116,7 +116,7 @@ return [ |
116 | 116 | 'entity2' => [ |
117 | 117 | 'model' => '\common\modules\rubrication\models\TaxOption', |
118 | 118 | 'label' => 'Option', |
119 | - 'listField' => 'ValueeRenderFlash', | |
119 | + 'listField' => 'ValueRenderFlash', | |
120 | 120 | 'key' => 'tax_option_id', |
121 | 121 | 'linked_key' => 'option_id', |
122 | 122 | ], | ... | ... |
common/models/ProductVariant.php deleted
1 | -<?php | |
2 | - | |
3 | -namespace common\models; | |
4 | - | |
5 | -use Yii; | |
6 | - | |
7 | -/** | |
8 | - * This is the model class for table "product_variant". | |
9 | - * | |
10 | - * @property integer $product_variant_id | |
11 | - * @property integer $product_id | |
12 | - * @property string $name | |
13 | - * @property string $sku | |
14 | - * @property double $price | |
15 | - * @property double $price_old | |
16 | - * @property double $stock | |
17 | - * @property integer $product_unit_id | |
18 | - * | |
19 | - * @property OrderItems[] $orderItems | |
20 | - * @property ProductUnit $productUnit | |
21 | - */ | |
22 | -class ProductVariant extends \yii\db\ActiveRecord | |
23 | -{ | |
24 | - /** | |
25 | - * @inheritdoc | |
26 | - */ | |
27 | - public static function tableName() | |
28 | - { | |
29 | - return 'product_variant'; | |
30 | - } | |
31 | - | |
32 | - /** | |
33 | - * @inheritdoc | |
34 | - */ | |
35 | - public function rules() | |
36 | - { | |
37 | - return [ | |
38 | - [['product_id', 'sku'], 'required'], | |
39 | - [['product_id', 'product_unit_id'], 'integer'], | |
40 | - [['price', 'price_old', 'stock'], 'number'], | |
41 | - [['name', 'sku'], 'string', 'max' => 255], | |
42 | - [['product_unit_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductUnit::className(), 'targetAttribute' => ['product_unit_id' => 'product_unit_id']], | |
43 | - ]; | |
44 | - } | |
45 | - | |
46 | - /** | |
47 | - * @inheritdoc | |
48 | - */ | |
49 | - public function attributeLabels() | |
50 | - { | |
51 | - return [ | |
52 | - 'product_variant_id' => Yii::t('app', 'Product Variant ID'), | |
53 | - 'product_id' => Yii::t('app', 'Product ID'), | |
54 | - 'name' => Yii::t('app', 'Name'), | |
55 | - 'sku' => Yii::t('app', 'Sku'), | |
56 | - 'price' => Yii::t('app', 'Price'), | |
57 | - 'price_old' => Yii::t('app', 'Price Old'), | |
58 | - 'stock' => Yii::t('app', 'Stock'), | |
59 | - 'product_unit_id' => Yii::t('app', 'Product Unit ID'), | |
60 | - ]; | |
61 | - } | |
62 | - | |
63 | - /** | |
64 | - * @return \yii\db\ActiveQuery | |
65 | - */ | |
66 | - public function getOrderItems() | |
67 | - { | |
68 | - return $this->hasMany(OrderItems::className(), ['item_id' => 'product_variant_id']); | |
69 | - } | |
70 | - | |
71 | - /** | |
72 | - * @return \yii\db\ActiveQuery | |
73 | - */ | |
74 | - public function getProductUnit() | |
75 | - { | |
76 | - return $this->hasOne(ProductUnit::className(), ['product_unit_id' => 'product_unit_id']); | |
77 | - } | |
78 | -} |
1 | +<?php | |
2 | + | |
3 | +namespace common\modules\product; | |
4 | + | |
5 | +use common\modules\product\models\Brand; | |
6 | +use common\modules\product\models\CategorySearch; | |
7 | +use common\modules\product\models\ProductSearch; | |
8 | +use common\modules\rubrication\models\TaxOption; | |
9 | +use Yii; | |
10 | +use yii\helpers\Url; | |
11 | +use yii\web\UrlRuleInterface; | |
12 | + | |
13 | +class CatalogUrlManager implements UrlRuleInterface { | |
14 | + public $route_map = []; | |
15 | + | |
16 | + public $option_prefix = 'o:'; | |
17 | + /** | |
18 | + * Parses the given request and returns the corresponding route and parameters. | |
19 | + * @param \yii\web\UrlManager $manager the URL manager | |
20 | + * @param \yii\web\Request $request the request component | |
21 | + * @return array|boolean the parsing result. The route and the parameters are returned as an array. | |
22 | + * If false, it means this rule cannot be used to parse this path info. | |
23 | + */ | |
24 | + public function parseRequest($manager, $request) | |
25 | + { | |
26 | + $pathInfo = $request->getPathInfo(); | |
27 | + $paths = explode('/', $pathInfo); | |
28 | + | |
29 | + if (!array_key_exists($paths[0], $this->route_map)) { | |
30 | + return false; | |
31 | + } | |
32 | + | |
33 | + $params = []; | |
34 | + if ($paths[0] == 'catalog') { | |
35 | + $route = 'catalog/category'; | |
36 | + // Category | |
37 | + if (!empty($paths[1])) { | |
38 | + $category = CategorySearch::findByAlias($paths[1]); | |
39 | + if (empty($category)) { | |
40 | + http_redirect(Url::to(['/'])); | |
41 | + } | |
42 | + $params['category'] = $category; | |
43 | + } | |
44 | + // Filter | |
45 | + if (!empty($paths[2])) { | |
46 | + if (strpos($paths[2], 'filter:') === 0) { | |
47 | + $params['filter'] = []; | |
48 | + $filter_str = substr($paths[2], 7); | |
49 | + $filter_options = explode(';', $filter_str); | |
50 | + foreach ($filter_options as $filter_option) { | |
51 | + if (empty($filter_option)) { | |
52 | + continue; | |
53 | + } | |
54 | + list($filter_key, $filter_option) = explode('=', $filter_option); | |
55 | + if($filter_key == 'prices') { // price-interval section | |
56 | + $prices = explode(':', $filter_option); | |
57 | + $params['filter'][$filter_key] = [ | |
58 | + 'min' => floatval($prices[0]), | |
59 | + 'max' => floatval($prices[1]), | |
60 | + ]; | |
61 | + } elseif (strpos($filter_key, $this->option_prefix) === 0) { // options section | |
62 | + $params['filter']['options'][substr($filter_key, 2)] = explode(',', $filter_option); | |
63 | + } else { // brands and other sections | |
64 | + $params['filter'][$filter_key] = explode(',', $filter_option); | |
65 | + } | |
66 | + | |
67 | + } | |
68 | + } | |
69 | + } | |
70 | + } elseif ($paths[0] == 'product') { | |
71 | + $product = ProductSearch::findByAlias($paths[1]); | |
72 | + if (empty($product->product_id)) { | |
73 | + throw new HttpException(404 ,'Page not found'); | |
74 | + } | |
75 | + $route = 'catalog/product'; | |
76 | + $params = [ | |
77 | + 'product' => $product, | |
78 | + ]; | |
79 | + } elseif ($paths[0] == 'brand') { | |
80 | + | |
81 | + } | |
82 | + | |
83 | + return [$route, $params]; | |
84 | + } | |
85 | + /** | |
86 | + * Creates a URL according to the given route and parameters. | |
87 | + * @param \yii\web\UrlManager $manager the URL manager | |
88 | + * @param string $route the route. It should not have slashes at the beginning or the end. | |
89 | + * @param array $params the parameters | |
90 | + * @return string|boolean the created URL, or false if this rule cannot be used for creating this URL. | |
91 | + */ | |
92 | + public function createUrl($manager, $route, $params) | |
93 | + { | |
94 | + if (!in_array($route, $this->route_map)) { | |
95 | + return false; | |
96 | + } | |
97 | + | |
98 | + switch($route) { | |
99 | + case 'catalog/category': | |
100 | + if (!empty($params['category'])) { | |
101 | + $category_alias = is_object($params['category']) ? $params['category']->alias : strtolower($params['category']); | |
102 | + } | |
103 | + $url = 'catalog/'. $category_alias .'/'; | |
104 | + | |
105 | + $filter = []; | |
106 | + if (!empty($params['filter'])) { | |
107 | + foreach ($params['filter'] as $key => $values) { | |
108 | + switch($key) { | |
109 | + case 'prices': | |
110 | + $filter[] = $key .'='. implode(':', $values); | |
111 | + break; | |
112 | + | |
113 | + case 'options': | |
114 | + foreach($values as $group => &$value_items) { | |
115 | + foreach($value_items as &$value_item) { | |
116 | + $value_item = $this->option_value_encode($value_item); | |
117 | + if (empty($value_item)) { | |
118 | + unset($value_item); | |
119 | + } | |
120 | + } | |
121 | + $filter[] = $this->option_prefix. $group .'='. implode(',', $value_items); | |
122 | + } | |
123 | + break; | |
124 | + | |
125 | + default: | |
126 | + foreach($values as &$value) { | |
127 | + $value = $this->option_value_encode($value); | |
128 | + if (empty($value)) { | |
129 | + unset($value); | |
130 | + } | |
131 | + } | |
132 | + $filter[] = $key .'='. implode(',', $values); | |
133 | + break; | |
134 | + } | |
135 | + } | |
136 | + $url .= 'filter:'. implode(';', $filter); | |
137 | + } | |
138 | + return $url; | |
139 | + break; | |
140 | + | |
141 | + case 'catalog/product': | |
142 | + if (!empty($params['product'])) { | |
143 | + $product_alias = is_object($params['product']) ? $params['product']->alias : strtolower($params['product']); | |
144 | + } | |
145 | + $url = 'product/'. $product_alias; | |
146 | + return $url; | |
147 | + break; | |
148 | + } | |
149 | + } | |
150 | + | |
151 | + private function option_value_encode($value) { | |
152 | + return str_replace(array(',', '/'), array('~', '&s;'), $value); | |
153 | + } | |
154 | +} | |
0 | 155 | \ No newline at end of file | ... | ... |
common/modules/product/helpers/ProductHelper.php
... | ... | @@ -14,4 +14,45 @@ class ProductHelper extends Object { |
14 | 14 | public static function getBrands() { |
15 | 15 | return Brand::find()->with('brandName'); |
16 | 16 | } |
17 | + | |
18 | + /* | |
19 | + * Return custom filter-option link | |
20 | + * @var array $filter | |
21 | + * @var array $options | |
22 | + * @return array | |
23 | + */ | |
24 | + public static function getFilterForOption($filter, $key, $value, $remove = false) { | |
25 | + $result = $filter; | |
26 | + if (is_array($value)) { | |
27 | + foreach($value as $value_key => $value_items) { | |
28 | + if (!is_array($value_items)) { | |
29 | + $value_items = [$value_items]; | |
30 | + } | |
31 | + foreach($value_items as $value_item) { | |
32 | + if ($remove && isset($result[$key]) && ($i = array_search($value_item, $result[$key][$value_key])) !== FALSE) { | |
33 | + unset($result[$key][$value_key][$i]); | |
34 | + if (empty($result[$key][$value_key])) { | |
35 | + unset($result[$key][$value_key]); | |
36 | + } | |
37 | + } else { | |
38 | + if (!isset($result[$key][$value_key]) || array_search($value_item, $result[$key][$value_key]) === FALSE) { | |
39 | + $result[$key][$value_key][] = $value_item; | |
40 | + } | |
41 | + } | |
42 | + } | |
43 | + } | |
44 | + } else { | |
45 | + if ($remove && isset($result[$key]) && ($i = array_search($value, $result[$key])) !== FALSE) { | |
46 | + unset($result[$key][$i]); | |
47 | + if (empty($result[$key])) { | |
48 | + unset($result[$key]); | |
49 | + } | |
50 | + } else { | |
51 | + if (!isset($result[$key]) || array_search($value, $result[$key]) === FALSE) { | |
52 | + $result[$key][] = $value; | |
53 | + } | |
54 | + } | |
55 | + } | |
56 | + return $result; | |
57 | + } | |
17 | 58 | } |
18 | 59 | \ No newline at end of file | ... | ... |
common/modules/product/models/BrandSearch.php
... | ... | @@ -72,4 +72,40 @@ class BrandSearch extends Brand |
72 | 72 | |
73 | 73 | return $dataProvider; |
74 | 74 | } |
75 | + | |
76 | + public function getBrands($category, $params) { | |
77 | + $query = Brand::find() | |
78 | + ->select([ | |
79 | + Brand::tableName() .'.*', | |
80 | + 'COUNT('. ProductCategory::tableName() .'.product_id) AS _items_count' | |
81 | + ]) | |
82 | + ->innerJoin(Product::tableName(), Product::tableName() .'.brand_id='. Brand::tableName() .'.brand_id') | |
83 | + ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. Product::tableName() .'.product_id') | |
84 | + | |
85 | + ->with('brandName') | |
86 | + ->where([ | |
87 | + ProductCategory::tableName() .'.category_id' => $category->category_id | |
88 | + ]) | |
89 | + ->groupBy(Brand::tableName() .'.brand_id'); | |
90 | + if (isset($params['options'])) { | |
91 | + unset($params['options']); | |
92 | + } | |
93 | + if (!empty($params['prices'])) { | |
94 | + if ($params['prices']['min'] > 0 || $params['prices']['max'] > 0) { | |
95 | + $query->innerJoin(ProductVariant::tableName(), ProductVariant::tableName() .'.product_id='. Product::tableName() .'.product_id'); | |
96 | + } | |
97 | + if ($params['prices']['min'] > 0) { | |
98 | + $query->andWhere(['>=', ProductVariant::tableName() .'.price', $params['prices']['min']]); | |
99 | + } | |
100 | + if ($params['prices']['max'] > 0) { | |
101 | + $query->andWhere(['<=', ProductVariant::tableName() .'.price', $params['prices']['max']]); | |
102 | + } | |
103 | + } | |
104 | + | |
105 | + $dataProvider = new ActiveDataProvider([ | |
106 | + 'query' => $query, | |
107 | + ]); | |
108 | + | |
109 | + return $dataProvider; | |
110 | + } | |
75 | 111 | } | ... | ... |
common/modules/product/widgets/views/submenu.php
1 | 1 | <div class="menu_item"> |
2 | - <?= \yii\helpers\Html::a($rootCategory->categoryName->value, ['catalog/category', 'alias' => $rootCategory->alias], ['class' => 'submenu_button '. $rootClass])?> | |
2 | + <?= \yii\helpers\Html::a($rootCategory->categoryName->value, ['catalog/category', 'category' => $rootCategory], ['class' => 'submenu_button '. $rootClass])?> | |
3 | 3 | <div class="submenu"> |
4 | 4 | <ul class="categories"> |
5 | 5 | <li class="sub_cat"><span>Популярные категории</span> |
... | ... | @@ -7,7 +7,7 @@ |
7 | 7 | <div class="sub_cat_content"> |
8 | 8 | <div class="content_items"> |
9 | 9 | <?php foreach($populary as $_item) :?> |
10 | - <div class="content_item"><a href="<?= \yii\helpers\Url::to(['catalog/category', 'alias' => $_item->alias])?>"> | |
10 | + <div class="content_item"><a href="<?= \yii\helpers\Url::to(['catalog/category', 'category' => $_item])?>"> | |
11 | 11 | <div valign="top" class="picture"> |
12 | 12 | <?php if (empty($_item->image)) :?> |
13 | 13 | <img valign="top" src="/images/no_photo.png"> |
... | ... | @@ -29,7 +29,7 @@ |
29 | 29 | <div class="sub_cat_content"> |
30 | 30 | <div class="content_items"> |
31 | 31 | <?php foreach($item['children'] as $_item) :?> |
32 | - <div class="content_item"><a href="<?= \yii\helpers\Url::to(['/catalog/category', 'alias' => $_item['item']->alias])?>"> | |
32 | + <div class="content_item"><a href="<?= \yii\helpers\Url::to(['catalog/category', 'category' => $_item['item']])?>"> | |
33 | 33 | <div valign="top" class="picture"> |
34 | 34 | <?php if (empty($_item['item']->image)) :?> |
35 | 35 | <img valign="top" src="/images/no_photo.png"> | ... | ... |
common/modules/rubrication/models/TaxGroup.php
... | ... | @@ -15,6 +15,7 @@ use Yii; |
15 | 15 | * @property string $module |
16 | 16 | * @property boolean $hierarchical |
17 | 17 | * @property string $settings |
18 | + * @property boolean is_filter | |
18 | 19 | * |
19 | 20 | * @property TaxGroupToGroup[] $taxGroupToGroups |
20 | 21 | * @property TaxGroupToGroup[] $taxGroupToGroups0 |
... | ... | @@ -81,6 +82,7 @@ class TaxGroup extends \yii\db\ActiveRecord |
81 | 82 | 'module' => 'Module', |
82 | 83 | 'hierarchical' => 'Hierarchical', |
83 | 84 | // 'settings' => 'Settings', |
85 | + 'is_filter' => 'Use in filter', | |
84 | 86 | ]; |
85 | 87 | } |
86 | 88 | ... | ... |
frontend/config/main.php
... | ... | @@ -47,11 +47,20 @@ return [ |
47 | 47 | 'enablePrettyUrl' => true, |
48 | 48 | 'showScriptName' => false, |
49 | 49 | 'rules' => [ |
50 | -// 'catalog' => 'catalog/category', | |
51 | - 'catalog/<alias:[A-Za-z0-9_-]+>' => 'catalog/category', | |
52 | - 'product/<alias:[A-Za-z0-9_-]+>' => 'catalog/product', | |
53 | - 'brand' => 'catalog/brands', | |
54 | - 'brand/<alias:[A-Za-z0-9_-]+>' => 'catalog/brand', | |
50 | + [ | |
51 | + 'class' => '\common\modules\product\CatalogUrlManager', | |
52 | + 'route_map' => [ | |
53 | + 'catalog' => 'catalog/category', | |
54 | + 'product' => 'catalog/product', | |
55 | + 'brand' => 'catalog/brand', | |
56 | + ] | |
57 | + ], | |
58 | +//// 'catalog' => 'catalog/category', | |
59 | +// 'catalog/<alias:[A-Za-z0-9_-]+>' => 'catalog/category', | |
60 | +// 'catalog/<alias:[A-Za-z0-9_-]+>/<filter>' => 'catalog/category', | |
61 | +// 'product/<alias:[A-Za-z0-9_-]+>' => 'catalog/product', | |
62 | +// 'brand' => 'catalog/brands', | |
63 | +// 'brand/<alias:[A-Za-z0-9_-]+>' => 'catalog/brand', | |
55 | 64 | ] |
56 | 65 | ] |
57 | 66 | ... | ... |
1 | +<?php | |
2 | + | |
3 | +namespace frontend\controllers; | |
4 | + | |
5 | +use common\modules\product\models\Brand; | |
6 | +use common\modules\product\models\Category; | |
7 | +use common\modules\product\models\CategorySearch; | |
8 | +use common\modules\product\models\Product; | |
9 | +use common\modules\product\models\ProductCategory; | |
10 | +use common\modules\product\models\ProductOption; | |
11 | +use common\modules\product\models\ProductSearch; | |
12 | +use common\modules\product\models\ProductVariant; | |
13 | +use common\modules\rubrication\models\TaxGroup; | |
14 | +use common\modules\rubrication\models\TaxOption; | |
15 | +use common\modules\rubrication\models\TaxValueString; | |
16 | +use yii\data\ActiveDataProvider; | |
17 | +use yii\data\Pagination; | |
18 | +use yii\data\Sort; | |
19 | +use yii\db\ActiveQuery; | |
20 | +use yii\web\HttpException; | |
21 | + | |
22 | +class CatalogController extends \yii\web\Controller | |
23 | +{ | |
24 | + public function actionSearch() { | |
25 | + | |
26 | + } | |
27 | + | |
28 | + public function actionCategory($alias) | |
29 | + { | |
30 | + $category = CategorySearch::findByAlias($alias); | |
31 | + if (empty($category->category_id)) { | |
32 | + throw new HttpException(404 ,'Page not found'); | |
33 | + } | |
34 | + if ($category->depth < 2) { | |
35 | + return $this->render( | |
36 | + 'categories', | |
37 | + [ | |
38 | + 'category' => $category | |
39 | + ] | |
40 | + ); | |
41 | + } else { | |
42 | + $per_page = 24; | |
43 | + | |
44 | + $sort = new Sort([ | |
45 | + 'attributes' => [ | |
46 | + 'name' => [ | |
47 | + 'asc' => ['name' => SORT_ASC], | |
48 | + 'desc' => ['name' => SORT_DESC], | |
49 | + 'default' => SORT_DESC, | |
50 | + 'label' => 'имени', | |
51 | + ], | |
52 | + 'price' => [ | |
53 | + 'asc' => [ProductVariant::tableName() .'.price' => SORT_ASC], | |
54 | + 'desc' => [ProductVariant::tableName() .'.price' => SORT_DESC], | |
55 | + 'default' => SORT_DESC, | |
56 | + 'label' => 'цене', | |
57 | + ], | |
58 | + ], | |
59 | + ]); | |
60 | + /** @var ActiveQuery $query */ | |
61 | + $query = $category->getRelations('product_categories') | |
62 | + ->joinWith([ | |
63 | + 'variants' | |
64 | + ]); | |
65 | + $all_count = $query->count(); | |
66 | + | |
67 | + $brandsQuery = Brand::find() | |
68 | + ->innerJoinWith('brandName') | |
69 | + ->innerJoinWith('products') | |
70 | + ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. Product::tableName() .'.product_id') | |
71 | + ->where([ | |
72 | + ProductCategory::tableName() .'.category_id' => $category->category_id | |
73 | + ]) | |
74 | + ->groupBy(Brand::tableName() .'.brand_id'); | |
75 | + $brands = $brandsQuery->all(); | |
76 | + $brands_count = count($brands); // $brandsQuery->count(); | |
77 | + | |
78 | + $optionsQuery = TaxOption::find() | |
79 | + ->select([ | |
80 | + TaxOption::tableName() .'.*', | |
81 | + 'COUNT('. ProductOption::tableName() .'.product_id) AS _items_count' | |
82 | + ]) | |
83 | + ->innerJoin(ProductOption::tableName(), ProductOption::tableName() .'.option_id='. TaxOption::tableName() .'.tax_option_id') | |
84 | + ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. ProductOption::tableName() .'.product_id') | |
85 | + ->innerJoinWith('group') | |
86 | + ->where([ | |
87 | + ProductCategory::tableName() .'.category_id' => $category->category_id | |
88 | + ]) | |
89 | + ->groupBy(TaxOption::tableName() .'.tax_option_id'); | |
90 | + $all_options = []; | |
91 | + foreach($optionsQuery->all() as $_option) { | |
92 | + $all_options[] = $_option; | |
93 | + } | |
94 | + | |
95 | + $priceQuery = clone $query; | |
96 | + $priceMin = $priceMinCurr = $priceQuery->min(ProductVariant::tableName() .'.price'); | |
97 | + $priceMax = $priceMaxCurr = $priceQuery->max(ProductVariant::tableName() .'.price'); | |
98 | + | |
99 | + // Prices | |
100 | + if (($price_interval = \Yii::$app->request->get('price_interval')) != false) { | |
101 | + $price_interval = explode(';', $price_interval); | |
102 | + $price_interval = [ | |
103 | + floatval($price_interval[0]), | |
104 | + floatval($price_interval[1]), | |
105 | + ]; | |
106 | + if ($price_interval[0] > 0) { | |
107 | + $query->andWhere(['>=', ProductVariant::tableName() .'.price', $price_interval[0]]); | |
108 | + $priceMinCurr = $price_interval[0]; | |
109 | + } | |
110 | + if ($price_interval[1] > 0) { | |
111 | + $query->andWhere(['<=', ProductVariant::tableName() .'.price', $price_interval[1]]); | |
112 | + $priceMaxCurr = $price_interval[1]; | |
113 | + } | |
114 | + } | |
115 | + | |
116 | + $groups = []; | |
117 | + foreach($category->getTaxGroups()->all() as $_group) { | |
118 | + $groups[$_group->tax_group_id] = $_group; | |
119 | + } | |
120 | + foreach ($all_options as $option) { | |
121 | + $groups[$option->tax_group_id]->_options[] = $option; | |
122 | + } | |
123 | + foreach($groups as $i => $group) { | |
124 | + if (empty($group->_options)) | |
125 | + unset($groups[$i]); | |
126 | + } | |
127 | + | |
128 | + // Options | |
129 | + if (($options = \Yii::$app->request->get('option')) != false) { | |
130 | +// $query->innerJoin(ProductOption::tableName(), ProductOption::tableName() .'.product_id='. Product::tableName() .'.product_id'); | |
131 | +// $query->innerJoin(TaxOption::tableName(), TaxOption::tableName() .'.tax_option_id='. ProductOption::tableName() .'.option_id'); | |
132 | + foreach($options as $group_alias => $options_alias) { | |
133 | + if (!is_array($options_alias)) { | |
134 | + $options_alias = [$options_alias]; | |
135 | + } | |
136 | + foreach($options_alias as &$option_alias) { | |
137 | + $option_alias = "'". $option_alias ."'"; | |
138 | + } | |
139 | + /*$group = TaxGroup::find()->where(['like', 'alias', $group_alias])->one(); | |
140 | + if (!$group) { | |
141 | + continue; | |
142 | + }*/ | |
143 | + } | |
144 | + $query->andWhere( | |
145 | + 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 WHERE tax_option.alias IN ('. implode(',', $options_alias) .'))' | |
146 | + ); | |
147 | + } | |
148 | + | |
149 | + if (($_brands = \Yii::$app->request->get('brand')) != false && is_array($_brands) && count($_brands) > 0) { | |
150 | + $_brands = Brand::find()->where(['in', 'alias', $_brands])->all(); | |
151 | + $bids = []; | |
152 | + foreach ($_brands as $brand) { | |
153 | + $bids[] = $brand->brand_id; | |
154 | + } | |
155 | + if (count($bids)) { | |
156 | + $query->andWhere([Product::tableName() .'.brand_id' => $bids]); | |
157 | + } | |
158 | + } | |
159 | + | |
160 | + $query->with('variant'); | |
161 | + $query->with('brand'); | |
162 | + $query->with('categories'); | |
163 | + $query->with('image'); | |
164 | + | |
165 | + $count = $query->count(); | |
166 | + $pages = new Pagination(['totalCount' => $count, 'pageSize' => $per_page]); | |
167 | + $query->offset($pages->offset) | |
168 | + ->orderBy($sort->orders) | |
169 | + ->limit($pages->limit); | |
170 | + | |
171 | + $products = $query->all(); | |
172 | + | |
173 | + return $this->render( | |
174 | + 'products', | |
175 | + [ | |
176 | + 'category' => $category, | |
177 | + 'products' => $products, | |
178 | + 'all_count' => $all_count, | |
179 | + 'product_count' => $count, | |
180 | + 'sort' => $sort, | |
181 | + 'pages' => $pages, | |
182 | + 'per_page' => $per_page, | |
183 | + 'priceMin' => $priceMin, | |
184 | + 'priceMax' => $priceMax, | |
185 | + 'priceMinCurr' => $priceMinCurr, | |
186 | + 'priceMaxCurr' => $priceMaxCurr, | |
187 | + '_brands' => $_brands, | |
188 | + 'brands' => $brands, | |
189 | + 'brands_count' => $brands_count, | |
190 | + 'groups' => $groups, | |
191 | + 'options' => $options, | |
192 | + ] | |
193 | + ); | |
194 | + } | |
195 | + } | |
196 | + | |
197 | + public function actionProduct($alias) | |
198 | + { | |
199 | + $product = ProductSearch::findByAlias($alias); | |
200 | + if (empty($product->product_id)) { | |
201 | + throw new HttpException(404 ,'Page not found'); | |
202 | + } | |
203 | + $groups = []; | |
204 | + foreach($product->category->getTaxGroups()->all() as $_group) { | |
205 | + $groups[$_group->tax_group_id] = $_group; | |
206 | + } | |
207 | + foreach ($product->options as $option) { | |
208 | + $groups[$option->tax_group_id]->_options[] = $option; | |
209 | + } | |
210 | + foreach($groups as $i => $group) { | |
211 | + if (empty($group->_options)) | |
212 | + unset($groups[$i]); | |
213 | + } | |
214 | + | |
215 | + return $this->render('product', [ | |
216 | + 'product' => $product, | |
217 | + 'properties' => $groups, | |
218 | + ]); | |
219 | + } | |
220 | + | |
221 | + public function actionBrands() | |
222 | + { | |
223 | + return 'actionBrands'; | |
224 | + } | |
225 | + | |
226 | + public function actionBrand($alias) | |
227 | + { | |
228 | + return 'actionBrand:'. $alias; | |
229 | + } | |
230 | + | |
231 | +} | ... | ... |
frontend/controllers/CatalogController.php
... | ... | @@ -2,7 +2,12 @@ |
2 | 2 | |
3 | 3 | namespace frontend\controllers; |
4 | 4 | |
5 | +use common\modules\product\Filter; | |
6 | +use common\modules\rubrication\models\TaxOptionSearch; | |
7 | +use frontend\models\ProductFrontendSearch; | |
8 | +use Yii; | |
5 | 9 | use common\modules\product\models\Brand; |
10 | +use common\modules\product\models\BrandSearch; | |
6 | 11 | use common\modules\product\models\Category; |
7 | 12 | use common\modules\product\models\CategorySearch; |
8 | 13 | use common\modules\product\models\Product; |
... | ... | @@ -25,9 +30,12 @@ class CatalogController extends \yii\web\Controller |
25 | 30 | |
26 | 31 | } |
27 | 32 | |
28 | - public function actionCategory($alias) | |
33 | + public function actionCategory() | |
29 | 34 | { |
30 | - $category = CategorySearch::findByAlias($alias); | |
35 | + /** @var Category $category */ | |
36 | + $category = Yii::$app->request->get('category'); | |
37 | + $filter = Yii::$app->request->get('filter', []); | |
38 | + | |
31 | 39 | if (empty($category->category_id)) { |
32 | 40 | throw new HttpException(404 ,'Page not found'); |
33 | 41 | } |
... | ... | @@ -39,85 +47,51 @@ class CatalogController extends \yii\web\Controller |
39 | 47 | ] |
40 | 48 | ); |
41 | 49 | } else { |
42 | - $per_page = 24; | |
43 | - | |
44 | - $sort = new Sort([ | |
45 | - 'attributes' => [ | |
46 | - 'name' => [ | |
47 | - 'asc' => ['name' => SORT_ASC], | |
48 | - 'desc' => ['name' => SORT_DESC], | |
49 | - 'default' => SORT_DESC, | |
50 | - 'label' => 'имени', | |
51 | - ], | |
52 | - 'price' => [ | |
53 | - 'asc' => [ProductVariant::tableName() .'.price' => SORT_ASC], | |
54 | - 'desc' => [ProductVariant::tableName() .'.price' => SORT_DESC], | |
55 | - 'default' => SORT_DESC, | |
56 | - 'label' => 'цене', | |
57 | - ], | |
58 | - ], | |
59 | - ]); | |
60 | - /** @var ActiveQuery $query */ | |
61 | - $query = $category->getRelations('product_categories') | |
62 | - ->joinWith([ | |
63 | - 'variants' | |
64 | - ]); | |
65 | - $all_count = $query->count(); | |
66 | - | |
67 | - $brandsQuery = Brand::find() | |
68 | - ->innerJoinWith('brandName') | |
69 | - ->innerJoinWith('products') | |
70 | - ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. Product::tableName() .'.product_id') | |
71 | - ->where([ | |
72 | - ProductCategory::tableName() .'.category_id' => $category->category_id | |
73 | - ]) | |
74 | - ->groupBy(Brand::tableName() .'.brand_id'); | |
75 | - $brands = $brandsQuery->all(); | |
76 | - $brands_count = count($brands); // $brandsQuery->count(); | |
77 | - | |
78 | - $optionsQuery = TaxOption::find() | |
79 | - ->select([ | |
80 | - TaxOption::tableName() .'.*', | |
81 | - 'COUNT('. ProductOption::tableName() .'.product_id) AS _items_count' | |
82 | - ]) | |
83 | - ->innerJoin(ProductOption::tableName(), ProductOption::tableName() .'.option_id='. TaxOption::tableName() .'.tax_option_id') | |
84 | - ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. ProductOption::tableName() .'.product_id') | |
85 | - ->innerJoinWith('group') | |
86 | - ->where([ | |
87 | - ProductCategory::tableName() .'.category_id' => $category->category_id | |
88 | - ]) | |
89 | - ->groupBy(TaxOption::tableName() .'.tax_option_id'); | |
90 | - $all_options = []; | |
91 | - foreach($optionsQuery->all() as $_option) { | |
92 | - $all_options[] = $_option; | |
93 | - } | |
50 | + $params = []; | |
94 | 51 | |
95 | - $priceQuery = clone $query; | |
96 | - $priceMin = $priceMinCurr = $priceQuery->min(ProductVariant::tableName() .'.price'); | |
97 | - $priceMax = $priceMaxCurr = $priceQuery->max(ProductVariant::tableName() .'.price'); | |
98 | - | |
99 | - // Prices | |
100 | - if (($price_interval = \Yii::$app->request->get('price_interval')) != false) { | |
101 | - $price_interval = explode(';', $price_interval); | |
102 | - $price_interval = [ | |
103 | - floatval($price_interval[0]), | |
104 | - floatval($price_interval[1]), | |
105 | - ]; | |
106 | - if ($price_interval[0] > 0) { | |
107 | - $query->andWhere(['>=', ProductVariant::tableName() .'.price', $price_interval[0]]); | |
108 | - $priceMinCurr = $price_interval[0]; | |
52 | + if ( !empty($filter['brands']) ) { | |
53 | + $brands = Brand::find()->select('brand_id')->where(['in', 'alias', $filter['brands']])->all(); | |
54 | + $params['brands'] = []; | |
55 | + foreach ($brands as $brand) { | |
56 | + $params['brands'][] = $brand->brand_id; | |
109 | 57 | } |
110 | - if ($price_interval[1] > 0) { | |
111 | - $query->andWhere(['<=', ProductVariant::tableName() .'.price', $price_interval[1]]); | |
112 | - $priceMaxCurr = $price_interval[1]; | |
58 | + } | |
59 | + | |
60 | + if ( !empty($filter['options']) ) { | |
61 | + $params['options'] = $filter['options']; | |
62 | + /*$optionQuery = TaxOption::find(); | |
63 | + $optionQuery->select('tax_option_id'); | |
64 | + $optionQuery->innerJoinWith('group'); | |
65 | + foreach ($filter['options'] as $option_key => $option_values) { | |
66 | + $optionQuery->orWhere([ | |
67 | + 'tax_group_id' => $option_key, | |
68 | + 'alias' => $filter['options'] | |
69 | + ]); | |
113 | 70 | } |
71 | + $options = ->where(['in', 'alias', $filter['options']])->all(); | |
72 | + $params['options'] = []; | |
73 | + foreach ($options as $option) { | |
74 | + $params['options'][] = $option->tax_option_id; | |
75 | + }*/ | |
114 | 76 | } |
115 | 77 | |
116 | - $groups = []; | |
117 | - foreach($category->getTaxGroups()->all() as $_group) { | |
118 | - $groups[$_group->tax_group_id] = $_group; | |
78 | + if ( !empty($filter['prices']) ) { | |
79 | + $params['prices'] = $filter['prices']; | |
119 | 80 | } |
120 | - foreach ($all_options as $option) { | |
81 | + | |
82 | + $productModel = new ProductFrontendSearch(); | |
83 | + $productProvider = $productModel->search($category, $params); | |
84 | + | |
85 | + $brandModel = new BrandSearch(); | |
86 | + $brandProvider = $brandModel->getBrands($category, $params); | |
87 | + | |
88 | + $optionsProvider = $productModel->optionsForCategory($category, $params); | |
89 | + $groups = []; | |
90 | + foreach ($optionsProvider->models as $option) { | |
91 | + if (!isset($groups[$option->tax_group_id])) { | |
92 | + $groups[$option->tax_group_id] = $option->taxGroup; | |
93 | + $groups[$option->tax_group_id]->_options = []; | |
94 | + } | |
121 | 95 | $groups[$option->tax_group_id]->_options[] = $option; |
122 | 96 | } |
123 | 97 | foreach($groups as $i => $group) { |
... | ... | @@ -125,78 +99,29 @@ class CatalogController extends \yii\web\Controller |
125 | 99 | unset($groups[$i]); |
126 | 100 | } |
127 | 101 | |
128 | - // Options | |
129 | - if (($options = \Yii::$app->request->get('option')) != false) { | |
130 | -// $query->innerJoin(ProductOption::tableName(), ProductOption::tableName() .'.product_id='. Product::tableName() .'.product_id'); | |
131 | -// $query->innerJoin(TaxOption::tableName(), TaxOption::tableName() .'.tax_option_id='. ProductOption::tableName() .'.option_id'); | |
132 | - foreach($options as $group_alias => $options_alias) { | |
133 | - if (!is_array($options_alias)) { | |
134 | - $options_alias = [$options_alias]; | |
135 | - } | |
136 | - foreach($options_alias as &$option_alias) { | |
137 | - $option_alias = "'". $option_alias ."'"; | |
138 | - } | |
139 | - /*$group = TaxGroup::find()->where(['like', 'alias', $group_alias])->one(); | |
140 | - if (!$group) { | |
141 | - continue; | |
142 | - }*/ | |
143 | - } | |
144 | - $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 WHERE tax_option.alias IN ('. implode(',', $options_alias) .'))'); | |
145 | - } | |
146 | - | |
147 | - if (($_brands = \Yii::$app->request->get('brand')) != false && is_array($_brands) && count($_brands) > 0) { | |
148 | - $_brands = Brand::find()->where(['in', 'alias', $_brands])->all(); | |
149 | - $bids = []; | |
150 | - foreach ($_brands as $brand) { | |
151 | - $bids[] = $brand->brand_id; | |
152 | - } | |
153 | - if (count($bids)) { | |
154 | - $query->andWhere([Product::tableName() .'.brand_id' => $bids]); | |
155 | - } | |
156 | - } | |
157 | - | |
158 | - $query->with('variant'); | |
159 | - $query->with('brand'); | |
160 | - $query->with('categories'); | |
161 | - $query->with('image'); | |
162 | - | |
163 | - $count = $query->count(); | |
164 | - $pages = new Pagination(['totalCount' => $count, 'pageSize' => $per_page]); | |
165 | - $query->offset($pages->offset) | |
166 | - ->orderBy($sort->orders) | |
167 | - ->limit($pages->limit); | |
168 | - | |
169 | - $products = $query->all(); | |
102 | + $priceLimits = $productModel->priceLimits($category, $params); | |
170 | 103 | |
171 | 104 | return $this->render( |
172 | 105 | 'products', |
173 | 106 | [ |
174 | - 'category' => $category, | |
175 | - 'products' => $products, | |
176 | - 'all_count' => $all_count, | |
177 | - 'product_count' => $count, | |
178 | - 'sort' => $sort, | |
179 | - 'pages' => $pages, | |
180 | - 'per_page' => $per_page, | |
181 | - 'priceMin' => $priceMin, | |
182 | - 'priceMax' => $priceMax, | |
183 | - 'priceMinCurr' => $priceMinCurr, | |
184 | - 'priceMaxCurr' => $priceMaxCurr, | |
185 | - 'brands' => $brands, | |
186 | - 'brands_count' => $brands_count, | |
187 | - 'groups' => $groups, | |
188 | - 'options' => $options, | |
107 | + 'category' => $category, | |
108 | + 'brandModel' => $brandModel, | |
109 | + 'brandProvider' => $brandProvider, | |
110 | + 'filter' => $filter, | |
111 | + 'productModel' => $productModel, | |
112 | + 'productProvider' => $productProvider, | |
113 | + 'optionsProvider' => $optionsProvider, | |
114 | + 'groups' => $groups, | |
115 | + 'priceLimits' => $priceLimits, | |
189 | 116 | ] |
190 | 117 | ); |
191 | 118 | } |
192 | 119 | } |
193 | 120 | |
194 | - public function actionProduct($alias) | |
121 | + public function actionProduct() | |
195 | 122 | { |
196 | - $product = ProductSearch::findByAlias($alias); | |
197 | - if (empty($product->product_id)) { | |
198 | - throw new HttpException(404 ,'Page not found'); | |
199 | - } | |
123 | + $product = Yii::$app->request->get('product'); | |
124 | + | |
200 | 125 | $groups = []; |
201 | 126 | foreach($product->category->getTaxGroups()->all() as $_group) { |
202 | 127 | $groups[$_group->tax_group_id] = $_group; | ... | ... |
1 | +<?php | |
2 | + | |
3 | +namespace frontend\models; | |
4 | + | |
5 | +use common\modules\product\models\Brand; | |
6 | +use common\modules\product\models\ProductCategory; | |
7 | +use common\modules\product\models\ProductOption; | |
8 | +use common\modules\rubrication\models\TaxGroup; | |
9 | +use common\modules\rubrication\models\TaxOption; | |
10 | +use Yii; | |
11 | +use yii\base\Model; | |
12 | +use yii\data\ActiveDataProvider; | |
13 | +use yii\db\ActiveQuery; | |
14 | +use yii\db\ActiveRecord; | |
15 | +use yii\web\NotFoundHttpException; | |
16 | +use common\modules\product\models\Product; | |
17 | +use common\modules\product\models\ProductVariant; | |
18 | + | |
19 | +class ProductFrontendSearch extends Product { | |
20 | + /** | |
21 | + * @inheritdoc | |
22 | + */ | |
23 | + public function rules() | |
24 | + { | |
25 | + return [ | |
26 | + [['price_interval', 'brands'], 'safe'], | |
27 | + ]; | |
28 | + } | |
29 | + | |
30 | + /** | |
31 | + * @inheritdoc | |
32 | + */ | |
33 | + public function scenarios() | |
34 | + { | |
35 | + // bypass scenarios() implementation in the parent class | |
36 | + return Model::scenarios(); | |
37 | + } | |
38 | + | |
39 | + /** | |
40 | + * Creates data provider instance with search query applied for frontend | |
41 | + * | |
42 | + * @param array $params | |
43 | + * | |
44 | + * @return ActiveDataProvider | |
45 | + */ | |
46 | + public function search($category, $params) { | |
47 | + /** @var ActiveQuery $query */ | |
48 | + $query = $category->getRelations('product_categories'); | |
49 | + | |
50 | + $query->joinWith('variant'); | |
51 | + $query->joinWith('brand'); | |
52 | + $query->joinWith('categories'); | |
53 | + $query->joinWith('image'); | |
54 | + | |
55 | + $dataProvider = new ActiveDataProvider([ | |
56 | + 'query' => $query, | |
57 | + 'pagination' => [ | |
58 | + 'pageSize' => 24, | |
59 | + ], | |
60 | + 'sort' => [ | |
61 | + 'attributes' => [ | |
62 | + 'name' => [ | |
63 | + 'asc' => ['name' => SORT_ASC], | |
64 | + 'desc' => ['name' => SORT_DESC], | |
65 | + 'default' => SORT_DESC, | |
66 | + 'label' => 'имени', | |
67 | + ], | |
68 | + 'price' => [ | |
69 | + 'asc' => [ProductVariant::tableName() .'.price' => SORT_ASC], | |
70 | + 'desc' => [ProductVariant::tableName() .'.price' => SORT_DESC], | |
71 | + 'default' => SORT_DESC, | |
72 | + 'label' => 'цене', | |
73 | + ], | |
74 | + ], | |
75 | + ] | |
76 | + ]); | |
77 | + | |
78 | + if (!$this->validate()) { | |
79 | + return $dataProvider; | |
80 | + } | |
81 | + | |
82 | + $this->_setParams($query, $params); | |
83 | + | |
84 | + return $dataProvider; | |
85 | + } | |
86 | + | |
87 | + public function optionsForCategory($category, $params) { | |
88 | + $query = TaxOption::find() | |
89 | + ->select([ | |
90 | + TaxOption::tableName() .'.*', | |
91 | + 'COUNT('. ProductOption::tableName() .'.product_id) AS _items_count' | |
92 | + ]) | |
93 | + ->innerJoin(ProductOption::tableName(), ProductOption::tableName() .'.option_id='. TaxOption::tableName() .'.tax_option_id') | |
94 | + ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. ProductOption::tableName() .'.product_id') | |
95 | + ->innerJoin(TaxGroup::tableName(), TaxGroup::tableName() .'.tax_group_id='. TaxOption::tableName() .'.tax_group_id') | |
96 | + ->where([ | |
97 | + TaxGroup::tableName() .'.is_filter' => true, | |
98 | + ProductCategory::tableName() .'.category_id' => $category->category_id | |
99 | + ]) | |
100 | + ->groupBy(TaxOption::tableName() .'.tax_option_id'); | |
101 | + | |
102 | + if (!empty($params['prices'])) { | |
103 | + if ($params['prices']['min'] > 0 || $params['prices']['max'] > 0) { | |
104 | + $query->innerJoin(ProductVariant::tableName(), ProductVariant::tableName() .'.product_id='. ProductCategory::tableName() .'.product_id'); | |
105 | + } | |
106 | + if ($params['prices']['min'] > 0) { | |
107 | + $query->andWhere(['>=', ProductVariant::tableName() .'.price', $params['prices']['min']]); | |
108 | + } | |
109 | + if ($params['prices']['max'] > 0) { | |
110 | + $query->andWhere(['<=', ProductVariant::tableName() .'.price', $params['prices']['max']]); | |
111 | + } | |
112 | + } | |
113 | + if (!empty($params['brands'])) { | |
114 | + $query->innerJoin(Product::tableName(), Product::tableName() .'.product_id='. ProductCategory::tableName() .'.product_id'); | |
115 | + $query->andWhere([Product::tableName() .'.brand_id' => $params['brands']]); | |
116 | + } | |
117 | + | |
118 | + $dataProvider = new ActiveDataProvider([ | |
119 | + 'query' => $query, | |
120 | + ]); | |
121 | + | |
122 | + return $dataProvider; | |
123 | + } | |
124 | + | |
125 | + public function priceLimits($category, $params) { | |
126 | + /** @var ActiveQuery $query */ | |
127 | + $query = $category->getRelations('product_categories'); | |
128 | + $query->joinWith('variant'); | |
129 | + | |
130 | + $this->_setParams($query, $params, false); | |
131 | + | |
132 | +// $query->select([ | |
133 | +// 'MIN('. ProductVariant::tableName() .'.price) AS priceMIN', | |
134 | +// 'MAX('. ProductVariant::tableName() .'.price) AS priceMAX', | |
135 | +// ]); | |
136 | + | |
137 | + return [ | |
138 | + 'min' => $query->min(ProductVariant::tableName() .'.price'), | |
139 | + 'max' => $query->max(ProductVariant::tableName() .'.price'), | |
140 | + ]; | |
141 | + } | |
142 | + | |
143 | + protected function _setParams(&$query, $params, $setPriceLimits = true) { | |
144 | + if (!empty($params['brands'])) { | |
145 | + $query->andFilterWhere([Product::tableName() .'.brand_id' => $params['brands']]); | |
146 | + } | |
147 | + if (!empty($params['options'])) { | |
148 | + foreach ($params['options'] as $group => $options) { | |
149 | + foreach ($options as &$option) { | |
150 | + $option = "'$option'"; | |
151 | + } | |
152 | + $query->andWhere( | |
153 | + 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 \''. $group .'\' AND tax_option.alias IN (' . implode(',', $options) . '))' | |
154 | + ); | |
155 | + } | |
156 | + } | |
157 | + if ($setPriceLimits && !empty($params['prices'])) { | |
158 | + if ($params['prices']['min'] > 0) { | |
159 | + $query->andWhere(['>=', ProductVariant::tableName() .'.price', $params['prices']['min']]); | |
160 | + } | |
161 | + if ($params['prices']['max'] > 0) { | |
162 | + $query->andWhere(['<=', ProductVariant::tableName() .'.price', $params['prices']['max']]); | |
163 | + } | |
164 | + } | |
165 | + } | |
166 | +} | |
0 | 167 | \ No newline at end of file | ... | ... |
frontend/views/catalog/categories.php
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | |
5 | 5 | $this->title = $category->name; |
6 | 6 | foreach($category->getParents()->all() as $parent) { |
7 | - $this->params['breadcrumbs'][] = ['label' => $parent->name, 'url' => ['catalog/category', 'alias' => $parent->alias]]; | |
7 | + $this->params['breadcrumbs'][] = ['label' => $parent->name, 'url' => ['catalog/category', 'category' => $parent]]; | |
8 | 8 | } |
9 | 9 | $this->params['breadcrumbs'][] = $this->title; |
10 | 10 | ?> |
... | ... | @@ -31,7 +31,7 @@ $this->params['breadcrumbs'][] = $this->title; |
31 | 31 | <div class="cat_li_sub_ul"> |
32 | 32 | <ul> |
33 | 33 | <?php foreach($category['children'] as $_category) :?> |
34 | - <li><a href="<?= \yii\helpers\Url::to(['catalog/category', 'alias' => $_category['item']->alias])?>"><?= $_category['item']->name?><!-- (18)--></a></li> | |
34 | + <li><a href="<?= \yii\helpers\Url::to(['catalog/category', 'category' => $_category['item']])?>"><?= $_category['item']->name?><!-- (18)--></a></li> | |
35 | 35 | <?php endforeach?> |
36 | 36 | </ul> |
37 | 37 | </div> | ... | ... |
frontend/views/catalog/product.php
... | ... | @@ -4,9 +4,9 @@ |
4 | 4 | |
5 | 5 | $this->title = $product->name; |
6 | 6 | foreach($product->category->getParents()->all() as $parent) { |
7 | - $this->params['breadcrumbs'][] = ['label' => $parent->name, 'url' => ['catalog/category', 'alias' => $parent->alias]]; | |
7 | + $this->params['breadcrumbs'][] = ['label' => $parent->categoryName->value, 'url' => ['catalog/category', 'category' => $parent]]; | |
8 | 8 | } |
9 | -$this->params['breadcrumbs'][] = ['label' => $product->category->name, 'url' => ['catalog/category', 'alias' => $product->category->alias]]; | |
9 | +$this->params['breadcrumbs'][] = ['label' => $product->category->categoryName->value, 'url' => ['catalog/category', 'category' => $product->category]]; | |
10 | 10 | $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku; |
11 | 11 | ?> |
12 | 12 | <h1 class="open_card_item_title"><?= $product->name .' '. $product->variant->name?></h1> | ... | ... |
frontend/views/catalog/product_item.php
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | <div class="item" data-id="<?= $product->product_id?>"> |
6 | 6 | <!--<div class="new">АКЦИЯ</div> |
7 | 7 | <div class="top">Toп</div>--> |
8 | - <a href="<?= \yii\helpers\Url::to(['catalog/product', 'alias' => $product->alias])?>" class="item_link"> | |
8 | + <a href="<?= \yii\helpers\Url::to(['catalog/product', 'product' => $product])?>" class="item_link"> | |
9 | 9 | <div class="pic"> |
10 | 10 | <?php if (empty($product->image)) :?> |
11 | 11 | <img src="/images/no_photo.png"> | ... | ... |
1 | +<?php | |
2 | +/** @var $this \yii\web\View */ | |
3 | +/** @var $dataProvider \yii\data\ActiveDataProvider */ | |
4 | + | |
5 | +$this->title = $category->categoryName->value; | |
6 | +foreach($category->getParents()->all() as $parent) { | |
7 | + $this->params['breadcrumbs'][] = ['label' => $parent->categoryName->value, 'url' => ['catalog/category', 'alias' => $parent->alias]]; | |
8 | +} | |
9 | +$this->params['breadcrumbs'][] = $category->categoryName->value; | |
10 | +?> | |
11 | +<script type="text/javascript"> | |
12 | + $(document).ready(function() { | |
13 | + // price rangeslider (filter price slider) | |
14 | + $("#price_interval").ionRangeSlider({ | |
15 | + type: "double", | |
16 | + min: <?= $priceMin?>, | |
17 | + max: <?= $priceMax?>, | |
18 | + from: <?= $priceMinCurr?>, | |
19 | + to: <?= $priceMaxCurr?>, | |
20 | + grid: false | |
21 | + }); | |
22 | + }); | |
23 | +</script> | |
24 | +<div class="w_960"> | |
25 | + <!-- side bar with all filters --> | |
26 | + <div class="cat_p_filter_bar"> | |
27 | + <div class="title">ФИЛЬТРЫ</div> | |
28 | + <div class="filter_list"> | |
29 | + <form action="#" name="filter_catalog_page_form"> | |
30 | + <ul> | |
31 | + <li>Цена: | |
32 | + <div class="arrow"><img src="/images/head_up.png" alt=""></i></div> | |
33 | + <div class="price_filter first_price_li"> | |
34 | + <div class="price_slider"> | |
35 | + <input type="text" id="price_interval" name="price_interval" value="" /> | |
36 | + </div> | |
37 | + <!--<div class="checkbox"> | |
38 | + <label><input type="checkbox" name="venecia" value="0" /></label> | |
39 | + <a href="#">Акции</a> | |
40 | + </div> | |
41 | + <div class="checkbox"> | |
42 | + <label><input type="checkbox" name="venecia" value="0" /></label> | |
43 | + <a href="#">Товар в наличии</a> | |
44 | + </div> | |
45 | + <div class="checkbox"> | |
46 | + <label><input type="checkbox" name="venecia" value="0" /></label> | |
47 | + <a href="#">Хит продаж</a> | |
48 | + </div>--> | |
49 | + </div> | |
50 | + </li> | |
51 | + | |
52 | + <?php if ($brands_count) :?> | |
53 | + <li>Бренд | |
54 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
55 | + <div class="price_filter<?= !empty($_brands)?' active-field':''?>"> | |
56 | + <?php foreach($brands as $brand) :?> | |
57 | + <div class="checkbox"> | |
58 | + <label><input type="checkbox" name="brand[]" value="<?= $brand->alias?>"<?= isset($_GET['brand']) && in_array($brand->alias, $_GET['brand']) ? ' checked' : ''?> /></label> | |
59 | + <a href="#<?php /*= \yii\helpers\Url::to(['brand', 'alias' => $brand->alias])*/?>"><?= $brand->name?><!-- (<?php /*= $brand->getProducts()->count()*/?>)--></a> | |
60 | + </div> | |
61 | + <?php endforeach?> | |
62 | + <!--<div class="checkbox see_all"> | |
63 | + <i class="fa fa-plus-circle"></i> | |
64 | + <a href="#">посмотреть все</a> | |
65 | + </div>--> | |
66 | + </div> | |
67 | + </li> | |
68 | + <?php endif?> | |
69 | + | |
70 | + <?php if (!empty($groups)) :?> | |
71 | + <div class="title_2">ПОДБОР ПО ПАРАМЕТРАМ</div> | |
72 | + | |
73 | + <?php foreach($groups as $group) :?> | |
74 | + <li><?= $group->name?> | |
75 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
76 | + <div class="price_filter<?= isset($options[$group->alias])?' active-field':''?>"> | |
77 | + <?php foreach($group->_options as $option) :?> | |
78 | + <div class="checkbox"> | |
79 | + <label><input type="checkbox" name="option[<?= $group->alias?>][]" value="<?= $option->alias?>"<?= (isset($options[$group->alias]) && in_array($option->alias, $options[$group->alias])) ? ' checked' : ''?> /></label> | |
80 | + <a href="#"><?= $option->ValueRenderHTML?> (<?= $option->_items_count?>)</a> | |
81 | + </div> | |
82 | + <?php endforeach?> | |
83 | + </div> | |
84 | + </li> | |
85 | + <?php endforeach?> | |
86 | + <?php endif?> | |
87 | + | |
88 | + </ul> | |
89 | + | |
90 | + <div class="filter_accept_bloc"> | |
91 | + <button type="submit" class="filter_accept_btn">применить</button> | |
92 | + <a href="#" class="form_checkbox_reset">сбросить фильтры</a> | |
93 | + </div> | |
94 | + </form> | |
95 | + <!--<div class="product_list"> | |
96 | + <h2 class="title">КАТАЛОГ ТОВАРОВ</h2> | |
97 | + <ul> | |
98 | + <li>Битумная черепица | |
99 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
100 | + <div class="price_filter"> | |
101 | + <a href="#">RUUKI</a> | |
102 | + <a href="#">Venecia</a> | |
103 | + </div> | |
104 | + </li> | |
105 | + | |
106 | + <li>Комплектация кровли | |
107 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
108 | + <div class="price_filter"> | |
109 | + <a href="#">RUUKI</a> | |
110 | + <a href="#">Venecia</a> | |
111 | + </div> | |
112 | + </li> | |
113 | + | |
114 | + <li>Водосточные системы | |
115 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
116 | + <div class="price_filter"> | |
117 | + <a href="#">RUUKI</a> | |
118 | + <a href="#">Venecia</a> | |
119 | + </div> | |
120 | + </li> | |
121 | + | |
122 | + <li>Чердачные лестницы | |
123 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
124 | + <div class="price_filter"> | |
125 | + <a href="#">RUUKI</a> | |
126 | + <a href="#">Venecia</a> | |
127 | + </div> | |
128 | + </li> | |
129 | + | |
130 | + <li>Мансардные окна | |
131 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
132 | + <div class="price_filter"> | |
133 | + <a href="#">RUUKI</a> | |
134 | + <a href="#">Venecia</a> | |
135 | + </div> | |
136 | + </li> | |
137 | + | |
138 | + <li>Металлочерепица | |
139 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
140 | + <div class="price_filter"> | |
141 | + <a href="#">RUUKI</a> | |
142 | + <a href="#">Venecia</a> | |
143 | + </div> | |
144 | + </li> | |
145 | + | |
146 | + <li>Плоская кровля | |
147 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
148 | + <div class="price_filter"> | |
149 | + <a href="#">RUUKI</a> | |
150 | + <a href="#">Venecia</a> | |
151 | + </div> | |
152 | + </li> | |
153 | + | |
154 | + <li>Профнастил | |
155 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
156 | + <div class="price_filter"> | |
157 | + <a href="#">RUUKI</a> | |
158 | + <a href="#">Venecia</a> | |
159 | + </div> | |
160 | + </li> | |
161 | + | |
162 | + <li>Ондулин | |
163 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
164 | + <div class="price_filter"> | |
165 | + <a href="#">RUUKI</a> | |
166 | + <a href="#">Venecia</a> | |
167 | + </div> | |
168 | + </li> | |
169 | + | |
170 | + <li>OSB плиты | |
171 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
172 | + <div class="price_filter"> | |
173 | + <a href="#">RUUKI</a> | |
174 | + <a href="#">Venecia</a> | |
175 | + </div> | |
176 | + </li> | |
177 | + | |
178 | + </ul> | |
179 | + </div>--> | |
180 | + </div> | |
181 | + | |
182 | + | |
183 | + </div> | |
184 | + | |
185 | + <!-- catalog list with all item cards --> | |
186 | + <div class="cat_p_catalog_list"> | |
187 | + <div class="title"><?= $category->categoryName->value?> <span>(<?= $all_count?>)</span></div> | |
188 | + | |
189 | + <?php if (empty($products)) :?> | |
190 | + <h2>По данному запросу товары не найдены.</h2><br> | |
191 | + <p>Показать <a href="<?= \yii\helpers\Url::to(['catalog/category', 'alias' => $category->alias])?>">все товары из категории "<?= $category->categoryName->value?>"</a></p> | |
192 | + <?php else :?> | |
193 | + <!-- sort menu --> | |
194 | + <div class="sort_menu"> | |
195 | + | |
196 | + <div class="sort_price"> | |
197 | + <span>Сортировка:</span> | |
198 | + <?= \yii\widgets\LinkSorter::widget([ | |
199 | + 'sort' => $sort, | |
200 | + 'attributes' => [ | |
201 | + 'name', | |
202 | + 'price', | |
203 | + ] | |
204 | + ]); | |
205 | + ?> | |
206 | + <!-- | |
207 | + <select name="sort_price" id="" class="sort_price_select"> | |
208 | + <option value="price">по цене</option> | |
209 | + <option value="popular">новые</option> | |
210 | + <option value="sale">по акции</option> | |
211 | + </select> | |
212 | + <i class="fa fa-angle-down"></i>--> | |
213 | + </div> | |
214 | + | |
215 | + <div class="show"> | |
216 | + <!--<span>Показывать по:</span> | |
217 | + <ul> | |
218 | + <li><a class="active" href="#">24</a></li> | |
219 | + <li><a href="#">48</a></li> | |
220 | + <li><a href="#">96</a></li> | |
221 | + </ul>--> | |
222 | + </div> | |
223 | + | |
224 | + <div class="show_pages"> | |
225 | + <?php if ($pages->totalCount > $pages->pageSize) :?> | |
226 | + <span>Страница:</span> | |
227 | + <?= \yii\widgets\LinkPager::widget([ | |
228 | + 'pagination' => $pages, | |
229 | + 'options' => ['class' => 'pagination pull-right'], | |
230 | + ]); | |
231 | + ?> | |
232 | + <!--<i class="fa fa-caret-right"></i>--> | |
233 | + <?php endif?> | |
234 | + </div> | |
235 | + | |
236 | + </div> | |
237 | + | |
238 | + | |
239 | + <div class="cat_p_item_card_list"> | |
240 | + <div class="novelty"> | |
241 | + <div class="content"> | |
242 | + <div class="novelty_cont"> | |
243 | + <?php foreach($products as $product) :?> | |
244 | + <?php require(__DIR__ .'/product_item.php')?> | |
245 | + <?php endforeach?> | |
246 | + </div> | |
247 | + | |
248 | + <?php if ($pages->totalCount > $pages->pageSize) :?> | |
249 | + <!-- LOAD MORE BUTTON --> | |
250 | + <!--button class="load_more_btn">Загрузить еще <?= $per_page?> товара</button--> | |
251 | + | |
252 | + <div class="show_pages"> | |
253 | + Страница: | |
254 | + <?= \yii\widgets\LinkPager::widget([ | |
255 | + 'pagination' => $pages, | |
256 | + 'options' => ['class' => 'pagination pull-right'], | |
257 | + ]); | |
258 | + ?> | |
259 | + <!--<i class="fa fa-caret-right"></i>--> | |
260 | + </div> | |
261 | + <?php endif?> | |
262 | + <hr> | |
263 | + | |
264 | + <?php if(!empty($category->description)) :?> | |
265 | + <div class="description"> | |
266 | + <?= $category->description?> | |
267 | + | |
268 | + <div class="empty_padding_400"></div> | |
269 | + </div> | |
270 | + <?php endif?> | |
271 | + </div> | |
272 | + </div> | |
273 | + </div> | |
274 | + | |
275 | + <?php endif?> | |
276 | + </div> | |
277 | +</div> | |
278 | + | ... | ... |
frontend/views/catalog/products.php
1 | 1 | <?php |
2 | 2 | /** @var $this \yii\web\View */ |
3 | -/** @var $dataProvider \yii\data\ActiveDataProvider */ | |
3 | +/** @var $productProvider \yii\data\ActiveDataProvider */ | |
4 | +/** @var $brandProvider \yii\data\ActiveDataProvider */ | |
5 | + | |
6 | +use yii\helpers\Url; | |
7 | +use common\modules\product\helpers\ProductHelper; | |
4 | 8 | |
5 | 9 | $this->title = $category->categoryName->value; |
6 | 10 | foreach($category->getParents()->all() as $parent) { |
7 | - $this->params['breadcrumbs'][] = ['label' => $parent->categoryName->value, 'url' => ['catalog/category', 'alias' => $parent->alias]]; | |
11 | + $this->params['breadcrumbs'][] = ['label' => $parent->categoryName->value, 'url' => ['catalog/category', 'category' => $parent]]; | |
8 | 12 | } |
9 | 13 | $this->params['breadcrumbs'][] = $category->categoryName->value; |
10 | 14 | ?> |
11 | 15 | <script type="text/javascript"> |
16 | +<?php if ($priceLimits['min'] < $priceLimits['max']) :?> | |
12 | 17 | $(document).ready(function() { |
13 | 18 | // price rangeslider (filter price slider) |
14 | 19 | $("#price_interval").ionRangeSlider({ |
15 | 20 | type: "double", |
16 | - min: <?= $priceMin?>, | |
17 | - max: <?= $priceMax?>, | |
18 | - from: <?= $priceMinCurr?>, | |
19 | - to: <?= $priceMaxCurr?>, | |
20 | - grid: false | |
21 | + min: <?= $priceLimits['min']?>, | |
22 | + max: <?= $priceLimits['max']?>, | |
23 | + from: <?= empty($filter['prices']['min']) ? $priceLimits['min'] : $filter['prices']['min']?>, | |
24 | + to: <?= empty($filter['prices']['max']) ? $priceLimits['max'] : $filter['prices']['max']?>, | |
25 | + grid: false, | |
26 | + onFinish: function(e) { | |
27 | +<?php | |
28 | +$filterWhitoutPrice = $filter; | |
29 | +$filterWhitoutPrice['prices'] = [ | |
30 | + 'min' => '{from}', | |
31 | + 'max' => '{to}', | |
32 | +]; | |
33 | +?> | |
34 | + var url = "<?= Url::to(['catalog/category', 'category' => $category, 'filter' => $filterWhitoutPrice])?>"; | |
35 | + var from = e.from; | |
36 | + var to = e.to; | |
37 | + document.location = url.replace('{from}', from).replace('{to}', to); | |
38 | + } | |
39 | + }); | |
40 | + }); | |
41 | +<?php endif?> | |
42 | +<?php /* | |
43 | + $(document).ready(function() { | |
44 | + $('form.filter-catalog-form').each(function() { | |
45 | + var form = $(this); | |
46 | + form.submit(function(e) { | |
47 | + e.preventDefault(); | |
48 | + var brands = ''; | |
49 | + // Get brands values | |
50 | + $('input[type=checkbox].brands-option:checked', form).each(function() { | |
51 | + var filter_value = $(this).val().replace(',', '~').replace('/', '&s;'); | |
52 | + if (brands) { | |
53 | + brands += ','+ filter_value; | |
54 | + } else { | |
55 | + brands = filter_value; | |
56 | + } | |
57 | + }); | |
58 | + // Formate query and redirect | |
59 | + var filter = ''; | |
60 | + if (brands) { | |
61 | + filter += 'brands='+ brands; | |
62 | + } | |
63 | + filter += ';'; | |
64 | + | |
65 | + if (filter) { | |
66 | + var request = '<?= Url::toRoute(['catalog/category/filter', 'alias' => $category->alias, 'filter' => '+ filter .'])?>'; | |
67 | + window.location.href = request; | |
68 | + } | |
69 | + }); | |
21 | 70 | }); |
22 | 71 | }); |
72 | +*/?> | |
23 | 73 | </script> |
24 | 74 | <div class="w_960"> |
25 | 75 | <!-- side bar with all filters --> |
26 | 76 | <div class="cat_p_filter_bar"> |
27 | 77 | <div class="title">ФИЛЬТРЫ</div> |
28 | 78 | <div class="filter_list"> |
29 | - <form action="#" name="filter_catalog_page_form"> | |
79 | + <form action="#" name="filter_catalog_page_form" class="filter-catalog-form"> | |
80 | + <?php if (!empty($filter)) :?> | |
81 | + <div class="filter_accept_bloc"> | |
82 | + <!-- <button type="submit" class="filter_accept_btn">применить</button>--> | |
83 | + <a href="<?= Url::to(['catalog/category', 'category' => $category])?>" class="_form_checkbox_reset">сбросить фильтры</a> | |
84 | + </div> | |
85 | + <?php endif?> | |
30 | 86 | <ul> |
87 | + <?php if ($priceLimits['min'] < $priceLimits['max']) :?> | |
31 | 88 | <li>Цена: |
32 | 89 | <div class="arrow"><img src="/images/head_up.png" alt=""></i></div> |
33 | 90 | <div class="price_filter first_price_li"> |
34 | 91 | <div class="price_slider"> |
35 | 92 | <input type="text" id="price_interval" name="price_interval" value="" /> |
36 | 93 | </div> |
37 | - <!--<div class="checkbox"> | |
38 | - <label><input type="checkbox" name="venecia" value="0" /></label> | |
39 | - <a href="#">Акции</a> | |
40 | - </div> | |
41 | - <div class="checkbox"> | |
42 | - <label><input type="checkbox" name="venecia" value="0" /></label> | |
43 | - <a href="#">Товар в наличии</a> | |
44 | - </div> | |
45 | - <div class="checkbox"> | |
46 | - <label><input type="checkbox" name="venecia" value="0" /></label> | |
47 | - <a href="#">Хит продаж</a> | |
48 | - </div>--> | |
49 | 94 | </div> |
50 | 95 | </li> |
96 | + <?php endif?> | |
51 | 97 | |
52 | - <?php if ($brands_count) :?> | |
53 | - <li>Бренд | |
54 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
55 | - <div class="price_filter"> | |
56 | - <?php foreach($brands as $brand) :?> | |
57 | - <div class="checkbox"> | |
58 | - <label><input type="checkbox" name="brand[]" value="<?= $brand->alias?>"<?= isset($_GET['brand']) && in_array($brand->alias, $_GET['brand']) ? ' checked' : ''?> /></label> | |
59 | - <a href="#<?php /*= \yii\helpers\Url::to(['brand', 'alias' => $brand->alias])*/?>"><?= $brand->name?><!-- (<?php /*= $brand->getProducts()->count()*/?>)--></a> | |
98 | + <?php if ($brandProvider->totalCount > 0) :?> | |
99 | + <li>Бренд | |
100 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
101 | + <div class="price_filter<?= !empty($filter['brands'])?' active-field':''?>"> | |
102 | + <?php foreach($brandProvider->models as $brand) : | |
103 | + $checked = !empty($filter['brands']) && in_array($brand->alias, $filter['brands']); | |
104 | + $option_url = Url::to(['catalog/category', 'category' => $category, 'filter' => ProductHelper::getFilterForOption($filter, 'brands', $brand->alias, $checked)]); | |
105 | + ?> | |
106 | + <div class="checkbox"> | |
107 | + <label><input type="checkbox" class="brands-option" <?php /*name="brands[]" value="<?= $brand->alias?>"*/?><?= $checked ? ' checked' : ''?> onchange="document.location='<?= $option_url?>'" /></label> | |
108 | + <a href="<?= $option_url?>"><?= $brand->name?> (<?= $brand->getProducts()->count()?>)</a> | |
109 | + </div> | |
110 | + <?php endforeach?> | |
60 | 111 | </div> |
61 | - <?php endforeach?> | |
62 | - <!--<div class="checkbox see_all"> | |
63 | - <i class="fa fa-plus-circle"></i> | |
64 | - <a href="#">посмотреть все</a> | |
65 | - </div>--> | |
66 | - </div> | |
67 | - </li> | |
112 | + </li> | |
68 | 113 | <?php endif?> |
69 | 114 | |
70 | 115 | <?php if (!empty($groups)) :?> |
71 | - <div class="title_2">ПОДБОР ПО ПАРАМЕТРАМ</div> | |
116 | + <div class="title_2">ПОДБОР ПО ПАРАМЕТРАМ</div> | |
72 | 117 | |
73 | 118 | <?php foreach($groups as $group) :?> |
74 | - <li><?= $group->name?> | |
75 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
76 | - <div class="price_filter"> | |
77 | - <?php foreach($group->_options as $option) :?> | |
78 | - <div class="checkbox"> | |
79 | - <label><input type="checkbox" name="option[<?= $group->alias?>][]" value="<?= $option->alias?>"<?= (isset($options[$group->alias]) && in_array($option->alias, $options[$group->alias])) ? ' checked' : ''?> /></label> | |
80 | - <a href="#"><?= $option->ValueRenderHTML?> (<?= $option->_items_count?>)</a> | |
119 | + <li><?= $group->name?> | |
120 | + <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
121 | + <div class="price_filter<?= isset($filter['options'][$group->alias])?' active-field':''?>"> | |
122 | + <?php foreach($group->_options as $option) : | |
123 | + $checked = (isset($filter['options'][$group->alias]) && in_array($option->alias, $filter['options'][$group->alias])); | |
124 | + $option_url = Url::to(['catalog/category', 'category' => $category, 'filter' => ProductHelper::getFilterForOption($filter, 'options', [$option->group->alias => [$option->alias]], $checked)]); | |
125 | + ?> | |
126 | + <div class="checkbox"> | |
127 | + <label><input type="checkbox" class="features-option" onchange="document.location='<?= $option_url?>'" <?php /* name="option[<?= $group->alias?>][]"value="<?= $option->alias?>"*/?><?= $checked ? ' checked' : ''?> /></label> | |
128 | + <a href="<?= $option_url?>"><?= $option->ValueRenderHTML?> (<?= $option->_items_count?>)</a> | |
129 | + </div> | |
130 | + <?php endforeach?> | |
81 | 131 | </div> |
82 | - <?php endforeach?> | |
83 | - </div> | |
84 | - </li> | |
132 | + </li> | |
85 | 133 | <?php endforeach?> |
86 | 134 | <?php endif?> |
87 | - | |
88 | 135 | </ul> |
89 | - | |
90 | - <div class="filter_accept_bloc"> | |
91 | - <button type="submit" class="filter_accept_btn">применить</button> | |
92 | - <a href="#" class="form_checkbox_reset">сбросить фильтры</a> | |
93 | - </div> | |
94 | 136 | </form> |
95 | - <!--<div class="product_list"> | |
96 | - <h2 class="title">КАТАЛОГ ТОВАРОВ</h2> | |
97 | - <ul> | |
98 | - <li>Битумная черепица | |
99 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
100 | - <div class="price_filter"> | |
101 | - <a href="#">RUUKI</a> | |
102 | - <a href="#">Venecia</a> | |
103 | - </div> | |
104 | - </li> | |
105 | - | |
106 | - <li>Комплектация кровли | |
107 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
108 | - <div class="price_filter"> | |
109 | - <a href="#">RUUKI</a> | |
110 | - <a href="#">Venecia</a> | |
111 | - </div> | |
112 | - </li> | |
113 | - | |
114 | - <li>Водосточные системы | |
115 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
116 | - <div class="price_filter"> | |
117 | - <a href="#">RUUKI</a> | |
118 | - <a href="#">Venecia</a> | |
119 | - </div> | |
120 | - </li> | |
121 | - | |
122 | - <li>Чердачные лестницы | |
123 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
124 | - <div class="price_filter"> | |
125 | - <a href="#">RUUKI</a> | |
126 | - <a href="#">Venecia</a> | |
127 | - </div> | |
128 | - </li> | |
129 | - | |
130 | - <li>Мансардные окна | |
131 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
132 | - <div class="price_filter"> | |
133 | - <a href="#">RUUKI</a> | |
134 | - <a href="#">Venecia</a> | |
135 | - </div> | |
136 | - </li> | |
137 | - | |
138 | - <li>Металлочерепица | |
139 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
140 | - <div class="price_filter"> | |
141 | - <a href="#">RUUKI</a> | |
142 | - <a href="#">Venecia</a> | |
143 | - </div> | |
144 | - </li> | |
145 | - | |
146 | - <li>Плоская кровля | |
147 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
148 | - <div class="price_filter"> | |
149 | - <a href="#">RUUKI</a> | |
150 | - <a href="#">Venecia</a> | |
151 | - </div> | |
152 | - </li> | |
153 | - | |
154 | - <li>Профнастил | |
155 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
156 | - <div class="price_filter"> | |
157 | - <a href="#">RUUKI</a> | |
158 | - <a href="#">Venecia</a> | |
159 | - </div> | |
160 | - </li> | |
161 | - | |
162 | - <li>Ондулин | |
163 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
164 | - <div class="price_filter"> | |
165 | - <a href="#">RUUKI</a> | |
166 | - <a href="#">Venecia</a> | |
167 | - </div> | |
168 | - </li> | |
169 | - | |
170 | - <li>OSB плиты | |
171 | - <div class="arrow"><img src="/images/head_down.png" alt=""></i></div> | |
172 | - <div class="price_filter"> | |
173 | - <a href="#">RUUKI</a> | |
174 | - <a href="#">Venecia</a> | |
175 | - </div> | |
176 | - </li> | |
177 | - | |
178 | - </ul> | |
179 | - </div>--> | |
180 | 137 | </div> |
181 | - | |
182 | - | |
183 | 138 | </div> |
184 | 139 | |
185 | 140 | <!-- catalog list with all item cards --> |
186 | 141 | <div class="cat_p_catalog_list"> |
187 | - <div class="title"><?= $category->categoryName->value?> <span>(<?= $all_count?>)</span></div> | |
142 | + <div class="title"><?= $category->categoryName->value?> <span>(<?= $productProvider->totalCount?>)</span></div> | |
188 | 143 | |
189 | - <?php if (empty($products)) :?> | |
144 | + <?php if (!$productProvider->count) :?> | |
190 | 145 | <h2>По данному запросу товары не найдены.</h2><br> |
191 | - <p>Показать <a href="<?= \yii\helpers\Url::to(['catalog/category', 'alias' => $category->alias])?>">все товары из категории "<?= $category->categoryName->value?>"</a></p> | |
146 | + <p>Показать <a href="<?= Url::to(['catalog/category', 'category' => $category])?>">все товары из категории "<?= $category->categoryName->value?>"</a></p> | |
192 | 147 | <?php else :?> |
193 | - <!-- sort menu --> | |
194 | - <div class="sort_menu"> | |
195 | - | |
196 | - <div class="sort_price"> | |
197 | - <span>Сортировка:</span> | |
198 | - <?= \yii\widgets\LinkSorter::widget([ | |
199 | - 'sort' => $sort, | |
200 | - 'attributes' => [ | |
201 | - 'name', | |
202 | - 'price', | |
203 | - ] | |
204 | - ]); | |
205 | - ?> | |
206 | - <!-- | |
207 | - <select name="sort_price" id="" class="sort_price_select"> | |
208 | - <option value="price">по цене</option> | |
209 | - <option value="popular">новые</option> | |
210 | - <option value="sale">по акции</option> | |
211 | - </select> | |
212 | - <i class="fa fa-angle-down"></i>--> | |
213 | - </div> | |
148 | + <!-- sort menu --> | |
149 | + <div class="sort_menu"> | |
150 | + | |
151 | + <div class="sort_price"> | |
152 | + <span>Сортировка:</span> | |
153 | + <?= \yii\widgets\LinkSorter::widget([ | |
154 | + 'sort' => $productProvider->sort, | |
155 | + 'attributes' => [ | |
156 | + 'name', | |
157 | + 'price', | |
158 | + ] | |
159 | + ]); | |
160 | + ?> | |
161 | + <!-- | |
162 | + <select name="sort_price" id="" class="sort_price_select"> | |
163 | + <option value="price">по цене</option> | |
164 | + <option value="popular">новые</option> | |
165 | + <option value="sale">по акции</option> | |
166 | + </select> | |
167 | + <i class="fa fa-angle-down"></i>--> | |
168 | + </div> | |
214 | 169 | |
215 | - <div class="show"> | |
216 | - <!--<span>Показывать по:</span> | |
217 | - <ul> | |
218 | - <li><a class="active" href="#">24</a></li> | |
219 | - <li><a href="#">48</a></li> | |
220 | - <li><a href="#">96</a></li> | |
221 | - </ul>--> | |
222 | - </div> | |
170 | + <div class="show"> | |
171 | + <!--<span>Показывать по:</span> | |
172 | + <ul> | |
173 | + <li><a class="active" href="#">24</a></li> | |
174 | + <li><a href="#">48</a></li> | |
175 | + <li><a href="#">96</a></li> | |
176 | + </ul>--> | |
177 | + </div> | |
223 | 178 | |
224 | - <div class="show_pages"> | |
225 | - <?php if ($pages->totalCount > $pages->pageSize) :?> | |
226 | - <span>Страница:</span> | |
227 | - <?= \yii\widgets\LinkPager::widget([ | |
228 | - 'pagination' => $pages, | |
229 | - 'options' => ['class' => 'pagination pull-right'], | |
230 | - ]); | |
231 | - ?> | |
232 | - <!--<i class="fa fa-caret-right"></i>--> | |
179 | + <?php if ($productProvider->totalCount > $productProvider->pagination->pageSize) :?> | |
180 | + <div class="show_pages"> | |
181 | + Страница: | |
182 | + <?= \yii\widgets\LinkPager::widget([ | |
183 | + 'pagination' => $productProvider->pagination, | |
184 | + 'options' => ['class' => 'pagination pull-right'], | |
185 | + ]); | |
186 | + ?> | |
187 | + <!--<i class="fa fa-caret-right"></i>--> | |
188 | + </div> | |
233 | 189 | <?php endif?> |
234 | - </div> | |
235 | - | |
236 | - </div> | |
237 | - | |
238 | 190 | |
239 | - <div class="cat_p_item_card_list"> | |
240 | - <div class="novelty"> | |
241 | - <div class="content"> | |
242 | - <div class="novelty_cont"> | |
243 | - <?php foreach($products as $product) :?> | |
244 | - <?php require(__DIR__ .'/product_item.php')?> | |
245 | - <?php endforeach?> | |
246 | - </div> | |
191 | + </div> | |
247 | 192 | |
248 | - <?php if ($pages->totalCount > $pages->pageSize) :?> | |
249 | - <!-- LOAD MORE BUTTON --> | |
250 | - <!--button class="load_more_btn">Загрузить еще <?= $per_page?> товара</button--> | |
193 | + <div class="cat_p_item_card_list"> | |
194 | + <div class="novelty"> | |
195 | + <div class="content"> | |
196 | + <div class="novelty_cont"> | |
197 | + <?php foreach($productProvider->models as $product) :?> | |
198 | + <?php require(__DIR__ .'/product_item.php')?> | |
199 | + <?php endforeach?> | |
200 | + </div> | |
251 | 201 | |
252 | - <div class="show_pages"> | |
253 | - Страница: | |
254 | - <?= \yii\widgets\LinkPager::widget([ | |
255 | - 'pagination' => $pages, | |
256 | - 'options' => ['class' => 'pagination pull-right'], | |
257 | - ]); | |
258 | - ?> | |
259 | - <!--<i class="fa fa-caret-right"></i>--> | |
260 | - </div> | |
261 | - <?php endif?> | |
262 | - <hr> | |
202 | + <?php if ($productProvider->totalCount > $productProvider->pagination->pageSize) :?> | |
203 | + <!-- LOAD MORE BUTTON --> | |
204 | + <!--button class="load_more_btn">Загрузить еще <?= $productProvider->pagination->pageSize?> товара</button--> | |
205 | + | |
206 | + <div class="show_pages"> | |
207 | + Страница: | |
208 | + <?= \yii\widgets\LinkPager::widget([ | |
209 | + 'pagination' => $productProvider->pagination, | |
210 | + 'options' => ['class' => 'pagination pull-right'], | |
211 | + ]); | |
212 | + ?> | |
213 | + <!--<i class="fa fa-caret-right"></i>--> | |
214 | + </div> | |
215 | + <?php endif ?> | |
216 | + <hr> | |
263 | 217 | |
264 | - <?php if(!empty($category->description)) :?> | |
265 | - <div class="description"> | |
266 | - <?= $category->description?> | |
218 | + <?php if(!empty($category->description)) :?> | |
219 | + <div class="description"> | |
220 | + <?= $category->description?> | |
267 | 221 | |
268 | - <div class="empty_padding_400"></div> | |
222 | + <div class="empty_padding_400"></div> | |
223 | + </div> | |
224 | + <?php endif?> | |
269 | 225 | </div> |
270 | - <?php endif?> | |
271 | 226 | </div> |
272 | 227 | </div> |
273 | - </div> | |
274 | 228 | |
275 | 229 | <?php endif?> |
276 | 230 | </div> |
277 | -</div> | |
278 | - | |
231 | +</div> | |
279 | 232 | \ No newline at end of file | ... | ... |
frontend/web/css/concat_all.css
... | ... | @@ -104,6 +104,9 @@ |
104 | 104 | .cat_p_filter_bar .filter_list .price_filter a { |
105 | 105 | color: #6aa033; |
106 | 106 | } |
107 | +.cat_p_filter_bar .filter_list .price_filter.active-field { | |
108 | + display: block; | |
109 | +} | |
107 | 110 | |
108 | 111 | .cat_p_filter_bar .filter_list .first_price_li { |
109 | 112 | padding-top: 30px; | ... | ... |
frontend/web/js/my_scripts.js
... | ... | @@ -2,16 +2,6 @@ $(document).ready(function(){ |
2 | 2 | // ion tabs |
3 | 3 | $.ionTabs("#tabs_1"); |
4 | 4 | |
5 | - // price rangeslider (filter price slider) | |
6 | - $("#example_id").ionRangeSlider({ | |
7 | - type: "double", | |
8 | - min: 0, | |
9 | - max: 500, | |
10 | - from: 50, | |
11 | - to: 450, | |
12 | - grid: false | |
13 | - }); | |
14 | - | |
15 | 5 | // ion checkradio init |
16 | 6 | $("input[type='radio'], input[type='checkbox']").ionCheckRadio(); |
17 | 7 | ... | ... |