Commit 5613104b0134fb2ef52223efcdd716a996cb1236

Authored by Administrator
2 parents 9f2129c6 fde39c35

Merge remote-tracking branch 'origin/master'

backend/config/main.php
... ... @@ -25,6 +25,9 @@ return [
25 25 'product' => [
26 26 'class' => 'common\modules\product\Module'
27 27 ],
  28 + 'gridview' => [
  29 + 'class' => '\kartik\grid\Module'
  30 + ]
28 31 ],
29 32 'components' => [
30 33 'user' => [
... ...
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-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;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-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;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 = '&ndash;') {
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 +}
... ...
common/modules/product/models/RemoteCategories.php 0 → 100644
  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 +}
... ...
common/modules/product/models/RemoteProducts.php 0 → 100644
  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
... ...
console/controllers/ImportController.php 0 → 100644
  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-&gt;params[&#39;breadcrumbs&#39;][] = $product-&gt;name .&#39; #&#39;. $product-&gt;variant-&gt;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-&gt;params[&#39;breadcrumbs&#39;][] = $product-&gt;name .&#39; #&#39;. $product-&gt;variant-&gt;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-&gt;params[&#39;breadcrumbs&#39;][] = $product-&gt;name .&#39; #&#39;. $product-&gt;variant-&gt;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>
... ...
frontend/views/catalog/product_smart.php 0 → 100644
  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[&#39;prices&#39;] = [
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[&#39;prices&#39;] = [
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
... ...
frontend/views/catalog/search.php 0 → 100644
  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>
... ...