Commit 5613104b0134fb2ef52223efcdd716a996cb1236
Merge remote-tracking branch 'origin/master'
Showing
30 changed files
with
1001 additions
and
125 deletions
Show diff stats
backend/config/main.php
backend/views/category/_form.php
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | use yii\helpers\Html; |
4 | 4 | use yii\widgets\ActiveForm; |
5 | 5 | use common\modules\file\widgets\ImageUploader; |
6 | +use kartik\select2\Select2; | |
6 | 7 | |
7 | 8 | /* @var $this yii\web\View */ |
8 | 9 | /* @var $model common\modules\product\models\Category */ |
... | ... | @@ -24,10 +25,25 @@ use common\modules\file\widgets\ImageUploader; |
24 | 25 | ] |
25 | 26 | ])->label(Yii::t('product', 'Parent category')) ?> |
26 | 27 | |
28 | + <?php /* | |
27 | 29 | <?= $form->field($model, 'group_to_category')->dropDownList( |
28 | 30 | \yii\helpers\ArrayHelper::map(\common\modules\rubrication\models\TaxGroup::find()->all(), 'tax_group_id', 'name'), [ |
29 | 31 | 'multiple' => true |
30 | 32 | ])->label(Yii::t('product', 'Linked options')) ?> |
33 | + */?> | |
34 | + | |
35 | + <?= $form->field($model, 'group_to_category')->widget(Select2::className(), [ | |
36 | + 'data' => \yii\helpers\ArrayHelper::map(\common\modules\rubrication\models\TaxGroup::find()->all(), 'tax_group_id', 'name'), | |
37 | + 'language' => 'ru', | |
38 | + 'options' => [ | |
39 | + 'placeholder' => 'Linked options', | |
40 | + 'multiple' => true, | |
41 | + ], | |
42 | + 'pluginOptions' => [ | |
43 | + 'allowClear' => true | |
44 | + ], | |
45 | + ] | |
46 | + ) ?> | |
31 | 47 | |
32 | 48 | <?= ImageUploader::widget([ |
33 | 49 | 'model'=> $model, |
... | ... | @@ -52,6 +68,19 @@ use common\modules\file\widgets\ImageUploader; |
52 | 68 | |
53 | 69 | <?= $form->field($model, 'seo_text')->textarea(['rows' => 6]) ?> |
54 | 70 | |
71 | + <?= $form->field($model, 'remote_category')->widget(Select2::className(), [ | |
72 | + 'data' => \yii\helpers\ArrayHelper::map(\common\modules\product\models\RemoteCategories::find()->all(), 'ID', 'Name'), | |
73 | + 'language' => 'ru', | |
74 | + 'options' => [ | |
75 | + 'placeholder' => 'Select a remote category', | |
76 | + 'multiple' => true, | |
77 | + ], | |
78 | + 'pluginOptions' => [ | |
79 | + 'allowClear' => true | |
80 | + ], | |
81 | + ] | |
82 | + ) ?> | |
83 | + | |
55 | 84 | <?php if (!empty($model) && $model->depth == 2) :?> |
56 | 85 | <?= $form->field($model, 'populary')->checkbox() ?> |
57 | 86 | <?php endif?> | ... | ... |
backend/views/category/index.php
1 | 1 | <?php |
2 | 2 | |
3 | 3 | use yii\helpers\Html; |
4 | -use yii\grid\GridView; | |
4 | +use kartik\grid\GridView; | |
5 | 5 | |
6 | 6 | /* @var $this yii\web\View */ |
7 | 7 | /* @var $searchModel common\modules\product\models\CategorySearch */ |
... | ... | @@ -37,12 +37,14 @@ $this->params['breadcrumbs'][] = $this->title; |
37 | 37 | ], |
38 | 38 | [ |
39 | 39 | 'class' => 'yii\grid\ActionColumn', |
40 | - 'template' => '{populary} {view} {update} {delete}', | |
40 | + 'template' => '{view} {update} {delete} {populary}', | |
41 | 41 | 'buttons' => [ |
42 | 42 | 'populary' => function ($url, $model) { |
43 | - return Html::a('<span class="glyphicon glyphicon-star'. ($model->populary ? '' : '-empty') .'"></span>', $url, [ | |
44 | - 'title' => Yii::t('product', ($model->populary ? 'Set not populary' : 'Set populary')), | |
45 | - ]); | |
43 | + if ($model->depth == 2) { | |
44 | + return Html::a('<span class="glyphicon glyphicon-star' . ($model->populary ? '' : '-empty') . '"></span>', $url, [ | |
45 | + 'title' => Yii::t('product', ($model->populary ? 'Set not populary' : 'Set populary')), | |
46 | + ]); | |
47 | + } | |
46 | 48 | }, |
47 | 49 | ], |
48 | 50 | 'urlCreator' => function ($action, $model, $key, $index) { |
... | ... | @@ -63,5 +65,8 @@ $this->params['breadcrumbs'][] = $this->title; |
63 | 65 | } |
64 | 66 | ], |
65 | 67 | ], |
68 | + 'panel' => [ | |
69 | + 'type'=>'success', | |
70 | + ], | |
66 | 71 | ]); ?> |
67 | 72 | </div> | ... | ... |
backend/views/layouts/main-sidebar.php
... | ... | @@ -30,6 +30,7 @@ use yii\widgets\Menu; |
30 | 30 | 'url' => ['/product/manage'], |
31 | 31 | 'items' => [ |
32 | 32 | ['label' => 'Товары', 'url' => ['/product/manage']], |
33 | + ['label' => 'Импорт товаров', 'url' => ['/product/manage/import']], | |
33 | 34 | ['label' => 'Категории', 'url' => ['/category']], |
34 | 35 | ['label' => 'Бренды', 'url' => ['/brand']], |
35 | 36 | ] | ... | ... |
common/components/artboxtree/ArtboxTreeHelper.php
... | ... | @@ -15,6 +15,23 @@ class ArtboxTreeHelper extends Object { |
15 | 15 | return $result; |
16 | 16 | } |
17 | 17 | |
18 | + public static function setArrayField($path, $as_string = false) { | |
19 | + if (is_array($path)) { | |
20 | + if ($as_string) { | |
21 | + foreach ($path as &$item) { | |
22 | + $item = "'$item'"; | |
23 | + } | |
24 | + } | |
25 | + $path = implode(',', $path); | |
26 | + } | |
27 | + return '{'. $path .'}'; | |
28 | + } | |
29 | + | |
30 | + public static function getArrayField($path) { | |
31 | + $path = trim($path, '{}'); | |
32 | + return empty($path) ? [] : explode(',', $path); | |
33 | + } | |
34 | + | |
18 | 35 | protected static function _recursiveTreeMap(&$result, $tree, $from, $to, $symbol = '–') { |
19 | 36 | foreach ($tree as $item) { |
20 | 37 | $element = $item['item']; | ... | ... |
common/modules/product/CatalogUrlManager.php
... | ... | @@ -41,8 +41,8 @@ class CatalogUrlManager implements UrlRuleInterface { |
41 | 41 | } |
42 | 42 | $params['category'] = $category; |
43 | 43 | } |
44 | - // Filter | |
45 | 44 | if (!empty($paths[2])) { |
45 | + // Filter | |
46 | 46 | if (strpos($paths[2], 'filter:') === 0) { |
47 | 47 | $params['filter'] = []; |
48 | 48 | $filter_str = substr($paths[2], 7); |
... | ... | @@ -65,6 +65,8 @@ class CatalogUrlManager implements UrlRuleInterface { |
65 | 65 | } |
66 | 66 | |
67 | 67 | } |
68 | + } elseif (strpos($paths[2], 'word:') === 0) { | |
69 | + $params['word'] = substr($paths[2], 5); | |
68 | 70 | } |
69 | 71 | } |
70 | 72 | } elseif ($paths[0] == 'product') { |
... | ... | @@ -99,8 +101,17 @@ class CatalogUrlManager implements UrlRuleInterface { |
99 | 101 | case 'catalog/category': |
100 | 102 | if (!empty($params['category'])) { |
101 | 103 | $category_alias = is_object($params['category']) ? $params['category']->alias : strtolower($params['category']); |
104 | + $url = 'catalog/'. $category_alias .'/'; | |
105 | + } else { | |
106 | + $url = 'catalog/'; | |
107 | + } | |
108 | + | |
109 | + if (!empty($params['word'])) { | |
110 | + if (!is_array($params['word'])) { | |
111 | + $params['word'] = [$params['word']]; | |
112 | + } | |
113 | + $url .= 'word:'. implode(';', $params['word']); | |
102 | 114 | } |
103 | - $url = 'catalog/'. $category_alias .'/'; | |
104 | 115 | |
105 | 116 | $filter = []; |
106 | 117 | if (!empty($params['filter'])) { |
... | ... | @@ -135,6 +146,7 @@ class CatalogUrlManager implements UrlRuleInterface { |
135 | 146 | } |
136 | 147 | $url .= 'filter:'. implode(';', $filter); |
137 | 148 | } |
149 | + | |
138 | 150 | return $url; |
139 | 151 | break; |
140 | 152 | ... | ... |
common/modules/product/controllers/ManageController.php
... | ... | @@ -5,6 +5,7 @@ namespace common\modules\product\controllers; |
5 | 5 | use common\modules\product\helpers\ProductHelper; |
6 | 6 | use common\modules\product\models\Category; |
7 | 7 | use common\modules\product\models\ProductVariant; |
8 | +use common\modules\product\models\RemoteProductsSearch; | |
8 | 9 | use Yii; |
9 | 10 | use common\modules\product\models\Product; |
10 | 11 | use common\modules\product\models\ProductSearch; |
... | ... | @@ -162,6 +163,16 @@ class ManageController extends Controller |
162 | 163 | return $this->redirect(['index']); |
163 | 164 | } |
164 | 165 | |
166 | + public function actionImport() { | |
167 | + $searchModel = new RemoteProductsSearch(); | |
168 | + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); | |
169 | + | |
170 | + return $this->render('remote-products', [ | |
171 | + 'searchModel' => $searchModel, | |
172 | + 'dataProvider' => $dataProvider, | |
173 | + ]); | |
174 | + } | |
175 | + | |
165 | 176 | /** |
166 | 177 | * Finds the Product model based on its primary key value. |
167 | 178 | * If the model is not found, a 404 HTTP exception will be thrown. | ... | ... |
common/modules/product/helpers/ProductHelper.php
... | ... | @@ -4,7 +4,9 @@ namespace common\modules\product\helpers; |
4 | 4 | |
5 | 5 | use common\modules\product\models\Brand; |
6 | 6 | use common\modules\product\models\Category; |
7 | +use common\modules\product\models\Product; | |
7 | 8 | use yii\base\Object; |
9 | +use Yii; | |
8 | 10 | |
9 | 11 | class ProductHelper extends Object { |
10 | 12 | public static function getCategories() { |
... | ... | @@ -55,4 +57,20 @@ class ProductHelper extends Object { |
55 | 57 | } |
56 | 58 | return $result; |
57 | 59 | } |
60 | + | |
61 | + public static function addLastProsucts($product_id) { | |
62 | + $last_products = self::getLastProducts(); | |
63 | + if (!in_array($product_id, $last_products)) { | |
64 | + $last_products[] = $product_id; | |
65 | + Yii::$app->session->set('last_products', $last_products); | |
66 | + } | |
67 | + } | |
68 | + | |
69 | + public static function getLastProducts($as_object = false) { | |
70 | + $last_products = Yii::$app->session->get('last_products', []); | |
71 | + if ($as_object) { | |
72 | + $last_products = Product::find()->where(['product_id' => $last_products])->all(); | |
73 | + } | |
74 | + return $last_products; | |
75 | + } | |
58 | 76 | } |
59 | 77 | \ No newline at end of file | ... | ... |
common/modules/product/models/BrandSearch.php
... | ... | @@ -73,7 +73,7 @@ class BrandSearch extends Brand |
73 | 73 | return $dataProvider; |
74 | 74 | } |
75 | 75 | |
76 | - public function getBrands($category, $params) { | |
76 | + public function getBrands($category = null, $params = []) { | |
77 | 77 | $query = Brand::find() |
78 | 78 | ->select([ |
79 | 79 | Brand::tableName() .'.*', |
... | ... | @@ -82,11 +82,13 @@ class BrandSearch extends Brand |
82 | 82 | ->innerJoin(Product::tableName(), Product::tableName() .'.brand_id='. Brand::tableName() .'.brand_id') |
83 | 83 | ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. Product::tableName() .'.product_id') |
84 | 84 | |
85 | - ->with('brandName') | |
86 | - ->where([ | |
85 | + ->with('brandName'); | |
86 | + if (!empty($category)) { | |
87 | + $query->where([ | |
87 | 88 | ProductCategory::tableName() .'.category_id' => $category->category_id |
88 | - ]) | |
89 | - ->groupBy(Brand::tableName() .'.brand_id'); | |
89 | + ]); | |
90 | + } | |
91 | + $query->groupBy(Brand::tableName() .'.brand_id'); | |
90 | 92 | if (isset($params['options'])) { |
91 | 93 | unset($params['options']); |
92 | 94 | } | ... | ... |
common/modules/product/models/Category.php
... | ... | @@ -4,6 +4,7 @@ namespace common\modules\product\models; |
4 | 4 | |
5 | 5 | use common\behaviors\RuSlug; |
6 | 6 | use common\components\artboxtree\ArtboxTreeBehavior; |
7 | +use common\components\artboxtree\ArtboxTreeHelper; | |
7 | 8 | use common\modules\relation\relationBehavior; |
8 | 9 | use common\modules\rubrication\behaviors\ArtboxSynonymBehavior; |
9 | 10 | use Yii; |
... | ... | @@ -12,6 +13,7 @@ use Yii; |
12 | 13 | * This is the model class for table "category". |
13 | 14 | * |
14 | 15 | * @property integer $category_id |
16 | + * @property string $remote_id | |
15 | 17 | * @property integer $parent_id |
16 | 18 | * @property string $path |
17 | 19 | * @property integer $depth |
... | ... | @@ -86,7 +88,7 @@ class Category extends \yii\db\ActiveRecord |
86 | 88 | [['meta_robots'], 'string', 'max' => 50], |
87 | 89 | [['alias', 'name'], 'string', 'max' => 250], |
88 | 90 | [['populary'], 'boolean'], |
89 | - [['group_to_category'], 'safe'], | |
91 | + [['group_to_category', 'remote_category'], 'safe'], | |
90 | 92 | [['category_name_id'], 'exist', 'skipOnError' => true, 'targetClass' => CategoryName::className(), 'targetAttribute' => ['category_name_id' => 'category_name_id']], |
91 | 93 | // [['image'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg, gif'], |
92 | 94 | // [['product_unit_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductUnit::className(), 'targetAttribute' => ['product_unit_id' => 'product_unit_id']], |
... | ... | @@ -112,6 +114,7 @@ class Category extends \yii\db\ActiveRecord |
112 | 114 | 'alias' => Yii::t('product', 'Alias'), |
113 | 115 | 'populary' => Yii::t('product', 'Populary'), |
114 | 116 | 'name' => Yii::t('product', 'Name'), |
117 | + 'remote_id' => Yii::t('product', 'Remote ID'), | |
115 | 118 | ]; |
116 | 119 | } |
117 | 120 | |
... | ... | @@ -147,15 +150,14 @@ class Category extends \yii\db\ActiveRecord |
147 | 150 | return $this->getRelations('tax_group_to_category'); |
148 | 151 | } |
149 | 152 | |
150 | - public function beforeSave($insert) | |
151 | - { | |
152 | - if (parent::beforeSave($insert)) { | |
153 | + public function getRemote_category() { | |
154 | + return ArtboxTreeHelper::getArrayField($this->remote_id); | |
155 | + } | |
153 | 156 | |
154 | - if (empty($this->parent_id)) | |
155 | - $this->parent_id = 0; | |
156 | - return true; | |
157 | + public function setRemote_category($value) { | |
158 | + if (!empty($value) && is_array($value)) { | |
159 | + $this->remote_id = ArtboxTreeHelper::setArrayField($value, false); | |
157 | 160 | } |
158 | - return false; | |
159 | 161 | } |
160 | 162 | |
161 | 163 | public function getCategoryName() { |
... | ... | @@ -165,4 +167,16 @@ class Category extends \yii\db\ActiveRecord |
165 | 167 | public function getName() { |
166 | 168 | return empty($this->categoryName) ? null : $this->categoryName->value; |
167 | 169 | } |
170 | + | |
171 | + public function beforeSave($insert) | |
172 | + { | |
173 | + if (parent::beforeSave($insert)) { | |
174 | + | |
175 | + if (empty($this->parent_id)) | |
176 | + $this->parent_id = 0; | |
177 | + | |
178 | + return true; | |
179 | + } | |
180 | + return false; | |
181 | + } | |
168 | 182 | } | ... | ... |
common/modules/product/models/CategorySearch.php
... | ... | @@ -2,6 +2,7 @@ |
2 | 2 | |
3 | 3 | namespace common\modules\product\models; |
4 | 4 | |
5 | +use common\components\artboxtree\ArtboxTreeHelper; | |
5 | 6 | use Yii; |
6 | 7 | use yii\base\Model; |
7 | 8 | use yii\data\ActiveDataProvider; |
... | ... | @@ -97,4 +98,19 @@ class CategorySearch extends Category |
97 | 98 | throw new NotFoundHttpException('The requested page does not exist.'); |
98 | 99 | } |
99 | 100 | } |
101 | + | |
102 | + public static function findByRemoteID($id) { | |
103 | + /** @var CategoryQuery $query */ | |
104 | + $query = Category::find() | |
105 | + ->with('categoryName') | |
106 | + ->andFilterWhere(['@>', 'remote_id', ArtboxTreeHelper::setArrayField($id)]); | |
107 | + if (($model = $query->one()) !== null) { | |
108 | + return $model; | |
109 | + } | |
110 | + return null; | |
111 | + } | |
112 | + | |
113 | +// public static function findByProductsKeywords($keywords = [], $category = null) { | |
114 | +// | |
115 | +// } | |
100 | 116 | } | ... | ... |
common/modules/product/models/ProductSearch.php
... | ... | @@ -80,4 +80,13 @@ class ProductSearch extends Product |
80 | 80 | } |
81 | 81 | } |
82 | 82 | |
83 | + public static function findByRemoteID($id) { | |
84 | + /** @var CategoryQuery $query */ | |
85 | + $query = Product::find() | |
86 | + ->andFilterWhere(['remote_id' => $id]); | |
87 | + if (($model = $query->one()) !== null) { | |
88 | + return $model; | |
89 | + } | |
90 | + return null; | |
91 | + } | |
83 | 92 | } | ... | ... |
common/modules/product/models/ProductVariant.php
... | ... | @@ -10,6 +10,7 @@ use Yii; |
10 | 10 | * @property integer $product_variant_id |
11 | 11 | * @property integer $product_id |
12 | 12 | * @property string $name |
13 | + * @property string $remote_id | |
13 | 14 | * @property string $sku |
14 | 15 | * @property double $price |
15 | 16 | * @property double $price_old |
... | ... | @@ -34,10 +35,11 @@ class ProductVariant extends \yii\db\ActiveRecord |
34 | 35 | public function rules() |
35 | 36 | { |
36 | 37 | return [ |
37 | - [['product_id', 'name', 'sku', 'product_unit_id'], 'required'], | |
38 | + [['product_id', 'sku', 'product_unit_id'], 'required'], | |
38 | 39 | [['product_id', 'product_unit_id'], 'integer'], |
39 | 40 | [['price', 'price_old', 'stock'], 'number'], |
40 | 41 | [['name', 'sku'], 'string', 'max' => 255], |
42 | + [['remote_id'], 'string', 'max' => 20], | |
41 | 43 | [['product_unit_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductUnit::className(), 'targetAttribute' => ['product_unit_id' => 'product_unit_id']], |
42 | 44 | ]; |
43 | 45 | } | ... | ... |
common/modules/product/models/ProductVariantSearch.php
0 → 100644
1 | +<?php | |
2 | + | |
3 | +namespace common\modules\product\models; | |
4 | + | |
5 | +use Yii; | |
6 | +use yii\base\Model; | |
7 | +use yii\data\ActiveDataProvider; | |
8 | +use yii\web\NotFoundHttpException; | |
9 | + | |
10 | +/** | |
11 | + * ProductVariantSearch represents the model behind the search form about `common\modules\product\models\ProductVariant`. | |
12 | + */ | |
13 | +class ProductVariantSearch extends ProductVariant | |
14 | +{ | |
15 | + /** | |
16 | + * @inheritdoc | |
17 | + */ | |
18 | + public function rules() | |
19 | + { | |
20 | + return [ | |
21 | + [['name', 'sku', 'price', 'price_old', 'stock'], 'safe'], | |
22 | + [['product_variant_id', 'product_id'], 'integer'], | |
23 | + ]; | |
24 | + } | |
25 | + | |
26 | + /** | |
27 | + * @inheritdoc | |
28 | + */ | |
29 | + public function scenarios() | |
30 | + { | |
31 | + // bypass scenarios() implementation in the parent class | |
32 | + return Model::scenarios(); | |
33 | + } | |
34 | + | |
35 | + /** | |
36 | + * Creates data provider instance with search query applied | |
37 | + * | |
38 | + * @param array $params | |
39 | + * | |
40 | + * @return ActiveDataProvider | |
41 | + */ | |
42 | + public function search($params) | |
43 | + { | |
44 | + $query = Product::find(); | |
45 | + | |
46 | + // add conditions that should always apply here | |
47 | + | |
48 | + $dataProvider = new ActiveDataProvider([ | |
49 | + 'query' => $query, | |
50 | + ]); | |
51 | + | |
52 | + $this->load($params); | |
53 | + | |
54 | + if (!$this->validate()) { | |
55 | + // uncomment the following line if you do not want to return any records when validation fails | |
56 | + // $query->where('0=1'); | |
57 | + return $dataProvider; | |
58 | + } | |
59 | + | |
60 | + // grid filtering conditions | |
61 | + $query->andFilterWhere([ | |
62 | + 'product_variant_id' => $this->product_variant_id, | |
63 | + 'product_id' => $this->product_id, | |
64 | + ]); | |
65 | + | |
66 | + $query->andFilterWhere(['like', 'name', $this->name]) | |
67 | + ->andFilterWhere(['like', 'sku', $this->sku]); | |
68 | + | |
69 | + return $dataProvider; | |
70 | + } | |
71 | + | |
72 | + public static function findBySku($sku) { | |
73 | + /** @var ProductQuery $query */ | |
74 | + $query = ProductVariant::find() | |
75 | + ->andFilterWhere(['sku' => $sku]); | |
76 | + if (($model = $query->one()) !== null) { | |
77 | + return $model; | |
78 | + } | |
79 | + return; | |
80 | + } | |
81 | + | |
82 | + public static function findByRemoteID($id) { | |
83 | + /** @var CategoryQuery $query */ | |
84 | + $query = ProductVariant::find() | |
85 | + ->andFilterWhere(['remote_id' => $id]); | |
86 | + if (($model = $query->one()) !== null) { | |
87 | + return $model; | |
88 | + } | |
89 | + return; | |
90 | + } | |
91 | +} | ... | ... |
1 | +<?php | |
2 | + | |
3 | +namespace common\modules\product\models; | |
4 | + | |
5 | +use Yii; | |
6 | + | |
7 | +/** | |
8 | + * This is the model class for table "remote_categories". | |
9 | + * | |
10 | + * @property string $Name | |
11 | + * @property string $ID_chief | |
12 | + * @property string $ID | |
13 | + */ | |
14 | +class RemoteCategories extends \yii\db\ActiveRecord | |
15 | +{ | |
16 | + /** | |
17 | + * @inheritdoc | |
18 | + */ | |
19 | + public static function tableName() | |
20 | + { | |
21 | + return 'remote_categories'; | |
22 | + } | |
23 | + | |
24 | + /** | |
25 | + * @inheritdoc | |
26 | + */ | |
27 | + public function rules() | |
28 | + { | |
29 | + return [ | |
30 | + [['Name'], 'string', 'max' => 100], | |
31 | + [['ID_chief', 'ID'], 'string', 'max' => 20], | |
32 | + ]; | |
33 | + } | |
34 | + | |
35 | + /** | |
36 | + * @inheritdoc | |
37 | + */ | |
38 | + public function attributeLabels() | |
39 | + { | |
40 | + return [ | |
41 | + 'Name' => Yii::t('product', 'Name'), | |
42 | + 'ID_chief' => Yii::t('product', 'Id Chief'), | |
43 | + 'ID' => Yii::t('product', 'ID'), | |
44 | + ]; | |
45 | + } | |
46 | + | |
47 | + public function getCategory() { | |
48 | + if (empty($this->ID)) { | |
49 | + return null; | |
50 | + } | |
51 | + return CategorySearch::findByRemoteID($this->ID); | |
52 | + } | |
53 | + | |
54 | + public static function findByID($id) { | |
55 | + /** @var CategoryQuery $query */ | |
56 | + $query = RemoteCategories::find() | |
57 | + ->andFilterWhere(['ID' => $id]); | |
58 | + if (($model = $query->one()) !== null) { | |
59 | + return $model; | |
60 | + } | |
61 | + return null; | |
62 | + } | |
63 | +} | ... | ... |
common/modules/product/models/RemoteCategoriesSearch.php
0 → 100644
1 | +<?php | |
2 | + | |
3 | +namespace common\modules\product\models; | |
4 | + | |
5 | +use Yii; | |
6 | +use yii\base\Model; | |
7 | +use yii\data\ActiveDataProvider; | |
8 | +use common\modules\product\models\RemoteCategories; | |
9 | + | |
10 | +/** | |
11 | + * RemoteCategoriesSearch represents the model behind the search form about `common\modules\product\models\RemoteCategories`. | |
12 | + */ | |
13 | +class RemoteCategoriesSearch extends RemoteCategories | |
14 | +{ | |
15 | + /** | |
16 | + * @inheritdoc | |
17 | + */ | |
18 | + public function rules() | |
19 | + { | |
20 | + return [ | |
21 | + [['Name', 'ID_chief', 'ID'], 'safe'], | |
22 | + [['local_id'], 'integer'], | |
23 | + ]; | |
24 | + } | |
25 | + | |
26 | + /** | |
27 | + * @inheritdoc | |
28 | + */ | |
29 | + public function scenarios() | |
30 | + { | |
31 | + // bypass scenarios() implementation in the parent class | |
32 | + return Model::scenarios(); | |
33 | + } | |
34 | + | |
35 | + /** | |
36 | + * Creates data provider instance with search query applied | |
37 | + * | |
38 | + * @param array $params | |
39 | + * | |
40 | + * @return ActiveDataProvider | |
41 | + */ | |
42 | + public function search($params) | |
43 | + { | |
44 | + $query = RemoteCategories::find(); | |
45 | + | |
46 | + // add conditions that should always apply here | |
47 | + | |
48 | + $dataProvider = new ActiveDataProvider([ | |
49 | + 'query' => $query, | |
50 | + ]); | |
51 | + | |
52 | + $this->load($params); | |
53 | + | |
54 | + if (!$this->validate()) { | |
55 | + // uncomment the following line if you do not want to return any records when validation fails | |
56 | + // $query->where('0=1'); | |
57 | + return $dataProvider; | |
58 | + } | |
59 | + | |
60 | + // grid filtering conditions | |
61 | + $query->andFilterWhere([ | |
62 | + 'local_id' => $this->local_id, | |
63 | + ]); | |
64 | + | |
65 | + $query->andFilterWhere(['like', 'Name', $this->Name]) | |
66 | + ->andFilterWhere(['like', 'ID_chief', $this->ID_chief]) | |
67 | + ->andFilterWhere(['like', 'ID', $this->ID]); | |
68 | + | |
69 | + return $dataProvider; | |
70 | + } | |
71 | +} | ... | ... |
1 | +<?php | |
2 | + | |
3 | +namespace common\modules\product\models; | |
4 | + | |
5 | +use Yii; | |
6 | + | |
7 | +/** | |
8 | + * This is the model class for table "remote_products". | |
9 | + * | |
10 | + * @property string $Name | |
11 | + * @property string $Price | |
12 | + * @property string $Price_old | |
13 | + * @property string $ID_chief | |
14 | + * @property string $Article | |
15 | + * @property string $Brand | |
16 | + * @property string $ID | |
17 | + * @property string $Date_create | |
18 | + * @property integer $local_id | |
19 | + * @property ProductVariant $product | |
20 | + * @property RemoteCategories $remoteCategory | |
21 | + */ | |
22 | +class RemoteProducts extends \yii\db\ActiveRecord | |
23 | +{ | |
24 | + /** | |
25 | + * @inheritdoc | |
26 | + */ | |
27 | + public static function tableName() | |
28 | + { | |
29 | + return 'remote_products'; | |
30 | + } | |
31 | + | |
32 | + /** | |
33 | + * @inheritdoc | |
34 | + */ | |
35 | + public function rules() | |
36 | + { | |
37 | + return [ | |
38 | + [['Price', 'Price_old'], 'number'], | |
39 | + [['Date_create'], 'safe'], | |
40 | + [['Name'], 'string', 'max' => 100], | |
41 | + [['ID_chief', 'Article', 'ID'], 'string', 'max' => 20], | |
42 | + [['Brand'], 'string', 'max' => 25], | |
43 | + ]; | |
44 | + } | |
45 | + | |
46 | + /** | |
47 | + * @inheritdoc | |
48 | + */ | |
49 | + public function attributeLabels() | |
50 | + { | |
51 | + return [ | |
52 | + 'Name' => Yii::t('product', 'Name'), | |
53 | + 'Price' => Yii::t('product', 'Price'), | |
54 | + 'Price_old' => Yii::t('product', 'Price Old'), | |
55 | + 'ID_chief' => Yii::t('product', 'Id Chief'), | |
56 | + 'Article' => Yii::t('product', 'Article'), | |
57 | + 'Brand' => Yii::t('product', 'Brand'), | |
58 | + 'ID' => Yii::t('product', 'ID'), | |
59 | + 'Date_create' => Yii::t('product', 'Date Create'), | |
60 | + 'local_id' => Yii::t('product', 'Local ID'), | |
61 | + ]; | |
62 | + } | |
63 | + | |
64 | + public function getRemoteCategory() { | |
65 | + if (empty($this->ID_chief)) { | |
66 | + return null; | |
67 | + } | |
68 | + return RemoteCategories::findByID($this->ID_chief); | |
69 | + } | |
70 | + | |
71 | + public function getProduct() { | |
72 | + if (empty($this->ID)) { | |
73 | + return null; | |
74 | + } | |
75 | + return ProductVariantSearch::findByRemoteID($this->ID); | |
76 | + } | |
77 | +} | ... | ... |
common/modules/product/models/RemoteProductsSearch.php
0 → 100644
1 | +<?php | |
2 | + | |
3 | +namespace common\modules\product\models; | |
4 | + | |
5 | +use Yii; | |
6 | +use yii\base\Model; | |
7 | +use yii\data\ActiveDataProvider; | |
8 | +use common\modules\product\models\RemoteProducts; | |
9 | + | |
10 | +/** | |
11 | + * RemoteProductsSearch represents the model behind the search form about `common\modules\product\models\RemoteProducts`. | |
12 | + */ | |
13 | +class RemoteProductsSearch extends RemoteProducts | |
14 | +{ | |
15 | + /** | |
16 | + * @inheritdoc | |
17 | + */ | |
18 | + public function rules() | |
19 | + { | |
20 | + return [ | |
21 | + [['Name', 'ID_chief', 'Article', 'Brand', 'ID', 'Date_create'], 'safe'], | |
22 | + [['Price', 'Price_old'], 'number'], | |
23 | + [['local_id'], 'integer'], | |
24 | + ]; | |
25 | + } | |
26 | + | |
27 | + /** | |
28 | + * @inheritdoc | |
29 | + */ | |
30 | + public function scenarios() | |
31 | + { | |
32 | + // bypass scenarios() implementation in the parent class | |
33 | + return Model::scenarios(); | |
34 | + } | |
35 | + | |
36 | + /** | |
37 | + * Creates data provider instance with search query applied | |
38 | + * | |
39 | + * @param array $params | |
40 | + * | |
41 | + * @return ActiveDataProvider | |
42 | + */ | |
43 | + public function search($params) | |
44 | + { | |
45 | + $query = RemoteProducts::find(); | |
46 | + | |
47 | + // add conditions that should always apply here | |
48 | + | |
49 | + $dataProvider = new ActiveDataProvider([ | |
50 | + 'query' => $query, | |
51 | + ]); | |
52 | + | |
53 | + $this->load($params); | |
54 | + | |
55 | + if (!$this->validate()) { | |
56 | + // uncomment the following line if you do not want to return any records when validation fails | |
57 | + // $query->where('0=1'); | |
58 | + return $dataProvider; | |
59 | + } | |
60 | + | |
61 | + // grid filtering conditions | |
62 | + $query->andFilterWhere([ | |
63 | + 'Price' => $this->Price, | |
64 | + 'Price_old' => $this->Price_old, | |
65 | + 'Date_create' => $this->Date_create, | |
66 | + 'local_id' => $this->local_id, | |
67 | + ]); | |
68 | + | |
69 | + $query->andFilterWhere(['like', 'Name', $this->Name]) | |
70 | + ->andFilterWhere(['like', 'ID_chief', $this->ID_chief]) | |
71 | + ->andFilterWhere(['like', 'Article', $this->Article]) | |
72 | + ->andFilterWhere(['like', 'Brand', $this->Brand]) | |
73 | + ->andFilterWhere(['like', 'ID', $this->ID]); | |
74 | + | |
75 | + return $dataProvider; | |
76 | + } | |
77 | +} | ... | ... |
common/modules/product/views/manage/_form.php
... | ... | @@ -8,6 +8,7 @@ use common\modules\product\helpers\ProductHelper; |
8 | 8 | use kartik\file\FileInput; |
9 | 9 | use unclead\widgets\MultipleInput; |
10 | 10 | use unclead\widgets\MultipleInputColumn; |
11 | +use kartik\select2\Select2; | |
11 | 12 | |
12 | 13 | /* @var $this yii\web\View */ |
13 | 14 | /* @var $model common\modules\product\models\Product */ |
... | ... | @@ -30,9 +31,9 @@ use unclead\widgets\MultipleInputColumn; |
30 | 31 | ] |
31 | 32 | ) ?> |
32 | 33 | |
33 | - <?= $form->field($model, 'categories')->widget(\kartik\select2\Select2::className(), [ | |
34 | + <?= $form->field($model, 'categories')->widget(Select2::className(), [ | |
34 | 35 | 'data' => ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'category_id', 'name'), |
35 | - 'language' => 'de', | |
36 | + 'language' => 'ru', | |
36 | 37 | 'options' => [ |
37 | 38 | 'placeholder' => 'Select a state ...', |
38 | 39 | 'multiple' => true, | ... | ... |
common/modules/product/views/manage/remote-products.php
0 → 100644
1 | +<?php | |
2 | + | |
3 | +use yii\helpers\Html; | |
4 | +use kartik\grid\GridView; | |
5 | + | |
6 | +/* @var $this yii\web\View */ | |
7 | +/* @var $searchModel common\modules\product\models\RemoteProductsSearch */ | |
8 | +/* @var $dataProvider yii\data\ActiveDataProvider */ | |
9 | + | |
10 | +$this->title = Yii::t('product', 'Remote Products'); | |
11 | +$this->params['breadcrumbs'][] = $this->title; | |
12 | +?> | |
13 | +<div class="remote-products-index"> | |
14 | + | |
15 | + <h1><?= Html::encode($this->title) ?></h1> | |
16 | + <?php // echo $this->render('_search', ['model' => $searchModel]); ?> | |
17 | + | |
18 | + <p> | |
19 | + <?= Html::a(Yii::t('product', 'Import selected'), ['import'], ['class' => 'btn btn-success']) ?> | |
20 | + </p> | |
21 | + <?= GridView::widget([ | |
22 | + 'dataProvider' => $dataProvider, | |
23 | + 'filterModel' => $searchModel, | |
24 | + 'columns' => [ | |
25 | + ['class' => 'yii\grid\SerialColumn'], | |
26 | + | |
27 | + 'Name', | |
28 | + 'ID_chief', | |
29 | + 'Article', | |
30 | + 'Price', | |
31 | + 'Price_old', | |
32 | + 'Brand', | |
33 | + 'ID', | |
34 | + 'Date_create', | |
35 | + 'remoteCategory.category.name', | |
36 | + 'remoteCategory.Name', | |
37 | + // 'local_id', | |
38 | + | |
39 | + ['class' => 'yii\grid\ActionColumn'], | |
40 | + ], | |
41 | + ]); ?> | |
42 | +</div> | ... | ... |
common/translation/ru/product.php
... | ... | @@ -5,4 +5,7 @@ return [ |
5 | 5 | 'Name' => 'Наименование', |
6 | 6 | 'Set populary' => 'Сделать популярной', |
7 | 7 | 'Set not populary' => 'Сделать не популярной', |
8 | + 'Remote ID' => 'ID в 1С', | |
9 | + 'Search for "{keywords}"' => 'Поиск по "{keywords}"', | |
10 | + 'Search for "{keywords}" in category "{category}"' => 'Поиск по "{keywords}" в категории "{category}"', | |
8 | 11 | ]; |
9 | 12 | \ No newline at end of file | ... | ... |
1 | +<?php | |
2 | + | |
3 | +namespace console\controllers; | |
4 | + | |
5 | +use common\modules\product\models\Brand; | |
6 | +use common\modules\product\models\BrandName; | |
7 | +use common\modules\product\models\Product; | |
8 | +use common\modules\product\models\ProductVariant; | |
9 | +use common\modules\product\models\RemoteProducts; | |
10 | +use yii\console\Controller; | |
11 | +use yii\helpers\Console; | |
12 | + | |
13 | +class ImportController extends Controller { | |
14 | + | |
15 | + public function actionIndex($section) { | |
16 | + $method = 'go'. ucfirst(strtolower($section)); | |
17 | + if (!method_exists($this, $method)) { | |
18 | + print $this->stdout("What is $section?\n"); | |
19 | + return Controller::EXIT_CODE_ERROR; | |
20 | + } | |
21 | + | |
22 | + $this->$method(); | |
23 | + | |
24 | + return Controller::EXIT_CODE_NORMAL; | |
25 | + } | |
26 | + | |
27 | + public function goGo() { | |
28 | + $new_products = $linked_products = 0; | |
29 | + foreach(RemoteProducts::find()->all() as $product) { | |
30 | + if (!empty($product->product->product_id)) { | |
31 | + $linked_products++; | |
32 | + | |
33 | + $_productVariant = ProductVariant::findOne($product->product->product_id); | |
34 | + $_product = Product::findOne($_productVariant->product_id); | |
35 | + | |
36 | + if ( | |
37 | + $_product->name != $product->Name || | |
38 | + $_product->categories != [$product->remoteCategory->category->category_id] || | |
39 | + ($product->Brand && ($brand = BrandName::find()->filterWhere(['like', 'value', trim($product->Brand)])->one()) !== null && $_product->brand_id != $brand->brand_id) | |
40 | + ) { | |
41 | + $_product->name = $product->Name; | |
42 | + $_product->categories = [$product->remoteCategory->category->category_id]; | |
43 | + if ( $product->Brand ) { | |
44 | + if ( ($brand = BrandName::find()->filterWhere(['like', 'value', trim($product->Brand)])->one()) !== null ) { | |
45 | + $_product->brand_id = $brand->brand_id; | |
46 | + } else { | |
47 | + // Create brand | |
48 | + $brand = new Brand(); | |
49 | + $brand->name = trim($product->Brand); | |
50 | + $brand->save(); | |
51 | + $_product->brand_id = $brand->brand_id; | |
52 | + } | |
53 | + } | |
54 | + $_product->save(); | |
55 | + } | |
56 | + | |
57 | + if ( | |
58 | + $_productVariant->price != floatval($product->Price) || | |
59 | + $_productVariant->price_old != floatval($product->Price_old) || | |
60 | + (!empty($product->Article) && $_productVariant->sku != $product->Article) | |
61 | + ) { | |
62 | + $_productVariant->price = floatval($product->Price); | |
63 | + $_productVariant->price_old = floatval($product->Price_old); | |
64 | + $_productVariant->sku = empty($product->Article) ? uniqid('gds_') : $product->Article; | |
65 | + if (!$_productVariant->price) { | |
66 | + $_productVariant->stock = 0; | |
67 | + } | |
68 | + $_productVariant->save(); | |
69 | + } | |
70 | + } elseif (!empty($product->remoteCategory) && !empty($product->remoteCategory->category) && !empty($product->remoteCategory->category->category_id)) { | |
71 | + $new_products++; | |
72 | + | |
73 | + $_product = new Product(); | |
74 | + $_productVariant = new ProductVariant(); | |
75 | + $_product->name = $product->Name; | |
76 | + $_product->categories = [$product->remoteCategory->category->category_id]; | |
77 | + | |
78 | + if ( $product->Brand ) { | |
79 | + if ( ($brand = BrandName::find()->filterWhere(['like', 'value', trim($product->Brand)])->one()) !== null ) { | |
80 | + $_product->brand_id = $brand->brand_id; | |
81 | + } else { | |
82 | + // Create brand | |
83 | + $brand = new Brand(); | |
84 | + $brand->name = trim($product->Brand); | |
85 | + $brand->save(); | |
86 | + $_product->brand_id = $brand->brand_id; | |
87 | + } | |
88 | + } | |
89 | + | |
90 | + $_productVariant->price = floatval($product->Price); | |
91 | + $_productVariant->price_old = floatval($product->Price_old); | |
92 | + $_productVariant->sku = empty($product->Article) ? uniqid('gds_') : $product->Article; | |
93 | + $_productVariant->product_unit_id = 1; | |
94 | + $_productVariant->remote_id = $product->ID; | |
95 | + $_productVariant->stock = $_productVariant->price > 0 ? null : 0; | |
96 | + | |
97 | + if (!$_product->save()) { | |
98 | + print $this->stdout("Saved error for the {$_product->name} {$_product->product_id}?\n"); | |
99 | + return Controller::EXIT_CODE_ERROR; | |
100 | + } | |
101 | + | |
102 | + $_productVariant->product_id = $_product->product_id; | |
103 | + if (!$_productVariant->save()) { | |
104 | + print $this->stdout("Saved error for variant of the {$_product->name} {$_product->product_id}?\n"); | |
105 | + return Controller::EXIT_CODE_ERROR; | |
106 | + } | |
107 | + } | |
108 | + } | |
109 | + | |
110 | + $this->goStat(); | |
111 | + } | |
112 | + | |
113 | + public function goStat() { | |
114 | + $all_products = $new_products = $linked_products = $orpahed_products = 0; | |
115 | + $remoteProducts = RemoteProducts::find()->all(); | |
116 | + | |
117 | + $not_linked_cats = []; | |
118 | + | |
119 | + foreach($remoteProducts as $product) { | |
120 | + if (!empty($product->product->product_id)) { | |
121 | + $linked_products++; | |
122 | + } elseif (!empty($product->remoteCategory) && !empty($product->remoteCategory->category) && !empty($product->remoteCategory->category->category_id)) { | |
123 | + $new_products++; | |
124 | + } else { | |
125 | + if (!empty($product->remoteCategory)) { | |
126 | + if (empty($not_linked_cats[$product->remoteCategory->ID])) { | |
127 | + $not_linked_cats[$product->remoteCategory->ID] = $product->remoteCategory->Name ." (". $product->remoteCategory->ID .")\n"; | |
128 | + } | |
129 | + } | |
130 | + $orpahed_products++; | |
131 | + } | |
132 | + $all_products++; | |
133 | + } | |
134 | + | |
135 | + $this->stdout("Всего $all_products товаров, $new_products новых и $linked_products уже связанных.\n"); | |
136 | + if (!empty($not_linked_cats)) { | |
137 | + $this->stdout("$orpahed_products товаров не привязаны к категориям:\n"); | |
138 | + foreach ($not_linked_cats as $not_linked_cat) { | |
139 | + $this->stdout("$not_linked_cat"); | |
140 | + } | |
141 | + } | |
142 | + } | |
143 | + | |
144 | + public function goProducts() { | |
145 | + | |
146 | + } | |
147 | +} | |
0 | 148 | \ No newline at end of file | ... | ... |
frontend/controllers/CatalogController.php
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | namespace frontend\controllers; |
4 | 4 | |
5 | 5 | use common\modules\product\Filter; |
6 | +use common\modules\product\helpers\ProductHelper; | |
6 | 7 | use common\modules\rubrication\models\TaxOptionSearch; |
7 | 8 | use frontend\models\ProductFrontendSearch; |
8 | 9 | use Yii; |
... | ... | @@ -27,7 +28,7 @@ use yii\web\HttpException; |
27 | 28 | class CatalogController extends \yii\web\Controller |
28 | 29 | { |
29 | 30 | public function actionSearch() { |
30 | - | |
31 | + // @todo | |
31 | 32 | } |
32 | 33 | |
33 | 34 | public function actionCategory() |
... | ... | @@ -35,15 +36,54 @@ class CatalogController extends \yii\web\Controller |
35 | 36 | /** @var Category $category */ |
36 | 37 | $category = Yii::$app->request->get('category'); |
37 | 38 | $filter = Yii::$app->request->get('filter', []); |
39 | + $word = trim(Yii::$app->request->get('word', '')); | |
38 | 40 | |
39 | - if (empty($category->category_id)) { | |
41 | + if (empty($category->category_id) && empty($word)) { | |
40 | 42 | throw new HttpException(404 ,'Page not found'); |
41 | 43 | } |
42 | - if ($category->depth < 2) { | |
44 | + | |
45 | + $last_products = ProductHelper::getLastProducts(true); | |
46 | + | |
47 | + if (!empty($word)) { | |
48 | + $params = []; | |
49 | + | |
50 | + $params['keywords'] = explode(' ', preg_replace("|[\s,.!:&?~();-]|i", " ", $word)); | |
51 | + foreach($params['keywords'] as $i => &$keyword) { | |
52 | + $keyword = trim($keyword); | |
53 | + if (empty($keyword)) { | |
54 | + unset($params['keywords'][$i]); | |
55 | + } | |
56 | + } | |
57 | + | |
58 | + $productModel = new ProductFrontendSearch(); | |
59 | + $productProvider = $productModel->search($category, $params); | |
60 | + | |
61 | + $categoriesQuery = Category::find() | |
62 | + ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.category_id = '. Category::tableName() .'.category_id') | |
63 | + ->innerJoin(Product::tableName(), Product::tableName() .'.product_id = '. ProductCategory::tableName() .'.product_id'); | |
64 | + foreach ($params['keywords'] as $keyword) { | |
65 | + $categoriesQuery->andWhere(['ilike', 'product.name', $keyword]); | |
66 | + } | |
67 | + $categories = $categoriesQuery->all(); | |
68 | + | |
69 | + return $this->render( | |
70 | + 'search', | |
71 | + [ | |
72 | + 'keywords' => $params['keywords'], | |
73 | + 'category' => $category, | |
74 | + 'productModel' => $productModel, | |
75 | + 'productProvider' => $productProvider, | |
76 | + 'last_products' => $last_products, | |
77 | + 'categories' => $categories, | |
78 | + ] | |
79 | + ); | |
80 | + | |
81 | + } elseif ($category->depth < 2) { | |
43 | 82 | return $this->render( |
44 | 83 | 'categories', |
45 | 84 | [ |
46 | - 'category' => $category | |
85 | + 'category' => $category, | |
86 | + 'last_products' => $last_products, | |
47 | 87 | ] |
48 | 88 | ); |
49 | 89 | } else { |
... | ... | @@ -113,6 +153,7 @@ class CatalogController extends \yii\web\Controller |
113 | 153 | 'optionsProvider' => $optionsProvider, |
114 | 154 | 'groups' => $groups, |
115 | 155 | 'priceLimits' => $priceLimits, |
156 | + 'last_products' => $last_products, | |
116 | 157 | ] |
117 | 158 | ); |
118 | 159 | } |
... | ... | @@ -134,9 +175,13 @@ class CatalogController extends \yii\web\Controller |
134 | 175 | unset($groups[$i]); |
135 | 176 | } |
136 | 177 | |
178 | + $last_products = ProductHelper::getLastProducts(true); | |
179 | + ProductHelper::addLastProsucts($product->product_id); | |
180 | + | |
137 | 181 | return $this->render('product', [ |
138 | 182 | 'product' => $product, |
139 | 183 | 'properties' => $groups, |
184 | + 'last_products' => $last_products | |
140 | 185 | ]); |
141 | 186 | } |
142 | 187 | ... | ... |
frontend/models/ProductFrontendSearch.php
... | ... | @@ -5,6 +5,7 @@ namespace frontend\models; |
5 | 5 | use common\modules\product\models\Brand; |
6 | 6 | use common\modules\product\models\ProductCategory; |
7 | 7 | use common\modules\product\models\ProductOption; |
8 | +use common\modules\product\models\ProductSearch; | |
8 | 9 | use common\modules\rubrication\models\TaxGroup; |
9 | 10 | use common\modules\rubrication\models\TaxOption; |
10 | 11 | use Yii; |
... | ... | @@ -43,14 +44,17 @@ class ProductFrontendSearch extends Product { |
43 | 44 | * |
44 | 45 | * @return ActiveDataProvider |
45 | 46 | */ |
46 | - public function search($category, $params) { | |
47 | - /** @var ActiveQuery $query */ | |
48 | - $query = $category->getRelations('product_categories'); | |
49 | - | |
47 | + public function search($category = null, $params = []) { | |
48 | + if (!empty($category)) { | |
49 | + /** @var ActiveQuery $query */ | |
50 | + $query = $category->getRelations('product_categories'); | |
51 | + } else { | |
52 | + $query = Product::find(); | |
53 | + } | |
50 | 54 | $query->joinWith('variant'); |
51 | 55 | $query->joinWith('brand'); |
52 | - $query->joinWith('categories'); | |
53 | 56 | $query->joinWith('image'); |
57 | + $query->joinWith('categories'); | |
54 | 58 | |
55 | 59 | $dataProvider = new ActiveDataProvider([ |
56 | 60 | 'query' => $query, |
... | ... | @@ -84,7 +88,7 @@ class ProductFrontendSearch extends Product { |
84 | 88 | return $dataProvider; |
85 | 89 | } |
86 | 90 | |
87 | - public function optionsForCategory($category, $params) { | |
91 | + public function optionsForCategory($category = null, $params = []) { | |
88 | 92 | $query = TaxOption::find() |
89 | 93 | ->select([ |
90 | 94 | TaxOption::tableName() .'.*', |
... | ... | @@ -93,11 +97,11 @@ class ProductFrontendSearch extends Product { |
93 | 97 | ->innerJoin(ProductOption::tableName(), ProductOption::tableName() .'.option_id='. TaxOption::tableName() .'.tax_option_id') |
94 | 98 | ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. ProductOption::tableName() .'.product_id') |
95 | 99 | ->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'); | |
100 | + ->andWhere([TaxGroup::tableName() .'.is_filter' => true]); | |
101 | + if (!empty($category)) { | |
102 | + $query->andWhere([ProductCategory::tableName() .'.category_id' => $category->category_id]); | |
103 | + } | |
104 | + $query->groupBy(TaxOption::tableName() .'.tax_option_id'); | |
101 | 105 | |
102 | 106 | if (!empty($params['prices'])) { |
103 | 107 | if ($params['prices']['min'] > 0 || $params['prices']['max'] > 0) { |
... | ... | @@ -122,9 +126,13 @@ class ProductFrontendSearch extends Product { |
122 | 126 | return $dataProvider; |
123 | 127 | } |
124 | 128 | |
125 | - public function priceLimits($category, $params) { | |
126 | - /** @var ActiveQuery $query */ | |
127 | - $query = $category->getRelations('product_categories'); | |
129 | + public function priceLimits($category = null, $params = []) { | |
130 | + if (!empty($category)) { | |
131 | + /** @var ActiveQuery $query */ | |
132 | + $query = $category->getRelations('product_categories'); | |
133 | + } else { | |
134 | + $query = Product::find(); | |
135 | + } | |
128 | 136 | $query->joinWith('variant'); |
129 | 137 | |
130 | 138 | $this->_setParams($query, $params, false); |
... | ... | @@ -141,6 +149,14 @@ class ProductFrontendSearch extends Product { |
141 | 149 | } |
142 | 150 | |
143 | 151 | protected function _setParams(&$query, $params, $setPriceLimits = true) { |
152 | + if (!empty($params['keywords'])) { | |
153 | + if (!is_array($params['keywords'])) { | |
154 | + $params['keywords'] = [$params['keywords']]; | |
155 | + } | |
156 | + foreach ($params['keywords'] as $keyword) { | |
157 | + $query->andFilterWhere(['ilike', Product::tableName() .'.name', $keyword]); | |
158 | + } | |
159 | + } | |
144 | 160 | if (!empty($params['brands'])) { |
145 | 161 | $query->andFilterWhere([Product::tableName() .'.brand_id' => $params['brands']]); |
146 | 162 | } | ... | ... |
frontend/views/catalog/product.php
1 | 1 | <?php |
2 | 2 | /** @var $this \yii\web\View */ |
3 | 3 | /** @var $dataProvider \yii\data\ActiveDataProvider */ |
4 | -die('here1'); | |
5 | 4 | $this->title = $product->name; |
6 | 5 | foreach($product->category->getParents()->all() as $parent) { |
7 | 6 | $this->params['breadcrumbs'][] = ['label' => $parent->categoryName->value, 'url' => ['catalog/category', 'category' => $parent]]; |
... | ... | @@ -50,13 +49,19 @@ $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku; |
50 | 49 | <div class="busket_block"> <!-- блок с счетчиком и кнопкой добавить в корзину --> |
51 | 50 | <div class="top_code"> |
52 | 51 | <span class="code">Код: <?= $product->variant->sku?></span> |
53 | - <span class="have"><img src="/images/ok_icon_green.png" alt=""><?= $product->stock !== 0 ? ' есть в наличии' : ' нет в наличии'?></span> | |
52 | + <span class="have"><img src="/images/ok_icon_green.png" alt=""><?= $product->stock !== 0 && $product->variant->price > 0 ? ' есть в наличии' : ' нет в наличии'?></span> | |
54 | 53 | </div> |
55 | 54 | |
56 | 55 | <div class="grey_bg"> |
57 | 56 | <div class="counter"> |
58 | - <div class="price"><?= $product->variant->price?></div> | |
57 | + <?php if ($product->variant->price > 0) :?> | |
58 | + <div class="price"> | |
59 | + <?= $product->variant->price?> | |
60 | + </div> | |
59 | 61 | <div class="sign">грн.</div> |
62 | + <?php else :?> | |
63 | + <div class="price"></div> | |
64 | + <?php endif?> | |
60 | 65 | |
61 | 66 | <div class="count_block"> |
62 | 67 | <input type="text" name="" class="form-control buy_one_item" value="1"> |
... | ... | @@ -214,23 +219,12 @@ $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku; |
214 | 219 | <div class="ionTabs__item" data-name="Tab_2_name"> |
215 | 220 | <?= $product->description?> |
216 | 221 | </div> |
217 | - <?php else :?> | |
218 | - <div class="ionTabs__item" data-name="Tab_2_name"> | |
219 | - Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. | |
220 | - </div> | |
221 | 222 | <?php endif?> |
222 | 223 | <?php if (!empty($product->video)) :?> |
223 | 224 | <div class="ionTabs__item" data-name="Tab_3_name"> |
224 | 225 | <?= $product->video?> |
225 | 226 | </div> |
226 | - <?php else :?> | |
227 | - <div class="ionTabs__item" data-name="Tab_3_name" style="width: 100%; text-align: center"> | |
228 | - <div style="clear: both;width: 100%;"><iframe width="420" height="315" src="https://www.youtube.com/embed/Q5LiO_35s1E" frameborder="0" allowfullscreen></iframe></div> | |
229 | - </div> | |
230 | 227 | <?php endif?> |
231 | - <!--<div class="ionTabs__item" data-name="Tab_4_name"> | |
232 | - <span class="tabs_item_name">Отзывы</span> | |
233 | - </div>--> | |
234 | 228 | |
235 | 229 | <div class="ionTabs__preloader"></div> |
236 | 230 | </div> |
... | ... | @@ -239,77 +233,16 @@ $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku; |
239 | 233 | </div> <!-- конец табов с описанием видео и отзывами --> |
240 | 234 | <div style="clear: both;"></div> |
241 | 235 | |
242 | - | |
236 | + <?php if(!empty($last_products)) :?> | |
243 | 237 | <hr> |
244 | - | |
245 | 238 | <div class="watched_block"> |
246 | 239 | <h1>Вы недавно просматривали</h1> |
247 | 240 | <div class="flex-container"> |
248 | - | |
249 | - <div class="my_custom_card"> | |
250 | - <div class="new">АКЦИЯ</div> | |
251 | - <div class="top">Toп</div> | |
252 | - <a href="#" class="item_link"><div class="pic"><img src="/images/no_photo.png"></div> | |
253 | - <div class="title_item">Штукатурка гипсовая Кнауф Ротбанд 30 кг белая</div></a> | |
254 | - <div class="brand">Бренд: <span>Knauf</span></div> | |
255 | - <div class="type">Штукатурки</div> | |
256 | - <div class="price">102.05 <span>грн.</span></div> | |
257 | - <a href="#" class="test_a"> | |
258 | - <button class="foo">в корзину<img src="/images/ico_basket_white.png" alt=""></button> | |
259 | - </a> | |
260 | - <a href="#" class="compare_add_but"><span>добавить к сравнению</span></a> | |
261 | - <img class="item_bottom_img" src="/images/nc_item_bottom.png" alt=""> | |
262 | - </div> | |
263 | - | |
264 | - <div class="my_custom_card"> | |
265 | - <div class="new">АКЦИЯ</div> | |
266 | - <div class="top">Toп</div> | |
267 | - <a href="#" class="item_link"><div class="pic"><img src="/images/no_photo.png"></div> | |
268 | - <div class="title_item">Штукатурка гипсовая Кнауф Ротбанд 30 кг белая</div></a> | |
269 | - <div class="brand">Бренд: <span>Knauf</span></div> | |
270 | - <div class="type">Штукатурки</div> | |
271 | - <div class="price">102.05 <span>грн.</span></div> | |
272 | - <a href="#" class="test_a"> | |
273 | - <button class="foo">в корзину<img src="/images/ico_basket_white.png" alt=""></button> | |
274 | - </a> | |
275 | - <a href="#" class="compare_add_but"><span>добавить к сравнению</span></a> | |
276 | - <img class="item_bottom_img" src="/images/nc_item_bottom.png" alt=""> | |
277 | - </div> | |
278 | - | |
279 | - <div class="my_custom_card"> | |
280 | - <div class="new">АКЦИЯ</div> | |
281 | - <div class="top">Toп</div> | |
282 | - <a href="#" class="item_link"><div class="pic"><img src="/images/no_photo.png"></div> | |
283 | - <div class="title_item">Штукатурка гипсовая Кнауф Ротбанд 30 кг белая</div></a> | |
284 | - <div class="brand">Бренд: <span>Knauf</span></div> | |
285 | - <div class="type">Штукатурки</div> | |
286 | - <div class="price">102.05 <span>грн.</span></div> | |
287 | - <a href="#" class="test_a"> | |
288 | - <button class="foo">в корзину<img src="/images/ico_basket_white.png" alt=""></button> | |
289 | - </a> | |
290 | - <a href="#" class="compare_add_but"><span>добавить к сравнению</span></a> | |
291 | - <img class="item_bottom_img" src="/images/nc_item_bottom.png" alt=""> | |
292 | - </div> | |
293 | - | |
294 | - <div class="my_custom_card"> | |
295 | - <div class="new">АКЦИЯ</div> | |
296 | - <div class="top">Toп</div> | |
297 | - <a href="#" class="item_link"><div class="pic"><img src="/images/no_photo.png"></div> | |
298 | - <div class="title_item">Штукатурка гипсовая Кнауф Ротбанд 30 кг белая</div></a> | |
299 | - <div class="brand">Бренд: <span>Knauf</span></div> | |
300 | - <div class="type">Штукатурки</div> | |
301 | - <div class="price">102.05 <span>грн.</span></div> | |
302 | - <a href="#" class="test_a"> | |
303 | - <button class="foo">в корзину<img src="/images/ico_basket_white.png" alt=""></button> | |
304 | - </a> | |
305 | - <a href="#" class="compare_add_but_d"> | |
306 | - <img src="/images/ico_scales.png" alt=""><span>добавить к сравнению</span> | |
307 | - </a> | |
308 | - <img class="item_bottom_img" src="/images/nc_item_bottom.png" alt=""> | |
309 | - </div> | |
310 | - | |
241 | + <?php foreach($last_products as $product) :?> | |
242 | + <?php require(__DIR__ .'/product_smart.php')?> | |
243 | + <?php endforeach?> | |
311 | 244 | </div> |
312 | - | |
313 | 245 | </div> |
246 | + <?php endif?> | |
314 | 247 | |
315 | 248 | </div> <!-- end flex container --> | ... | ... |
frontend/views/catalog/product_item.php
... | ... | @@ -14,7 +14,9 @@ |
14 | 14 | <?php endif?> |
15 | 15 | </div> |
16 | 16 | <div class="title_item"><?= $product->name?></div></a> |
17 | + <?php if (!empty($product->brand)) :?> | |
17 | 18 | <div class="brand">Бренд: <span><?= $product->brand->name?></span></div> |
19 | + <?php endif?> | |
18 | 20 | <div class="type"><?= implode(', ', $product->categoriesNames)?></div> |
19 | 21 | <?php if($product->variant) :?> |
20 | 22 | <div class="price"><?= $product->variant->price?> <span>грн.</span></div> | ... | ... |
1 | +<?php | |
2 | +/** @var \common\modules\product\models\Product $product */ | |
3 | + | |
4 | +?> | |
5 | +<div class="my_custom_card"> | |
6 | + <!--<div class="new">АКЦИЯ</div> | |
7 | + <div class="top">Toп</div>--> | |
8 | + <a href="<?= \yii\helpers\Url::to(['catalog/product', 'product' => $product])?>" class="item_link"><div class="pic"><img src="/images/no_photo.png"></div> | |
9 | + <div class="title_item"><?= $product->name?></div></a> | |
10 | + <?php if ($product->brand) :?> | |
11 | + <div class="brand">Бренд: <span><?= $product->brand->name?></span></div> | |
12 | + <?php endif?> | |
13 | + <div class="type"><?= implode(', ', $product->categoriesNames)?></div> | |
14 | + <?php if($product->variant) :?> | |
15 | + <div class="price"><?= $product->variant->price?> <span>грн.</span></div> | |
16 | + <button class="basket_add_but" data-id="<?= $product->variant->product_variant_id?>">в корзину</button> | |
17 | + <?php endif?> | |
18 | + <a href="#" class="compare_add_but" data-id="<?= $product->product_id?>"><span>добавить к сравнению</span></a> | |
19 | + <img class="item_bottom_img" src="/images/nc_item_bottom.png" alt=""> | |
20 | +</div> | |
0 | 21 | \ No newline at end of file | ... | ... |
frontend/views/catalog/products.php
... | ... | @@ -7,12 +7,12 @@ |
7 | 7 | use yii\helpers\Url; |
8 | 8 | use common\modules\product\helpers\ProductHelper; |
9 | 9 | |
10 | - | |
11 | -$this->title = $category->categoryName->value; | |
10 | +$this->title = $category->categoryName->value; | |
12 | 11 | foreach($category->getParents()->all() as $parent) { |
13 | 12 | $this->params['breadcrumbs'][] = ['label' => $parent->categoryName->value, 'url' => ['catalog/category', 'category' => $parent]]; |
14 | 13 | } |
15 | 14 | $this->params['breadcrumbs'][] = $category->categoryName->value; |
15 | + | |
16 | 16 | $this->params['seo']['seo_text'] = 'TEST SEO TEXT'; |
17 | 17 | $this->params['seo']['h1'] = 'TEST H1'; |
18 | 18 | $this->params['seo']['description'] = 'TEST DESCRIPTION'; |
... | ... | @@ -147,10 +147,11 @@ $filterWhitoutPrice['prices'] = [ |
147 | 147 | <!-- catalog list with all item cards --> |
148 | 148 | <div class="cat_p_catalog_list"> |
149 | 149 | <div class="title"><?= $category->categoryName->value?> <span>(<?= $productProvider->totalCount?>)</span></div> |
150 | - | |
151 | 150 | <?php if (!$productProvider->count) :?> |
152 | 151 | <h2>По данному запросу товары не найдены.</h2><br> |
152 | + <?php if (!empty($category)) :?> | |
153 | 153 | <p>Показать <a href="<?= Url::to(['catalog/category', 'category' => $category])?>">все товары из категории "<?= $category->categoryName->value?>"</a></p> |
154 | + <?php endif?> | |
154 | 155 | <?php else :?> |
155 | 156 | <!-- sort menu --> |
156 | 157 | <div class="sort_menu"> |
... | ... | @@ -235,4 +236,16 @@ $filterWhitoutPrice['prices'] = [ |
235 | 236 | |
236 | 237 | <?php endif?> |
237 | 238 | </div> |
239 | + | |
240 | + <?php if(!empty($last_products)) :?> | |
241 | + <hr> | |
242 | + <div class="watched_block"> | |
243 | + <h1>Вы недавно просматривали</h1> | |
244 | + <div class="flex-container"> | |
245 | + <?php foreach($last_products as $product) :?> | |
246 | + <?php require(__DIR__ .'/product_smart.php')?> | |
247 | + <?php endforeach?> | |
248 | + </div> | |
249 | + </div> | |
250 | + <?php endif?> | |
238 | 251 | </div> |
239 | 252 | \ No newline at end of file | ... | ... |
1 | +<?php | |
2 | +/** @var $this \yii\web\View */ | |
3 | +/** @var $productProvider \yii\data\ActiveDataProvider */ | |
4 | +/** @var $brandProvider \yii\data\ActiveDataProvider */ | |
5 | + | |
6 | + | |
7 | +use yii\helpers\Url; | |
8 | +use common\modules\product\helpers\ProductHelper; | |
9 | + | |
10 | +$page_data = [ | |
11 | + 'keywords' => implode(' ', $keywords), | |
12 | +]; | |
13 | + | |
14 | +if (!empty($category)) { | |
15 | + $page_data['category'] = $category->name; | |
16 | +} | |
17 | + | |
18 | +$this->title = Yii::t('product', "Search for \"{keywords}\"". (empty($category) ? '' : ' in category \"{category}\"'), $page_data); | |
19 | + | |
20 | +$this->params['seo']['seo_text'] = 'TEST SEO TEXT'; | |
21 | +$this->params['seo']['h1'] = 'TEST H1'; | |
22 | +$this->params['seo']['description'] = 'TEST DESCRIPTION'; | |
23 | +$this->params['seo']['fields']['name'] = 'TEST NAME FROM FIELD'; | |
24 | +$this->params['seo']['key']= 'product_list'; | |
25 | +?> | |
26 | +<div class="w_960"> | |
27 | + <?php if(!empty($categories)) :?> | |
28 | + <!-- side bar with all filters --> | |
29 | + <div class="cat_p_filter_bar"> | |
30 | + <div class="title">Категории</div> | |
31 | + <div class="filter_list"> | |
32 | + <ul> | |
33 | + <?php foreach ($categories as $_category) :?> | |
34 | + <li><a href="<?= Url::to(['catalog/category', 'category' => $_category, 'word' => implode(' ', $keywords)])?>"><?= $_category->name?></a></li> | |
35 | + <?php endforeach?> | |
36 | + </ul> | |
37 | + </div> | |
38 | + </div> | |
39 | + <?php endif?> | |
40 | + | |
41 | + <!-- catalog list with all item cards --> | |
42 | + <div class="cat_p_catalog_list"> | |
43 | + <div class="title"><?= Yii::t('product', "Search for \"{keywords}\"". (empty($category) ? '' : ' in category "{category}"'), $page_data)?><span><?= $productProvider->totalCount ? ' ('.$productProvider->totalCount .')' : ''?></span></div> | |
44 | + <?php if (!$productProvider->count) :?> | |
45 | + <h2>По данному запросу товары не найдены.</h2><br> | |
46 | + <?php if (!empty($category)) :?> | |
47 | + <p>Показать <a href="<?= Url::to(['catalog/category', 'category' => $category])?>">все товары из категории "<?= $category->name?>"</a></p> | |
48 | + <?php endif?> | |
49 | + <?php else :?> | |
50 | + <!-- sort menu --> | |
51 | + <div class="sort_menu"> | |
52 | + | |
53 | + <div class="sort_price"> | |
54 | + <span>Сортировка:</span> | |
55 | + <?= \yii\widgets\LinkSorter::widget([ | |
56 | + 'sort' => $productProvider->sort, | |
57 | + 'attributes' => [ | |
58 | + 'name', | |
59 | + 'price', | |
60 | + ] | |
61 | + ]); | |
62 | + ?> | |
63 | + </div> | |
64 | + | |
65 | + <div class="show"> | |
66 | + <!--<span>Показывать по:</span> | |
67 | + <ul> | |
68 | + <li><a class="active" href="#">24</a></li> | |
69 | + <li><a href="#">48</a></li> | |
70 | + <li><a href="#">96</a></li> | |
71 | + </ul>--> | |
72 | + </div> | |
73 | + | |
74 | + <?php if ($productProvider->totalCount > $productProvider->pagination->pageSize) :?> | |
75 | + <div class="show_pages"> | |
76 | + Страница: | |
77 | + <?= \yii\widgets\LinkPager::widget([ | |
78 | + 'pagination' => $productProvider->pagination, | |
79 | + 'options' => ['class' => 'pagination pull-right'], | |
80 | + ]); | |
81 | + ?> | |
82 | + </div> | |
83 | + <?php endif?> | |
84 | + | |
85 | + </div> | |
86 | + | |
87 | + <div class="cat_p_item_card_list"> | |
88 | + <div class="novelty"> | |
89 | + <div class="content"> | |
90 | + <div class="novelty_cont"> | |
91 | + <?php foreach($productProvider->models as $product) :?> | |
92 | + <?php require(__DIR__ .'/product_item.php')?> | |
93 | + <?php endforeach?> | |
94 | + </div> | |
95 | + | |
96 | + <?php if ($productProvider->totalCount > $productProvider->pagination->pageSize) :?> | |
97 | + <!-- LOAD MORE BUTTON --> | |
98 | + <!--button class="load_more_btn">Загрузить еще <?= $productProvider->pagination->pageSize?> товара</button--> | |
99 | + | |
100 | + <div class="show_pages"> | |
101 | + Страница: | |
102 | + <?= \yii\widgets\LinkPager::widget([ | |
103 | + 'pagination' => $productProvider->pagination, | |
104 | + 'options' => ['class' => 'pagination pull-right'], | |
105 | + ]); | |
106 | + ?> | |
107 | + </div> | |
108 | + <?php endif ?> | |
109 | + <hr> | |
110 | + | |
111 | + <?php if(!empty($category->description)) :?> | |
112 | + <div class="description"> | |
113 | + <?= $category->description?> | |
114 | + | |
115 | + <div class="empty_padding_400"></div> | |
116 | + </div> | |
117 | + <?php endif?> | |
118 | + </div> | |
119 | + </div> | |
120 | + </div> | |
121 | + | |
122 | + <?php endif?> | |
123 | + </div> | |
124 | + | |
125 | + <?php if(!empty($last_products)) :?> | |
126 | + <hr> | |
127 | + <div class="watched_block"> | |
128 | + <h1>Вы недавно просматривали</h1> | |
129 | + <div class="flex-container"> | |
130 | + <?php foreach($last_products as $product) :?> | |
131 | + <?php require(__DIR__ .'/product_smart.php')?> | |
132 | + <?php endforeach?> | |
133 | + </div> | |
134 | + </div> | |
135 | + <?php endif?> | |
136 | +</div> | |
0 | 137 | \ No newline at end of file | ... | ... |
frontend/views/layouts/main.php
... | ... | @@ -58,7 +58,7 @@ AppAsset::register($this); |
58 | 58 | <?= Html::a(Html::img('/images/bau_logo.png',['border'=>'0']), ['/'],['class'=>'head_up_cell bau_logo'])?> |
59 | 59 | <div class="head_up_cell srch"> |
60 | 60 | <div class="search_head"> |
61 | - <form action="<?= Url::to('catalog')?>"> | |
61 | + <form action="/<?= Url::to('catalog')?>"> | |
62 | 62 | <div class="srch_head_desc">Введите запрос <a href="#" onclick="$('#search-head').val('Шифер');return false;">Шифер</a> <a href="#" onclick="$('#search-head').val('Рубероид');return false;">Рубероид</a></div> |
63 | 63 | <input type="text" name="word" id="search-head"> |
64 | 64 | <button><div class="search_img"></div></button> | ... | ... |