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
@@ -25,6 +25,9 @@ return [ | @@ -25,6 +25,9 @@ return [ | ||
25 | 'product' => [ | 25 | 'product' => [ |
26 | 'class' => 'common\modules\product\Module' | 26 | 'class' => 'common\modules\product\Module' |
27 | ], | 27 | ], |
28 | + 'gridview' => [ | ||
29 | + 'class' => '\kartik\grid\Module' | ||
30 | + ] | ||
28 | ], | 31 | ], |
29 | 'components' => [ | 32 | 'components' => [ |
30 | 'user' => [ | 33 | 'user' => [ |
backend/views/category/_form.php
@@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
3 | use yii\helpers\Html; | 3 | use yii\helpers\Html; |
4 | use yii\widgets\ActiveForm; | 4 | use yii\widgets\ActiveForm; |
5 | use common\modules\file\widgets\ImageUploader; | 5 | use common\modules\file\widgets\ImageUploader; |
6 | +use kartik\select2\Select2; | ||
6 | 7 | ||
7 | /* @var $this yii\web\View */ | 8 | /* @var $this yii\web\View */ |
8 | /* @var $model common\modules\product\models\Category */ | 9 | /* @var $model common\modules\product\models\Category */ |
@@ -24,10 +25,25 @@ use common\modules\file\widgets\ImageUploader; | @@ -24,10 +25,25 @@ use common\modules\file\widgets\ImageUploader; | ||
24 | ] | 25 | ] |
25 | ])->label(Yii::t('product', 'Parent category')) ?> | 26 | ])->label(Yii::t('product', 'Parent category')) ?> |
26 | 27 | ||
28 | + <?php /* | ||
27 | <?= $form->field($model, 'group_to_category')->dropDownList( | 29 | <?= $form->field($model, 'group_to_category')->dropDownList( |
28 | \yii\helpers\ArrayHelper::map(\common\modules\rubrication\models\TaxGroup::find()->all(), 'tax_group_id', 'name'), [ | 30 | \yii\helpers\ArrayHelper::map(\common\modules\rubrication\models\TaxGroup::find()->all(), 'tax_group_id', 'name'), [ |
29 | 'multiple' => true | 31 | 'multiple' => true |
30 | ])->label(Yii::t('product', 'Linked options')) ?> | 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 | <?= ImageUploader::widget([ | 48 | <?= ImageUploader::widget([ |
33 | 'model'=> $model, | 49 | 'model'=> $model, |
@@ -52,6 +68,19 @@ use common\modules\file\widgets\ImageUploader; | @@ -52,6 +68,19 @@ use common\modules\file\widgets\ImageUploader; | ||
52 | 68 | ||
53 | <?= $form->field($model, 'seo_text')->textarea(['rows' => 6]) ?> | 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 | <?php if (!empty($model) && $model->depth == 2) :?> | 84 | <?php if (!empty($model) && $model->depth == 2) :?> |
56 | <?= $form->field($model, 'populary')->checkbox() ?> | 85 | <?= $form->field($model, 'populary')->checkbox() ?> |
57 | <?php endif?> | 86 | <?php endif?> |
backend/views/category/index.php
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | use yii\helpers\Html; | 3 | use yii\helpers\Html; |
4 | -use yii\grid\GridView; | 4 | +use kartik\grid\GridView; |
5 | 5 | ||
6 | /* @var $this yii\web\View */ | 6 | /* @var $this yii\web\View */ |
7 | /* @var $searchModel common\modules\product\models\CategorySearch */ | 7 | /* @var $searchModel common\modules\product\models\CategorySearch */ |
@@ -37,12 +37,14 @@ $this->params['breadcrumbs'][] = $this->title; | @@ -37,12 +37,14 @@ $this->params['breadcrumbs'][] = $this->title; | ||
37 | ], | 37 | ], |
38 | [ | 38 | [ |
39 | 'class' => 'yii\grid\ActionColumn', | 39 | 'class' => 'yii\grid\ActionColumn', |
40 | - 'template' => '{populary} {view} {update} {delete}', | 40 | + 'template' => '{view} {update} {delete} {populary}', |
41 | 'buttons' => [ | 41 | 'buttons' => [ |
42 | 'populary' => function ($url, $model) { | 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 | 'urlCreator' => function ($action, $model, $key, $index) { | 50 | 'urlCreator' => function ($action, $model, $key, $index) { |
@@ -63,5 +65,8 @@ $this->params['breadcrumbs'][] = $this->title; | @@ -63,5 +65,8 @@ $this->params['breadcrumbs'][] = $this->title; | ||
63 | } | 65 | } |
64 | ], | 66 | ], |
65 | ], | 67 | ], |
68 | + 'panel' => [ | ||
69 | + 'type'=>'success', | ||
70 | + ], | ||
66 | ]); ?> | 71 | ]); ?> |
67 | </div> | 72 | </div> |
backend/views/layouts/main-sidebar.php
@@ -30,6 +30,7 @@ use yii\widgets\Menu; | @@ -30,6 +30,7 @@ use yii\widgets\Menu; | ||
30 | 'url' => ['/product/manage'], | 30 | 'url' => ['/product/manage'], |
31 | 'items' => [ | 31 | 'items' => [ |
32 | ['label' => 'Товары', 'url' => ['/product/manage']], | 32 | ['label' => 'Товары', 'url' => ['/product/manage']], |
33 | + ['label' => 'Импорт товаров', 'url' => ['/product/manage/import']], | ||
33 | ['label' => 'Категории', 'url' => ['/category']], | 34 | ['label' => 'Категории', 'url' => ['/category']], |
34 | ['label' => 'Бренды', 'url' => ['/brand']], | 35 | ['label' => 'Бренды', 'url' => ['/brand']], |
35 | ] | 36 | ] |
common/components/artboxtree/ArtboxTreeHelper.php
@@ -15,6 +15,23 @@ class ArtboxTreeHelper extends Object { | @@ -15,6 +15,23 @@ class ArtboxTreeHelper extends Object { | ||
15 | return $result; | 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 | protected static function _recursiveTreeMap(&$result, $tree, $from, $to, $symbol = '–') { | 35 | protected static function _recursiveTreeMap(&$result, $tree, $from, $to, $symbol = '–') { |
19 | foreach ($tree as $item) { | 36 | foreach ($tree as $item) { |
20 | $element = $item['item']; | 37 | $element = $item['item']; |
common/modules/product/CatalogUrlManager.php
@@ -41,8 +41,8 @@ class CatalogUrlManager implements UrlRuleInterface { | @@ -41,8 +41,8 @@ class CatalogUrlManager implements UrlRuleInterface { | ||
41 | } | 41 | } |
42 | $params['category'] = $category; | 42 | $params['category'] = $category; |
43 | } | 43 | } |
44 | - // Filter | ||
45 | if (!empty($paths[2])) { | 44 | if (!empty($paths[2])) { |
45 | + // Filter | ||
46 | if (strpos($paths[2], 'filter:') === 0) { | 46 | if (strpos($paths[2], 'filter:') === 0) { |
47 | $params['filter'] = []; | 47 | $params['filter'] = []; |
48 | $filter_str = substr($paths[2], 7); | 48 | $filter_str = substr($paths[2], 7); |
@@ -65,6 +65,8 @@ class CatalogUrlManager implements UrlRuleInterface { | @@ -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 | } elseif ($paths[0] == 'product') { | 72 | } elseif ($paths[0] == 'product') { |
@@ -99,8 +101,17 @@ class CatalogUrlManager implements UrlRuleInterface { | @@ -99,8 +101,17 @@ class CatalogUrlManager implements UrlRuleInterface { | ||
99 | case 'catalog/category': | 101 | case 'catalog/category': |
100 | if (!empty($params['category'])) { | 102 | if (!empty($params['category'])) { |
101 | $category_alias = is_object($params['category']) ? $params['category']->alias : strtolower($params['category']); | 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 | $filter = []; | 116 | $filter = []; |
106 | if (!empty($params['filter'])) { | 117 | if (!empty($params['filter'])) { |
@@ -135,6 +146,7 @@ class CatalogUrlManager implements UrlRuleInterface { | @@ -135,6 +146,7 @@ class CatalogUrlManager implements UrlRuleInterface { | ||
135 | } | 146 | } |
136 | $url .= 'filter:'. implode(';', $filter); | 147 | $url .= 'filter:'. implode(';', $filter); |
137 | } | 148 | } |
149 | + | ||
138 | return $url; | 150 | return $url; |
139 | break; | 151 | break; |
140 | 152 |
common/modules/product/controllers/ManageController.php
@@ -5,6 +5,7 @@ namespace common\modules\product\controllers; | @@ -5,6 +5,7 @@ namespace common\modules\product\controllers; | ||
5 | use common\modules\product\helpers\ProductHelper; | 5 | use common\modules\product\helpers\ProductHelper; |
6 | use common\modules\product\models\Category; | 6 | use common\modules\product\models\Category; |
7 | use common\modules\product\models\ProductVariant; | 7 | use common\modules\product\models\ProductVariant; |
8 | +use common\modules\product\models\RemoteProductsSearch; | ||
8 | use Yii; | 9 | use Yii; |
9 | use common\modules\product\models\Product; | 10 | use common\modules\product\models\Product; |
10 | use common\modules\product\models\ProductSearch; | 11 | use common\modules\product\models\ProductSearch; |
@@ -162,6 +163,16 @@ class ManageController extends Controller | @@ -162,6 +163,16 @@ class ManageController extends Controller | ||
162 | return $this->redirect(['index']); | 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 | * Finds the Product model based on its primary key value. | 177 | * Finds the Product model based on its primary key value. |
167 | * If the model is not found, a 404 HTTP exception will be thrown. | 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,7 +4,9 @@ namespace common\modules\product\helpers; | ||
4 | 4 | ||
5 | use common\modules\product\models\Brand; | 5 | use common\modules\product\models\Brand; |
6 | use common\modules\product\models\Category; | 6 | use common\modules\product\models\Category; |
7 | +use common\modules\product\models\Product; | ||
7 | use yii\base\Object; | 8 | use yii\base\Object; |
9 | +use Yii; | ||
8 | 10 | ||
9 | class ProductHelper extends Object { | 11 | class ProductHelper extends Object { |
10 | public static function getCategories() { | 12 | public static function getCategories() { |
@@ -55,4 +57,20 @@ class ProductHelper extends Object { | @@ -55,4 +57,20 @@ class ProductHelper extends Object { | ||
55 | } | 57 | } |
56 | return $result; | 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 | \ No newline at end of file | 77 | \ No newline at end of file |
common/modules/product/models/BrandSearch.php
@@ -73,7 +73,7 @@ class BrandSearch extends Brand | @@ -73,7 +73,7 @@ class BrandSearch extends Brand | ||
73 | return $dataProvider; | 73 | return $dataProvider; |
74 | } | 74 | } |
75 | 75 | ||
76 | - public function getBrands($category, $params) { | 76 | + public function getBrands($category = null, $params = []) { |
77 | $query = Brand::find() | 77 | $query = Brand::find() |
78 | ->select([ | 78 | ->select([ |
79 | Brand::tableName() .'.*', | 79 | Brand::tableName() .'.*', |
@@ -82,11 +82,13 @@ class BrandSearch extends Brand | @@ -82,11 +82,13 @@ class BrandSearch extends Brand | ||
82 | ->innerJoin(Product::tableName(), Product::tableName() .'.brand_id='. Brand::tableName() .'.brand_id') | 82 | ->innerJoin(Product::tableName(), Product::tableName() .'.brand_id='. Brand::tableName() .'.brand_id') |
83 | ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. Product::tableName() .'.product_id') | 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 | ProductCategory::tableName() .'.category_id' => $category->category_id | 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 | if (isset($params['options'])) { | 92 | if (isset($params['options'])) { |
91 | unset($params['options']); | 93 | unset($params['options']); |
92 | } | 94 | } |
common/modules/product/models/Category.php
@@ -4,6 +4,7 @@ namespace common\modules\product\models; | @@ -4,6 +4,7 @@ namespace common\modules\product\models; | ||
4 | 4 | ||
5 | use common\behaviors\RuSlug; | 5 | use common\behaviors\RuSlug; |
6 | use common\components\artboxtree\ArtboxTreeBehavior; | 6 | use common\components\artboxtree\ArtboxTreeBehavior; |
7 | +use common\components\artboxtree\ArtboxTreeHelper; | ||
7 | use common\modules\relation\relationBehavior; | 8 | use common\modules\relation\relationBehavior; |
8 | use common\modules\rubrication\behaviors\ArtboxSynonymBehavior; | 9 | use common\modules\rubrication\behaviors\ArtboxSynonymBehavior; |
9 | use Yii; | 10 | use Yii; |
@@ -12,6 +13,7 @@ use Yii; | @@ -12,6 +13,7 @@ use Yii; | ||
12 | * This is the model class for table "category". | 13 | * This is the model class for table "category". |
13 | * | 14 | * |
14 | * @property integer $category_id | 15 | * @property integer $category_id |
16 | + * @property string $remote_id | ||
15 | * @property integer $parent_id | 17 | * @property integer $parent_id |
16 | * @property string $path | 18 | * @property string $path |
17 | * @property integer $depth | 19 | * @property integer $depth |
@@ -86,7 +88,7 @@ class Category extends \yii\db\ActiveRecord | @@ -86,7 +88,7 @@ class Category extends \yii\db\ActiveRecord | ||
86 | [['meta_robots'], 'string', 'max' => 50], | 88 | [['meta_robots'], 'string', 'max' => 50], |
87 | [['alias', 'name'], 'string', 'max' => 250], | 89 | [['alias', 'name'], 'string', 'max' => 250], |
88 | [['populary'], 'boolean'], | 90 | [['populary'], 'boolean'], |
89 | - [['group_to_category'], 'safe'], | 91 | + [['group_to_category', 'remote_category'], 'safe'], |
90 | [['category_name_id'], 'exist', 'skipOnError' => true, 'targetClass' => CategoryName::className(), 'targetAttribute' => ['category_name_id' => 'category_name_id']], | 92 | [['category_name_id'], 'exist', 'skipOnError' => true, 'targetClass' => CategoryName::className(), 'targetAttribute' => ['category_name_id' => 'category_name_id']], |
91 | // [['image'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg, gif'], | 93 | // [['image'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg, gif'], |
92 | // [['product_unit_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductUnit::className(), 'targetAttribute' => ['product_unit_id' => 'product_unit_id']], | 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,6 +114,7 @@ class Category extends \yii\db\ActiveRecord | ||
112 | 'alias' => Yii::t('product', 'Alias'), | 114 | 'alias' => Yii::t('product', 'Alias'), |
113 | 'populary' => Yii::t('product', 'Populary'), | 115 | 'populary' => Yii::t('product', 'Populary'), |
114 | 'name' => Yii::t('product', 'Name'), | 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,15 +150,14 @@ class Category extends \yii\db\ActiveRecord | ||
147 | return $this->getRelations('tax_group_to_category'); | 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 | public function getCategoryName() { | 163 | public function getCategoryName() { |
@@ -165,4 +167,16 @@ class Category extends \yii\db\ActiveRecord | @@ -165,4 +167,16 @@ class Category extends \yii\db\ActiveRecord | ||
165 | public function getName() { | 167 | public function getName() { |
166 | return empty($this->categoryName) ? null : $this->categoryName->value; | 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,6 +2,7 @@ | ||
2 | 2 | ||
3 | namespace common\modules\product\models; | 3 | namespace common\modules\product\models; |
4 | 4 | ||
5 | +use common\components\artboxtree\ArtboxTreeHelper; | ||
5 | use Yii; | 6 | use Yii; |
6 | use yii\base\Model; | 7 | use yii\base\Model; |
7 | use yii\data\ActiveDataProvider; | 8 | use yii\data\ActiveDataProvider; |
@@ -97,4 +98,19 @@ class CategorySearch extends Category | @@ -97,4 +98,19 @@ class CategorySearch extends Category | ||
97 | throw new NotFoundHttpException('The requested page does not exist.'); | 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,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,6 +10,7 @@ use Yii; | ||
10 | * @property integer $product_variant_id | 10 | * @property integer $product_variant_id |
11 | * @property integer $product_id | 11 | * @property integer $product_id |
12 | * @property string $name | 12 | * @property string $name |
13 | + * @property string $remote_id | ||
13 | * @property string $sku | 14 | * @property string $sku |
14 | * @property double $price | 15 | * @property double $price |
15 | * @property double $price_old | 16 | * @property double $price_old |
@@ -34,10 +35,11 @@ class ProductVariant extends \yii\db\ActiveRecord | @@ -34,10 +35,11 @@ class ProductVariant extends \yii\db\ActiveRecord | ||
34 | public function rules() | 35 | public function rules() |
35 | { | 36 | { |
36 | return [ | 37 | return [ |
37 | - [['product_id', 'name', 'sku', 'product_unit_id'], 'required'], | 38 | + [['product_id', 'sku', 'product_unit_id'], 'required'], |
38 | [['product_id', 'product_unit_id'], 'integer'], | 39 | [['product_id', 'product_unit_id'], 'integer'], |
39 | [['price', 'price_old', 'stock'], 'number'], | 40 | [['price', 'price_old', 'stock'], 'number'], |
40 | [['name', 'sku'], 'string', 'max' => 255], | 41 | [['name', 'sku'], 'string', 'max' => 255], |
42 | + [['remote_id'], 'string', 'max' => 20], | ||
41 | [['product_unit_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductUnit::className(), 'targetAttribute' => ['product_unit_id' => 'product_unit_id']], | 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,6 +8,7 @@ use common\modules\product\helpers\ProductHelper; | ||
8 | use kartik\file\FileInput; | 8 | use kartik\file\FileInput; |
9 | use unclead\widgets\MultipleInput; | 9 | use unclead\widgets\MultipleInput; |
10 | use unclead\widgets\MultipleInputColumn; | 10 | use unclead\widgets\MultipleInputColumn; |
11 | +use kartik\select2\Select2; | ||
11 | 12 | ||
12 | /* @var $this yii\web\View */ | 13 | /* @var $this yii\web\View */ |
13 | /* @var $model common\modules\product\models\Product */ | 14 | /* @var $model common\modules\product\models\Product */ |
@@ -30,9 +31,9 @@ use unclead\widgets\MultipleInputColumn; | @@ -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 | 'data' => ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'category_id', 'name'), | 35 | 'data' => ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'category_id', 'name'), |
35 | - 'language' => 'de', | 36 | + 'language' => 'ru', |
36 | 'options' => [ | 37 | 'options' => [ |
37 | 'placeholder' => 'Select a state ...', | 38 | 'placeholder' => 'Select a state ...', |
38 | 'multiple' => true, | 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,4 +5,7 @@ return [ | ||
5 | 'Name' => 'Наименование', | 5 | 'Name' => 'Наименование', |
6 | 'Set populary' => 'Сделать популярной', | 6 | 'Set populary' => 'Сделать популярной', |
7 | 'Set not populary' => 'Сделать не популярной', | 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 | \ No newline at end of file | 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 | \ No newline at end of file | 148 | \ No newline at end of file |
frontend/controllers/CatalogController.php
@@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
3 | namespace frontend\controllers; | 3 | namespace frontend\controllers; |
4 | 4 | ||
5 | use common\modules\product\Filter; | 5 | use common\modules\product\Filter; |
6 | +use common\modules\product\helpers\ProductHelper; | ||
6 | use common\modules\rubrication\models\TaxOptionSearch; | 7 | use common\modules\rubrication\models\TaxOptionSearch; |
7 | use frontend\models\ProductFrontendSearch; | 8 | use frontend\models\ProductFrontendSearch; |
8 | use Yii; | 9 | use Yii; |
@@ -27,7 +28,7 @@ use yii\web\HttpException; | @@ -27,7 +28,7 @@ use yii\web\HttpException; | ||
27 | class CatalogController extends \yii\web\Controller | 28 | class CatalogController extends \yii\web\Controller |
28 | { | 29 | { |
29 | public function actionSearch() { | 30 | public function actionSearch() { |
30 | - | 31 | + // @todo |
31 | } | 32 | } |
32 | 33 | ||
33 | public function actionCategory() | 34 | public function actionCategory() |
@@ -35,15 +36,54 @@ class CatalogController extends \yii\web\Controller | @@ -35,15 +36,54 @@ class CatalogController extends \yii\web\Controller | ||
35 | /** @var Category $category */ | 36 | /** @var Category $category */ |
36 | $category = Yii::$app->request->get('category'); | 37 | $category = Yii::$app->request->get('category'); |
37 | $filter = Yii::$app->request->get('filter', []); | 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 | throw new HttpException(404 ,'Page not found'); | 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 | return $this->render( | 82 | return $this->render( |
44 | 'categories', | 83 | 'categories', |
45 | [ | 84 | [ |
46 | - 'category' => $category | 85 | + 'category' => $category, |
86 | + 'last_products' => $last_products, | ||
47 | ] | 87 | ] |
48 | ); | 88 | ); |
49 | } else { | 89 | } else { |
@@ -113,6 +153,7 @@ class CatalogController extends \yii\web\Controller | @@ -113,6 +153,7 @@ class CatalogController extends \yii\web\Controller | ||
113 | 'optionsProvider' => $optionsProvider, | 153 | 'optionsProvider' => $optionsProvider, |
114 | 'groups' => $groups, | 154 | 'groups' => $groups, |
115 | 'priceLimits' => $priceLimits, | 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,9 +175,13 @@ class CatalogController extends \yii\web\Controller | ||
134 | unset($groups[$i]); | 175 | unset($groups[$i]); |
135 | } | 176 | } |
136 | 177 | ||
178 | + $last_products = ProductHelper::getLastProducts(true); | ||
179 | + ProductHelper::addLastProsucts($product->product_id); | ||
180 | + | ||
137 | return $this->render('product', [ | 181 | return $this->render('product', [ |
138 | 'product' => $product, | 182 | 'product' => $product, |
139 | 'properties' => $groups, | 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,6 +5,7 @@ namespace frontend\models; | ||
5 | use common\modules\product\models\Brand; | 5 | use common\modules\product\models\Brand; |
6 | use common\modules\product\models\ProductCategory; | 6 | use common\modules\product\models\ProductCategory; |
7 | use common\modules\product\models\ProductOption; | 7 | use common\modules\product\models\ProductOption; |
8 | +use common\modules\product\models\ProductSearch; | ||
8 | use common\modules\rubrication\models\TaxGroup; | 9 | use common\modules\rubrication\models\TaxGroup; |
9 | use common\modules\rubrication\models\TaxOption; | 10 | use common\modules\rubrication\models\TaxOption; |
10 | use Yii; | 11 | use Yii; |
@@ -43,14 +44,17 @@ class ProductFrontendSearch extends Product { | @@ -43,14 +44,17 @@ class ProductFrontendSearch extends Product { | ||
43 | * | 44 | * |
44 | * @return ActiveDataProvider | 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 | $query->joinWith('variant'); | 54 | $query->joinWith('variant'); |
51 | $query->joinWith('brand'); | 55 | $query->joinWith('brand'); |
52 | - $query->joinWith('categories'); | ||
53 | $query->joinWith('image'); | 56 | $query->joinWith('image'); |
57 | + $query->joinWith('categories'); | ||
54 | 58 | ||
55 | $dataProvider = new ActiveDataProvider([ | 59 | $dataProvider = new ActiveDataProvider([ |
56 | 'query' => $query, | 60 | 'query' => $query, |
@@ -84,7 +88,7 @@ class ProductFrontendSearch extends Product { | @@ -84,7 +88,7 @@ class ProductFrontendSearch extends Product { | ||
84 | return $dataProvider; | 88 | return $dataProvider; |
85 | } | 89 | } |
86 | 90 | ||
87 | - public function optionsForCategory($category, $params) { | 91 | + public function optionsForCategory($category = null, $params = []) { |
88 | $query = TaxOption::find() | 92 | $query = TaxOption::find() |
89 | ->select([ | 93 | ->select([ |
90 | TaxOption::tableName() .'.*', | 94 | TaxOption::tableName() .'.*', |
@@ -93,11 +97,11 @@ class ProductFrontendSearch extends Product { | @@ -93,11 +97,11 @@ class ProductFrontendSearch extends Product { | ||
93 | ->innerJoin(ProductOption::tableName(), ProductOption::tableName() .'.option_id='. TaxOption::tableName() .'.tax_option_id') | 97 | ->innerJoin(ProductOption::tableName(), ProductOption::tableName() .'.option_id='. TaxOption::tableName() .'.tax_option_id') |
94 | ->innerJoin(ProductCategory::tableName(), ProductCategory::tableName() .'.product_id='. ProductOption::tableName() .'.product_id') | 98 | ->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') | 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 | if (!empty($params['prices'])) { | 106 | if (!empty($params['prices'])) { |
103 | if ($params['prices']['min'] > 0 || $params['prices']['max'] > 0) { | 107 | if ($params['prices']['min'] > 0 || $params['prices']['max'] > 0) { |
@@ -122,9 +126,13 @@ class ProductFrontendSearch extends Product { | @@ -122,9 +126,13 @@ class ProductFrontendSearch extends Product { | ||
122 | return $dataProvider; | 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 | $query->joinWith('variant'); | 136 | $query->joinWith('variant'); |
129 | 137 | ||
130 | $this->_setParams($query, $params, false); | 138 | $this->_setParams($query, $params, false); |
@@ -141,6 +149,14 @@ class ProductFrontendSearch extends Product { | @@ -141,6 +149,14 @@ class ProductFrontendSearch extends Product { | ||
141 | } | 149 | } |
142 | 150 | ||
143 | protected function _setParams(&$query, $params, $setPriceLimits = true) { | 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 | if (!empty($params['brands'])) { | 160 | if (!empty($params['brands'])) { |
145 | $query->andFilterWhere([Product::tableName() .'.brand_id' => $params['brands']]); | 161 | $query->andFilterWhere([Product::tableName() .'.brand_id' => $params['brands']]); |
146 | } | 162 | } |
frontend/views/catalog/product.php
1 | <?php | 1 | <?php |
2 | /** @var $this \yii\web\View */ | 2 | /** @var $this \yii\web\View */ |
3 | /** @var $dataProvider \yii\data\ActiveDataProvider */ | 3 | /** @var $dataProvider \yii\data\ActiveDataProvider */ |
4 | -die('here1'); | ||
5 | $this->title = $product->name; | 4 | $this->title = $product->name; |
6 | foreach($product->category->getParents()->all() as $parent) { | 5 | foreach($product->category->getParents()->all() as $parent) { |
7 | $this->params['breadcrumbs'][] = ['label' => $parent->categoryName->value, 'url' => ['catalog/category', 'category' => $parent]]; | 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,13 +49,19 @@ $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku; | ||
50 | <div class="busket_block"> <!-- блок с счетчиком и кнопкой добавить в корзину --> | 49 | <div class="busket_block"> <!-- блок с счетчиком и кнопкой добавить в корзину --> |
51 | <div class="top_code"> | 50 | <div class="top_code"> |
52 | <span class="code">Код: <?= $product->variant->sku?></span> | 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 | </div> | 53 | </div> |
55 | 54 | ||
56 | <div class="grey_bg"> | 55 | <div class="grey_bg"> |
57 | <div class="counter"> | 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 | <div class="sign">грн.</div> | 61 | <div class="sign">грн.</div> |
62 | + <?php else :?> | ||
63 | + <div class="price"></div> | ||
64 | + <?php endif?> | ||
60 | 65 | ||
61 | <div class="count_block"> | 66 | <div class="count_block"> |
62 | <input type="text" name="" class="form-control buy_one_item" value="1"> | 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,23 +219,12 @@ $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku; | ||
214 | <div class="ionTabs__item" data-name="Tab_2_name"> | 219 | <div class="ionTabs__item" data-name="Tab_2_name"> |
215 | <?= $product->description?> | 220 | <?= $product->description?> |
216 | </div> | 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 | <?php endif?> | 222 | <?php endif?> |
222 | <?php if (!empty($product->video)) :?> | 223 | <?php if (!empty($product->video)) :?> |
223 | <div class="ionTabs__item" data-name="Tab_3_name"> | 224 | <div class="ionTabs__item" data-name="Tab_3_name"> |
224 | <?= $product->video?> | 225 | <?= $product->video?> |
225 | </div> | 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 | <?php endif?> | 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 | <div class="ionTabs__preloader"></div> | 229 | <div class="ionTabs__preloader"></div> |
236 | </div> | 230 | </div> |
@@ -239,77 +233,16 @@ $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku; | @@ -239,77 +233,16 @@ $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku; | ||
239 | </div> <!-- конец табов с описанием видео и отзывами --> | 233 | </div> <!-- конец табов с описанием видео и отзывами --> |
240 | <div style="clear: both;"></div> | 234 | <div style="clear: both;"></div> |
241 | 235 | ||
242 | - | 236 | + <?php if(!empty($last_products)) :?> |
243 | <hr> | 237 | <hr> |
244 | - | ||
245 | <div class="watched_block"> | 238 | <div class="watched_block"> |
246 | <h1>Вы недавно просматривали</h1> | 239 | <h1>Вы недавно просматривали</h1> |
247 | <div class="flex-container"> | 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 | </div> | 244 | </div> |
312 | - | ||
313 | </div> | 245 | </div> |
246 | + <?php endif?> | ||
314 | 247 | ||
315 | </div> <!-- end flex container --> | 248 | </div> <!-- end flex container --> |
frontend/views/catalog/product_item.php
@@ -14,7 +14,9 @@ | @@ -14,7 +14,9 @@ | ||
14 | <?php endif?> | 14 | <?php endif?> |
15 | </div> | 15 | </div> |
16 | <div class="title_item"><?= $product->name?></div></a> | 16 | <div class="title_item"><?= $product->name?></div></a> |
17 | + <?php if (!empty($product->brand)) :?> | ||
17 | <div class="brand">Бренд: <span><?= $product->brand->name?></span></div> | 18 | <div class="brand">Бренд: <span><?= $product->brand->name?></span></div> |
19 | + <?php endif?> | ||
18 | <div class="type"><?= implode(', ', $product->categoriesNames)?></div> | 20 | <div class="type"><?= implode(', ', $product->categoriesNames)?></div> |
19 | <?php if($product->variant) :?> | 21 | <?php if($product->variant) :?> |
20 | <div class="price"><?= $product->variant->price?> <span>грн.</span></div> | 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 | \ No newline at end of file | 21 | \ No newline at end of file |
frontend/views/catalog/products.php
@@ -7,12 +7,12 @@ | @@ -7,12 +7,12 @@ | ||
7 | use yii\helpers\Url; | 7 | use yii\helpers\Url; |
8 | use common\modules\product\helpers\ProductHelper; | 8 | use common\modules\product\helpers\ProductHelper; |
9 | 9 | ||
10 | - | ||
11 | -$this->title = $category->categoryName->value; | 10 | +$this->title = $category->categoryName->value; |
12 | foreach($category->getParents()->all() as $parent) { | 11 | foreach($category->getParents()->all() as $parent) { |
13 | $this->params['breadcrumbs'][] = ['label' => $parent->categoryName->value, 'url' => ['catalog/category', 'category' => $parent]]; | 12 | $this->params['breadcrumbs'][] = ['label' => $parent->categoryName->value, 'url' => ['catalog/category', 'category' => $parent]]; |
14 | } | 13 | } |
15 | $this->params['breadcrumbs'][] = $category->categoryName->value; | 14 | $this->params['breadcrumbs'][] = $category->categoryName->value; |
15 | + | ||
16 | $this->params['seo']['seo_text'] = 'TEST SEO TEXT'; | 16 | $this->params['seo']['seo_text'] = 'TEST SEO TEXT'; |
17 | $this->params['seo']['h1'] = 'TEST H1'; | 17 | $this->params['seo']['h1'] = 'TEST H1'; |
18 | $this->params['seo']['description'] = 'TEST DESCRIPTION'; | 18 | $this->params['seo']['description'] = 'TEST DESCRIPTION'; |
@@ -147,10 +147,11 @@ $filterWhitoutPrice['prices'] = [ | @@ -147,10 +147,11 @@ $filterWhitoutPrice['prices'] = [ | ||
147 | <!-- catalog list with all item cards --> | 147 | <!-- catalog list with all item cards --> |
148 | <div class="cat_p_catalog_list"> | 148 | <div class="cat_p_catalog_list"> |
149 | <div class="title"><?= $category->categoryName->value?> <span>(<?= $productProvider->totalCount?>)</span></div> | 149 | <div class="title"><?= $category->categoryName->value?> <span>(<?= $productProvider->totalCount?>)</span></div> |
150 | - | ||
151 | <?php if (!$productProvider->count) :?> | 150 | <?php if (!$productProvider->count) :?> |
152 | <h2>По данному запросу товары не найдены.</h2><br> | 151 | <h2>По данному запросу товары не найдены.</h2><br> |
152 | + <?php if (!empty($category)) :?> | ||
153 | <p>Показать <a href="<?= Url::to(['catalog/category', 'category' => $category])?>">все товары из категории "<?= $category->categoryName->value?>"</a></p> | 153 | <p>Показать <a href="<?= Url::to(['catalog/category', 'category' => $category])?>">все товары из категории "<?= $category->categoryName->value?>"</a></p> |
154 | + <?php endif?> | ||
154 | <?php else :?> | 155 | <?php else :?> |
155 | <!-- sort menu --> | 156 | <!-- sort menu --> |
156 | <div class="sort_menu"> | 157 | <div class="sort_menu"> |
@@ -235,4 +236,16 @@ $filterWhitoutPrice['prices'] = [ | @@ -235,4 +236,16 @@ $filterWhitoutPrice['prices'] = [ | ||
235 | 236 | ||
236 | <?php endif?> | 237 | <?php endif?> |
237 | </div> | 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 | </div> | 251 | </div> |
239 | \ No newline at end of file | 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 | \ No newline at end of file | 137 | \ No newline at end of file |
frontend/views/layouts/main.php
@@ -58,7 +58,7 @@ AppAsset::register($this); | @@ -58,7 +58,7 @@ AppAsset::register($this); | ||
58 | <?= Html::a(Html::img('/images/bau_logo.png',['border'=>'0']), ['/'],['class'=>'head_up_cell bau_logo'])?> | 58 | <?= Html::a(Html::img('/images/bau_logo.png',['border'=>'0']), ['/'],['class'=>'head_up_cell bau_logo'])?> |
59 | <div class="head_up_cell srch"> | 59 | <div class="head_up_cell srch"> |
60 | <div class="search_head"> | 60 | <div class="search_head"> |
61 | - <form action="<?= Url::to('catalog')?>"> | 61 | + <form action="/<?= Url::to('catalog')?>"> |
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> | 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 | <input type="text" name="word" id="search-head"> | 63 | <input type="text" name="word" id="search-head"> |
64 | <button><div class="search_img"></div></button> | 64 | <button><div class="search_img"></div></button> |