Commit 550f051a4f30fa03da64f26f1844360d10936152

Authored by Karnovsky A
1 parent c790ef09

Karnovsky-05052016-0900

backend/controllers/BrandController.php
... ... @@ -9,6 +9,8 @@ use yii\web\Controller;
9 9 use yii\web\NotFoundHttpException;
10 10 use yii\filters\VerbFilter;
11 11 use yii\filters\AccessControl;
  12 +use yii\web\UploadedFile;
  13 +
12 14 /**
13 15 * BrandController implements the CRUD actions for Brand model.
14 16 */
... ... @@ -78,8 +80,14 @@ class BrandController extends Controller
78 80 public function actionCreate()
79 81 {
80 82 $model = new Brand();
81   - if ($model->load(Yii::$app->request->post()) && $model->save()) {
82   - exit;
  83 + if ($model->load(Yii::$app->request->post())) {
  84 + if ( ($image = UploadedFile::getInstance($model, 'imageUpload')) ) {
  85 + $model->image = $image->name;
  86 + }
  87 + if ($model->save() && $image) {
  88 + $image->saveAs(Yii::getAlias('@frontend/web/images/brand/' . $image->name));
  89 + }
  90 +
83 91 return is_null(Yii::$app->request->post('create_and_new')) ? $this->redirect(['view', 'id' => $model->brand_id]) : $this->redirect(array_merge(['create'], Yii::$app->request->queryParams));
84 92 } else {
85 93 return $this->render('create', [
... ... @@ -98,7 +106,14 @@ class BrandController extends Controller
98 106 {
99 107 $model = $this->findModel($id);
100 108  
101   - if ($model->load(Yii::$app->request->post()) && $model->save()) {
  109 + if ($model->load(Yii::$app->request->post())) {
  110 + if ( ($image = UploadedFile::getInstance($model, 'imageUpload')) ) {
  111 + $model->image = $image->name;
  112 + }
  113 + if ($model->save() && $image) {
  114 + $image->saveAs(Yii::getAlias('@frontend/web/images/brand/' . $image->name));
  115 + }
  116 +
102 117 return $this->redirect(['view', 'id' => $model->brand_id]);
103 118 } else {
104 119 return $this->render('update', [
... ...
backend/controllers/CategoryController.php
... ... @@ -11,6 +11,8 @@ use yii\web\Controller;
11 11 use yii\web\NotFoundHttpException;
12 12 use yii\filters\VerbFilter;
13 13 use yii\filters\AccessControl;
  14 +use yii\web\UploadedFile;
  15 +
14 16 /**
15 17 * CategoryController implements the CRUD actions for Category model.
16 18 */
... ... @@ -81,7 +83,14 @@ class CategoryController extends Controller
81 83 {
82 84 $model = new Category();
83 85  
84   - if ($model->load(Yii::$app->request->post()) && $model->save()) {
  86 + if ($model->load(Yii::$app->request->post())) {
  87 + if ( ($image = UploadedFile::getInstance($model, 'imageUpload')) ) {
  88 + $model->image = $image->name;
  89 + }
  90 + if ($model->save() && $image) {
  91 + $image->saveAs(Yii::getAlias('@frontend/web/images/category/' . $image->name));
  92 + }
  93 +
85 94 return is_null(Yii::$app->request->post('create_and_new')) ? $this->redirect(['view', 'id' => $model->category_id]) : $this->redirect(array_merge(['create'], Yii::$app->request->queryParams));
86 95 } else {
87 96 if (!empty(Yii::$app->request->queryParams['parent'])) {
... ... @@ -104,7 +113,14 @@ class CategoryController extends Controller
104 113 {
105 114 $model = $this->findModel($id);
106 115  
107   - if ($model->load(Yii::$app->request->post()) && $model->save()) {
  116 + if ($model->load(Yii::$app->request->post())) {
  117 + if ( ($image = UploadedFile::getInstance($model, 'imageUpload')) ) {
  118 + $model->image = $image->name;
  119 + }
  120 + if ($model->save() && $image) {
  121 + $image->saveAs(Yii::getAlias('@frontend/web/images/category/' . $image->name));
  122 + }
  123 +
108 124 return $this->redirect(['view', 'id' => $model->category_id]);
109 125 } else {
110 126 return $this->render('update', [
... ...
backend/views/brand/_form.php
... ... @@ -10,26 +10,27 @@ use yii\widgets\ActiveForm;
10 10  
11 11 <div class="brand-form">
12 12  
13   - <?php $form = ActiveForm::begin(); ?>
  13 + <?php $form = ActiveForm::begin([
  14 + 'options' => ['enctype'=>'multipart/form-data']
  15 + ]); ?>
14 16  
15 17 <?= $form->field($model, 'name')->textInput() ?>
16 18  
17 19 <?= $form->field($model, 'alias')->textInput(['maxlength' => true]) ?>
18 20  
19   - <?= \common\modules\file\widgets\ImageUploader::widget([
20   - 'model'=> $model,
21   - 'field'=>'image',
22   - 'size' => [
23   - [
24   - 'width'=>102,
25   - 'height'=>57,
26   - ]
  21 + <?= $form->field($model, 'imageUpload')->widget(\kartik\file\FileInput::classname(), [
  22 + 'options' => [
  23 + 'accept' => 'image/*',
27 24 ],
28   - 'multi'=>false,
29   - 'gallery' => $model->image,
30   - 'name' => 'Загрузить изображение'
31   - ]);
32   - ?>
  25 + 'pluginOptions' => [
  26 + 'allowedFileExtensions' => ['jpg','gif','png'],
  27 + 'initialPreview' => function() use ($model) {
  28 + if (!empty($model->imageUrl))
  29 + return Html::img($model->imageUrl);
  30 + },
  31 + 'overwriteInitial' => false,
  32 + ],
  33 + ]); ?>
33 34  
34 35 <?= $form->field($model, 'meta_title')->textInput(['maxlength' => true]) ?>
35 36  
... ...
backend/views/brand/index.php
... ... @@ -20,13 +20,16 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;title;
20 20 </p>
21 21 <?= GridView::widget([
22 22 'dataProvider' => $dataProvider,
23   -// 'filterModel' => $searchModel,
  23 + 'filterModel' => $searchModel,
24 24 'columns' => [
25 25 ['class' => 'yii\grid\SerialColumn'],
26   -
27   - 'name',
  26 + [
  27 + 'label' => Yii::t('product', 'Brand'),
  28 + 'value' => 'brandName.value',
  29 + 'attribute' => 'brand_name'
  30 + ],
28 31 'alias',
29   -
  32 + 'imageUrl:image',
30 33 ['class' => 'yii\grid\ActionColumn'],
31 34 ],
32 35 ]); ?>
... ...
backend/views/brand/update.php
... ... @@ -7,9 +7,9 @@ use yii\helpers\Html;
7 7  
8 8 $this->title = Yii::t('product', 'Update {modelClass}: ', [
9 9 'modelClass' => 'Brand',
10   -]) . ' ' . $model->brand_id;
  10 +]) . ' ' . $model->name;
11 11 $this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Brands'), 'url' => ['index']];
12   -$this->params['breadcrumbs'][] = ['label' => $model->brand_id, 'url' => ['view', 'id' => $model->brand_id]];
  12 +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->brand_id]];
13 13 $this->params['breadcrumbs'][] = Yii::t('product', 'Update');
14 14 ?>
15 15 <div class="brand-update">
... ...
backend/views/brand/view.php
... ... @@ -31,7 +31,7 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;title;
31 31 'brand_id',
32 32 'brand_name_id',
33 33 'alias',
34   - 'image',
  34 + 'imageUrl:image',
35 35 'meta_title',
36 36 'meta_desc:ntext',
37 37 'meta_robots',
... ...
backend/views/category/_form.php
... ... @@ -12,18 +12,46 @@ use kartik\select2\Select2;
12 12  
13 13 <div class="category-form">
14 14  
15   - <?php $form = ActiveForm::begin(); ?>
  15 + <?php $form = ActiveForm::begin([
  16 + 'options' => ['enctype'=>'multipart/form-data']
  17 + ]); ?>
16 18  
17 19 <?= $form->field($model, 'name')->textInput() ?>
18 20  
19 21 <?= $form->field($model, 'alias')->textInput(['maxlength' => true]) ?>
20 22  
21   - <?= $form->field($model, 'parent_id')->dropDownList($categories, [
  23 + <?php /*= $form->field($model, 'parent_id')->dropDownList($categories, [
22 24 'prompt' => Yii::t('rubrication', 'Root category'),
23 25 'options' => [
24 26 $model->category_id => ['disabled' => true]
25 27 ]
26   - ])->label(Yii::t('product', 'Parent category')) ?>
  28 + ])->label(Yii::t('rubrication', 'Parent category')) */?>
  29 +
  30 + <?= $form->field($model, 'parent_id')->widget(Select2::className(), [
  31 + 'data' => $categories,
  32 + 'language' => 'ru',
  33 + 'options' => [
  34 + 'placeholder' => Yii::t('product', 'Parent category'),
  35 + 'multiple' => false,
  36 + ],
  37 + 'pluginOptions' => [
  38 + 'allowClear' => true
  39 + ],
  40 + ]
  41 + ) ?>
  42 +
  43 + <?= $form->field($model, 'product_unit_id')->widget(Select2::className(), [
  44 + 'data' => \yii\helpers\ArrayHelper::map(\common\modules\product\models\ProductUnit::find()->all(), 'product_unit_id', 'name'),
  45 + 'language' => 'ru',
  46 + 'options' => [
  47 + 'placeholder' => Yii::t('product', 'Select unit'),
  48 + 'multiple' => false,
  49 + ],
  50 + 'pluginOptions' => [
  51 + 'allowClear' => true
  52 + ],
  53 + ]
  54 + ) ?>
27 55  
28 56 <?php /*
29 57 <?= $form->field($model, 'group_to_category')->dropDownList(
... ... @@ -45,20 +73,14 @@ use kartik\select2\Select2;
45 73 ]
46 74 ) ?>
47 75  
48   - <?= ImageUploader::widget([
49   - 'model'=> $model,
50   - 'field'=>'image',
51   - 'size' => [
52   - [
53   - 'width'=>340,
54   - 'height'=>260,
55   - ]
  76 + <?= $form->field($model, 'imageUpload')->widget(\kartik\file\FileInput::classname(), [
  77 + 'options' => [
  78 + 'accept' => 'image/*',
  79 + ],
  80 + 'pluginOptions' => [
  81 + 'allowedFileExtensions' => ['jpg','gif','png'],
56 82 ],
57   - 'multi'=>false,
58   - 'gallery' => $model->image,
59   - 'name' => 'Загрузить изображение'
60   - ]);
61   - ?>
  83 + ]); ?>
62 84  
63 85 <?= $form->field($model, 'meta_title')->textInput(['maxlength' => true]) ?>
64 86  
... ...
backend/views/category/index.php
... ... @@ -35,6 +35,7 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;title;
35 35 // return str_repeat('-', $data->depth) .'&nbsp;'. $data->name;
36 36 }
37 37 ],
  38 +// 'imageUrl:image',
38 39 [
39 40 'class' => 'yii\grid\ActionColumn',
40 41 'template' => '{view} {update} {delete} {populary}',
... ...
backend/views/category/view.php
... ... @@ -33,10 +33,8 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;title;
33 33 'model' => $model,
34 34 'attributes' => [
35 35 'category_id',
36   - 'parent_id',
37   - 'path',
38   - 'depth',
39   - 'image',
  36 + 'parent.name',
  37 + 'imageUrl:image',
40 38 'meta_title',
41 39 'meta_desc:ntext',
42 40 'meta_robots',
... ...
backend/views/layouts/main-sidebar.php
... ... @@ -33,6 +33,7 @@ use yii\widgets\Menu;
33 33 ['label' => 'Категории', 'url' => ['/category']],
34 34 ['label' => 'Бренды', 'url' => ['/brand']],
35 35 ['label' => 'Характеристики', 'url' => ['/rubrication/tax-group']],
  36 + ['label' => 'Единицы измерения', 'url' => ['/product/product-unit']],
36 37 ['label' => 'Статистика импорта', 'url' => ['/product/manage/import-stat']],
37 38 ]
38 39 ],
... ...
common/modules/product/CatalogUrlManager.php
... ... @@ -111,6 +111,7 @@ class CatalogUrlManager implements UrlRuleInterface {
111 111 $params['word'] = [$params['word']];
112 112 }
113 113 $url .= 'word:'. implode(';', $params['word']);
  114 + unset($params['word']);
114 115 }
115 116  
116 117 $filter = [];
... ... @@ -147,6 +148,10 @@ class CatalogUrlManager implements UrlRuleInterface {
147 148 $url .= 'filter:'. implode(';', $filter);
148 149 }
149 150  
  151 + if (!empty($params) && ($query = http_build_query($params)) !== '') {
  152 + $url .= '?' . $query;
  153 + }
  154 +
150 155 return $url;
151 156 break;
152 157  
... ... @@ -155,6 +160,11 @@ class CatalogUrlManager implements UrlRuleInterface {
155 160 $product_alias = is_object($params['product']) ? $params['product']->alias : strtolower($params['product']);
156 161 }
157 162 $url = 'product/'. $product_alias;
  163 +
  164 + if (!empty($params) && ($query = http_build_query($params)) !== '') {
  165 + $url .= '?' . $query;
  166 + }
  167 +
158 168 return $url;
159 169 break;
160 170 }
... ...
common/modules/product/controllers/ProductUnitController.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\modules\product\controllers;
  4 +
  5 +use Yii;
  6 +use common\modules\product\models\ProductUnit;
  7 +use common\modules\product\models\ProductUnitSearch;
  8 +use yii\web\Controller;
  9 +use yii\web\NotFoundHttpException;
  10 +use yii\filters\VerbFilter;
  11 +
  12 +/**
  13 + * ProductUnitController implements the CRUD actions for ProductUnit model.
  14 + */
  15 +class ProductUnitController extends Controller
  16 +{
  17 + /**
  18 + * @inheritdoc
  19 + */
  20 + public function behaviors()
  21 + {
  22 + return [
  23 + 'verbs' => [
  24 + 'class' => VerbFilter::className(),
  25 + 'actions' => [
  26 + 'delete' => ['POST'],
  27 + ],
  28 + ],
  29 + ];
  30 + }
  31 +
  32 + /**
  33 + * Lists all ProductUnit models.
  34 + * @return mixed
  35 + */
  36 + public function actionIndex()
  37 + {
  38 + $searchModel = new ProductUnitSearch();
  39 + $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
  40 +
  41 + return $this->render('index', [
  42 + 'searchModel' => $searchModel,
  43 + 'dataProvider' => $dataProvider,
  44 + ]);
  45 + }
  46 +
  47 + /**
  48 + * Displays a single ProductUnit model.
  49 + * @param integer $id
  50 + * @return mixed
  51 + */
  52 + public function actionView($id)
  53 + {
  54 + return $this->render('view', [
  55 + 'model' => $this->findModel($id),
  56 + ]);
  57 + }
  58 +
  59 + /**
  60 + * Creates a new ProductUnit model.
  61 + * If creation is successful, the browser will be redirected to the 'view' page.
  62 + * @return mixed
  63 + */
  64 + public function actionCreate()
  65 + {
  66 + $model = new ProductUnit();
  67 +
  68 + if ($model->load(Yii::$app->request->post()) && $model->save()) {
  69 + return $this->redirect(['view', 'id' => $model->product_unit_id]);
  70 + } else {
  71 + return $this->render('create', [
  72 + 'model' => $model,
  73 + ]);
  74 + }
  75 + }
  76 +
  77 + /**
  78 + * Updates an existing ProductUnit model.
  79 + * If update is successful, the browser will be redirected to the 'view' page.
  80 + * @param integer $id
  81 + * @return mixed
  82 + */
  83 + public function actionUpdate($id)
  84 + {
  85 + $model = $this->findModel($id);
  86 +
  87 + if ($model->load(Yii::$app->request->post()) && $model->save()) {
  88 + return $this->redirect(['view', 'id' => $model->product_unit_id]);
  89 + } else {
  90 + return $this->render('update', [
  91 + 'model' => $model,
  92 + ]);
  93 + }
  94 + }
  95 +
  96 + /**
  97 + * Deletes an existing ProductUnit model.
  98 + * If deletion is successful, the browser will be redirected to the 'index' page.
  99 + * @param integer $id
  100 + * @return mixed
  101 + */
  102 + public function actionDelete($id)
  103 + {
  104 + $this->findModel($id)->delete();
  105 +
  106 + return $this->redirect(['index']);
  107 + }
  108 +
  109 + /**
  110 + * Finds the ProductUnit model based on its primary key value.
  111 + * If the model is not found, a 404 HTTP exception will be thrown.
  112 + * @param integer $id
  113 + * @return ProductUnit the loaded model
  114 + * @throws NotFoundHttpException if the model cannot be found
  115 + */
  116 + protected function findModel($id)
  117 + {
  118 + if (($model = ProductUnit::findOne($id)) !== null) {
  119 + return $model;
  120 + } else {
  121 + throw new NotFoundHttpException('The requested page does not exist.');
  122 + }
  123 + }
  124 +}
... ...
common/modules/product/models/Brand.php
... ... @@ -24,6 +24,8 @@ use Yii;
24 24 */
25 25 class Brand extends \yii\db\ActiveRecord
26 26 {
  27 + public $imageUpload;
  28 +
27 29 public function behaviors()
28 30 {
29 31 return [
... ... @@ -64,6 +66,8 @@ class Brand extends \yii\db\ActiveRecord
64 66 [['alias', 'name'], 'string', 'max' => 250],
65 67 [['image', 'meta_title'], 'string', 'max' => 255],
66 68 [['meta_robots'], 'string', 'max' => 50],
  69 + [['imageUpload'], 'safe'],
  70 + [['imageUpload'], 'file', 'extensions' => 'jpg, gif, png'],
67 71 // [['brand_name_id'], 'exist', 'skipOnError' => true, 'targetClass' => BrandName::className(), 'targetAttribute' => ['brand_name_id' => 'brand_name_id']],
68 72 ];
69 73 }
... ... @@ -79,6 +83,7 @@ class Brand extends \yii\db\ActiveRecord
79 83 'brand_name_id' => Yii::t('product', 'Brand Name ID'),
80 84 'alias' => Yii::t('product', 'Alias'),
81 85 'image' => Yii::t('product', 'Image'),
  86 + 'imageUrl' => Yii::t('product', 'Image'),
82 87 'meta_title' => Yii::t('product', 'Meta Title'),
83 88 'meta_desc' => Yii::t('product', 'Meta Desc'),
84 89 'meta_robots' => Yii::t('product', 'Meta Robots'),
... ... @@ -113,4 +118,8 @@ class Brand extends \yii\db\ActiveRecord
113 118 public function getName() {
114 119 return empty($this->brand_name_id) ? null : $this->brandName->value;
115 120 }
  121 +
  122 + public function getImageUrl() {
  123 + return empty($this->image) ? null : '/images/brand/'. $this->image;
  124 + }
116 125 }
... ...
common/modules/product/models/BrandSearch.php
... ... @@ -12,6 +12,7 @@ use common\modules\product\models\Brand;
12 12 */
13 13 class BrandSearch extends Brand
14 14 {
  15 + public $brand_name;
15 16 /**
16 17 * @inheritdoc
17 18 */
... ... @@ -19,7 +20,7 @@ class BrandSearch extends Brand
19 20 {
20 21 return [
21 22 [['brand_id', 'brand_name_id'], 'integer'],
22   - [['alias', 'image', 'meta_title', 'meta_desc', 'meta_robots', 'seo_text'], 'safe'],
  23 + [['alias', 'image', 'meta_title', 'meta_desc', 'meta_robots', 'seo_text', 'brand_name'], 'safe'],
23 24 ];
24 25 }
25 26  
... ... @@ -57,18 +58,28 @@ class BrandSearch extends Brand
57 58 return $dataProvider;
58 59 }*/
59 60  
  61 + $dataProvider->setSort([
  62 + 'attributes' => [
  63 + 'brand_name',
  64 + 'alias'
  65 + ]
  66 + ]);
  67 +
60 68 // grid filtering conditions
61 69 $query->andFilterWhere([
62 70 'brand_id' => $this->brand_id,
63 71 'brand_name_id' => $this->brand_name_id,
64 72 ]);
65 73  
66   - $query->andFilterWhere(['like', 'alias', $this->alias])
67   - ->andFilterWhere(['like', 'image', $this->image])
68   - ->andFilterWhere(['like', 'meta_title', $this->meta_title])
69   - ->andFilterWhere(['like', 'meta_desc', $this->meta_desc])
70   - ->andFilterWhere(['like', 'meta_robots', $this->meta_robots])
71   - ->andFilterWhere(['like', 'seo_text', $this->seo_text]);
  74 + $query->joinWith('brandName');
  75 +
  76 + $query->andFilterWhere(['ilike', 'alias', $this->alias])
  77 + ->andFilterWhere(['ilike', 'image', $this->image])
  78 + ->andFilterWhere(['ilike', 'meta_title', $this->meta_title])
  79 + ->andFilterWhere(['ilike', 'meta_desc', $this->meta_desc])
  80 + ->andFilterWhere(['ilike', 'meta_robots', $this->meta_robots])
  81 + ->andFilterWhere(['ilike', 'seo_text', $this->seo_text])
  82 + ->andFilterWhere(['ilike', 'brand_name.value', $this->brand_name]);
72 83  
73 84 return $dataProvider;
74 85 }
... ...
common/modules/product/models/Category.php
... ... @@ -34,6 +34,8 @@ use Yii;
34 34 */
35 35 class Category extends \yii\db\ActiveRecord
36 36 {
  37 + public $imageUpload;
  38 +
37 39 public function behaviors()
38 40 {
39 41 return [
... ... @@ -89,7 +91,8 @@ class Category extends \yii\db\ActiveRecord
89 91 [['populary'], 'boolean'],
90 92 [['group_to_category', 'remote_category'], 'safe'],
91 93 [['category_name_id'], 'exist', 'skipOnError' => true, 'targetClass' => CategoryName::className(), 'targetAttribute' => ['category_name_id' => 'category_name_id']],
92   - // [['image'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg, gif'],
  94 + [['imageUpload'], 'safe'],
  95 + [['imageUpload'], 'file', 'extensions' => 'jpg, gif, png'],
93 96 // [['product_unit_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductUnit::className(), 'targetAttribute' => ['product_unit_id' => 'product_unit_id']],
94 97 ];
95 98 }
... ... @@ -105,6 +108,7 @@ class Category extends \yii\db\ActiveRecord
105 108 'path' => Yii::t('product', 'Path'),
106 109 'depth' => Yii::t('product', 'Depth'),
107 110 'image' => Yii::t('product', 'Image'),
  111 + 'imageUrl' => Yii::t('product', 'Image'),
108 112 'meta_title' => Yii::t('product', 'Meta Title'),
109 113 'meta_desc' => Yii::t('product', 'Meta Desc'),
110 114 'meta_robots' => Yii::t('product', 'Meta Robots'),
... ... @@ -117,7 +121,8 @@ class Category extends \yii\db\ActiveRecord
117 121 ];
118 122 }
119 123  
120   - public static function find() {
  124 + public static function find()
  125 + {
121 126 return new CategoryQuery(get_called_class());
122 127 }
123 128  
... ... @@ -145,28 +150,38 @@ class Category extends \yii\db\ActiveRecord
145 150 return $this->hasMany(ProductCategory::className(), ['category_id' => 'category_id']);
146 151 }
147 152  
148   - public function getTaxGroups() {
  153 + public function getTaxGroups()
  154 + {
149 155 return $this->getRelations('tax_group_to_category');
150 156 }
151 157  
152   - public function getRemote_category() {
  158 + public function getRemote_category()
  159 + {
153 160 return ArtboxTreeHelper::getArrayField($this->remote_id);
154 161 }
155 162  
156   - public function setRemote_category($value) {
  163 + public function setRemote_category($value)
  164 + {
157 165 if (!empty($value) && is_array($value)) {
158 166 $this->remote_id = ArtboxTreeHelper::setArrayField($value, false);
159 167 }
160 168 }
161 169  
162   - public function getCategoryName() {
  170 + public function getCategoryName()
  171 + {
163 172 return $this->hasOne(CategoryName::className(), ['category_name_id' => 'category_name_id']);
164 173 }
165 174  
166   - public function getName() {
  175 + public function getName()
  176 + {
167 177 return empty($this->categoryName) ? null : $this->categoryName->value;
168 178 }
169 179  
  180 + public function getImageUrl()
  181 + {
  182 + return empty($this->image) ? null : '/images/category/' . $this->image;
  183 + }
  184 +
170 185 public function beforeSave($insert)
171 186 {
172 187 if (parent::beforeSave($insert)) {
... ...
common/modules/product/models/Product.php
... ... @@ -19,6 +19,8 @@ use yii\db\ActiveQuery;
19 19 * @property ProductVariant $variant
20 20 * @property ProductImage $image
21 21 * @property array $images
  22 + * @property boolean $is_top
  23 + * @property boolean $is_new
22 24 */
23 25 class Product extends \yii\db\ActiveRecord
24 26 {
... ... @@ -69,6 +71,7 @@ class Product extends \yii\db\ActiveRecord
69 71 [['categories', 'variants', 'options'], 'safe'],
70 72 // [['imagesUpload'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg, gif'],
71 73 [['description', 'video'], 'safe'],
  74 + [['is_top', 'is_new'], 'boolean'],
72 75 // [['product_id'], 'exist', 'skipOnError' => true, 'targetClass' => Product::className(), 'targetAttribute' => ['product_id' => 'product_id']],
73 76 ];
74 77 }
... ... @@ -86,6 +89,11 @@ class Product extends \yii\db\ActiveRecord
86 89 'category' => Yii::t('product', 'Category'), // relation behavior field
87 90 'image' => Yii::t('product', 'Image'),
88 91 'images' => Yii::t('product', 'Images'),
  92 + 'description' => Yii::t('product', 'Description'),
  93 + 'video' => Yii::t('product', 'Video embeded'),
  94 + 'variants' => Yii::t('product', 'Variants'),
  95 + 'is_top' => Yii::t('product', 'Is top'),
  96 + 'is_new' => Yii::t('product', 'Is new'),
89 97 ];
90 98 }
91 99  
... ... @@ -146,7 +154,8 @@ class Product extends \yii\db\ActiveRecord
146 154 }
147 155  
148 156 public function getCategories() {
149   - return $this->getRelations('product_categories');
  157 + return $this->hasMany(Category::className(), ['category_id' => 'category_id'])->viaTable('product_category', ['product_id' => 'product_id']);
  158 +// return $this->getRelations('product_categories');
150 159 }
151 160  
152 161 public function getCategoriesNames() {
... ... @@ -158,12 +167,7 @@ class Product extends \yii\db\ActiveRecord
158 167 }
159 168  
160 169 public function getCategory() {
161   - /** @var ActiveQuery $categories */
162   - $categories = $this->getRelations('product_categories');
163   - $count = $categories->count();
164   - if ($count == 0)
165   - return;
166   - return $categories->one();
  170 + return $this->hasOne(Category::className(), ['category_id' => 'category_id'])->viaTable('product_category', ['product_id' => 'product_id']);
167 171 }
168 172  
169 173 public function getOptions() {
... ...
common/modules/product/models/ProductSearch.php
... ... @@ -13,14 +13,18 @@ use yii\web\NotFoundHttpException;
13 13 */
14 14 class ProductSearch extends Product
15 15 {
  16 + public $brand_name;
  17 + public $category_name;
  18 +
16 19 /**
17 20 * @inheritdoc
18 21 */
19 22 public function rules()
20 23 {
21 24 return [
22   - [['name'], 'safe'],
  25 + [['name', 'brand_name', 'category_name'], 'safe'],
23 26 [['tax_brand_id', 'product_id'], 'integer'],
  27 + [['is_top', 'is_new'], 'boolean'],
24 28 ];
25 29 }
26 30  
... ... @@ -58,13 +62,27 @@ class ProductSearch extends Product
58 62 return $dataProvider;
59 63 }
60 64  
  65 + $dataProvider->setSort([
  66 + 'attributes' => [
  67 + 'name',
  68 + 'brand_name',
  69 + 'category_name'
  70 + ]
  71 + ]);
  72 +
  73 + $query->joinWith(['brand', 'brand.brandNames', 'categories', 'categories.categoryNames']);
  74 +
61 75 // grid filtering conditions
62 76 $query->andFilterWhere([
63 77 'tax_brand_id' => $this->tax_brand_id,
64 78 'product_id' => $this->product_id,
  79 + 'is_top' => (bool)$this->is_top,
  80 + 'is_new' => (bool)$this->is_new,
65 81 ]);
66 82  
67   - $query->andFilterWhere(['like', 'name', $this->name]);
  83 + $query->andFilterWhere(['ilike', 'name', $this->name]);
  84 + $query->andFilterWhere(['ilike', 'brand_name.value', $this->brand_name]);
  85 + $query->andFilterWhere(['ilike', 'category_name.value', $this->category_name]);
68 86  
69 87 return $dataProvider;
70 88 }
... ...
common/modules/product/models/ProductUnitSearch.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\ProductUnit;
  9 +
  10 +/**
  11 + * ProductUnitSearch represents the model behind the search form about `common\modules\product\models\ProductUnit`.
  12 + */
  13 +class ProductUnitSearch extends ProductUnit
  14 +{
  15 + /**
  16 + * @inheritdoc
  17 + */
  18 + public function rules()
  19 + {
  20 + return [
  21 + [['product_unit_id'], 'integer'],
  22 + [['name', 'code'], 'safe'],
  23 + [['is_default'], 'boolean'],
  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 = ProductUnit::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 + 'product_unit_id' => $this->product_unit_id,
  64 + 'is_default' => $this->is_default,
  65 + ]);
  66 +
  67 + $query->andFilterWhere(['like', 'name', $this->name])
  68 + ->andFilterWhere(['like', 'code', $this->code]);
  69 +
  70 + return $dataProvider;
  71 + }
  72 +}
... ...
common/modules/product/models/ProductVariant.php
... ... @@ -58,6 +58,7 @@ class ProductVariant extends \yii\db\ActiveRecord
58 58 'price_old' => Yii::t('product', 'Price Old'),
59 59 'stock' => Yii::t('product', 'Stock'),
60 60 'product_unit_id' => Yii::t('product', 'Product Unit ID'),
  61 + 'stock_caption' => Yii::t('product', 'Stock'),
61 62 ];
62 63 }
63 64  
... ... @@ -77,6 +78,14 @@ class ProductVariant extends \yii\db\ActiveRecord
77 78 return $this->hasOne(Product::className(), ['product_id' => 'product_id']);
78 79 }
79 80  
  81 + public function getEnabled() {
  82 + return $this->stock !== 0;
  83 + }
  84 +
  85 + public function getStock_caption() {
  86 + return is_null($this->stock) ? '∞' : intval($this->stock);
  87 + }
  88 +
80 89 /**
81 90 * @inheritdoc
82 91 * @return ProductVariantQuery the active query used by this AR class.
... ...
common/modules/product/views/manage/_form.php
... ... @@ -22,7 +22,7 @@ use kartik\select2\Select2;
22 22 <?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
23 23  
24 24 <?= $form->field($model, 'description')->widget(\mihaildev\ckeditor\CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ], ]); ?>
25   - <?= $form->field($model, 'video')->textarea()->label('Video embeded'); ?>
  25 + <?= $form->field($model, 'video')->textarea(); ?>
26 26  
27 27 <?= $form->field($model, 'brand_id')->dropDownList(
28 28 ArrayHelper::map(ProductHelper::getBrands()->all(), 'brand_id', 'name'),
... ... @@ -35,7 +35,7 @@ use kartik\select2\Select2;
35 35 'data' => ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'category_id', 'name'),
36 36 'language' => 'ru',
37 37 'options' => [
38   - 'placeholder' => 'Select a state ...',
  38 + 'placeholder' => Yii::t('product', 'Select categories'),
39 39 'multiple' => true,
40 40 ],
41 41 'pluginOptions' => [
... ... @@ -62,33 +62,33 @@ use kartik\select2\Select2;
62 62 [
63 63 'name' => 'name',
64 64 'type' => MultipleInputColumn::TYPE_TEXT_INPUT,
65   - 'title' => 'Name',
  65 + 'title' => Yii::t('product', 'Name'),
66 66 ],
67 67 [
68 68 'name' => 'sku',
69 69 'type' => MultipleInputColumn::TYPE_TEXT_INPUT,
70   - 'title' => 'SKU',
  70 + 'title' => Yii::t('product', 'SKU'),
71 71 ],
72 72 [
73 73 'name' => 'price',
74 74 'type' => MultipleInputColumn::TYPE_TEXT_INPUT,
75   - 'title' => 'Price',
  75 + 'title' => Yii::t('product', 'Price'),
76 76 ],
77 77 [
78 78 'name' => 'price_old',
79 79 'type' => MultipleInputColumn::TYPE_TEXT_INPUT,
80   - 'title' => 'Old Price',
  80 + 'title' => Yii::t('product', 'Old Price'),
81 81 ],
82 82 [
83 83 'name' => 'product_unit_id',
84 84 'type' => MultipleInputColumn::TYPE_DROPDOWN,
85   - 'title' => 'Unit',
  85 + 'title' => Yii::t('product', 'Unit'),
86 86 'items' => ArrayHelper::map(\common\modules\product\models\ProductUnit::find()->all(), 'product_unit_id', 'name'),
87 87 ],
88 88 [
89 89 'name' => 'stock',
90 90 'type' => MultipleInputColumn::TYPE_TEXT_INPUT,
91   - 'title' => 'Stock',
  91 + 'title' => Yii::t('product', 'Stock'),
92 92 'options' => [
93 93 'placeholder' => '∞'
94 94 ],
... ...
common/modules/product/views/manage/index.php
... ... @@ -22,12 +22,57 @@ $this-&gt;params[&#39;breadcrumbs&#39;][] = $this-&gt;title;
22 22 'filterModel' => $searchModel,
23 23 'columns' => [
24 24 ['class' => 'yii\grid\SerialColumn'],
25   - 'product_id',
  25 +// 'product_id',
26 26 'name',
27   - 'brand.name',
28   - 'category.name',
  27 + [
  28 + 'label' => Yii::t('product', 'Brand'),
  29 + 'attribute' => 'brand_name',
  30 + 'value' => 'brand.name',
  31 + ],
  32 + [
  33 + 'label' => Yii::t('product', 'Category'),
  34 + 'attribute' => 'category_name',
  35 + 'value' => 'category.name',
  36 + ],
  37 + 'variant.price',
  38 + 'variant.stock_caption',
29 39  
30   - ['class' => 'yii\grid\ActionColumn'],
  40 +
  41 + [
  42 + 'class' => 'yii\grid\ActionColumn',
  43 + 'template' => '{view} {is_top} {is_new} {update} {delete}',
  44 + 'buttons' => [
  45 + 'is_top' => function ($url, $model) {
  46 + return Html::a('<span class="glyphicon glyphicon-star' . ($model->is_top ? '' : '-empty') . '"></span>', $url, [
  47 + 'title' => Yii::t('product', ($model->is_top ? 'Set not is top' : 'Set is top')),
  48 + ]);
  49 + },
  50 + 'is_new' => function ($url, $model) {
  51 + return Html::a('<span class="glyphicon glyphicon-heart' . ($model->is_new ? '' : '-empty') . '"></span>', $url, [
  52 + 'title' => Yii::t('product', ($model->is_new ? 'Set not is new' : 'Set is new')),
  53 + ]);
  54 + },
  55 + ],
  56 + 'urlCreator' => function ($action, $model, $key, $index) {
  57 + switch ($action) {
  58 + case 'is_top':
  59 + return \yii\helpers\Url::to(['manage/is_top', 'id' => $model->product_id]);
  60 + break;
  61 + case 'is_new':
  62 + return \yii\helpers\Url::to(['manage/is_new', 'id' => $model->product_id]);
  63 + break;
  64 + case 'view':
  65 + return \yii\helpers\Url::to(['/catalog/product', 'id' => $model->product_id, ['target' => '_blank']]);
  66 + break;
  67 + case 'update':
  68 + return \yii\helpers\Url::to(['manage/update', 'id' => $model->product_id]);
  69 + break;
  70 + case 'delete':
  71 + return \yii\helpers\Url::to(['manage/delete', 'id' => $model->product_id]);
  72 + break;
  73 + }
  74 + }
  75 + ],
31 76 ],
32 77 ]); ?>
33 78 </div>
... ...
common/modules/product/views/product-unit/_form.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\modules\product\models\ProductUnit */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="product-unit-form">
  12 +
  13 + <?php $form = ActiveForm::begin(); ?>
  14 +
  15 + <?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
  16 +
  17 + <?= $form->field($model, 'code')->textInput(['maxlength' => true]) ?>
  18 +
  19 + <?= $form->field($model, 'is_default')->checkbox() ?>
  20 +
  21 + <div class="form-group">
  22 + <?= Html::submitButton($model->isNewRecord ? Yii::t('product', 'Create') : Yii::t('product', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  23 + </div>
  24 +
  25 + <?php ActiveForm::end(); ?>
  26 +
  27 +</div>
... ...
common/modules/product/views/product-unit/_search.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\modules\product\models\ProductUnitSearch */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="product-unit-search">
  12 +
  13 + <?php $form = ActiveForm::begin([
  14 + 'action' => ['index'],
  15 + 'method' => 'get',
  16 + ]); ?>
  17 +
  18 + <?= $form->field($model, 'product_unit_id') ?>
  19 +
  20 + <?= $form->field($model, 'name') ?>
  21 +
  22 + <?= $form->field($model, 'code') ?>
  23 +
  24 + <?= $form->field($model, 'is_default')->checkbox() ?>
  25 +
  26 + <div class="form-group">
  27 + <?= Html::submitButton(Yii::t('product', 'Search'), ['class' => 'btn btn-primary']) ?>
  28 + <?= Html::resetButton(Yii::t('product', 'Reset'), ['class' => 'btn btn-default']) ?>
  29 + </div>
  30 +
  31 + <?php ActiveForm::end(); ?>
  32 +
  33 +</div>
... ...
common/modules/product/views/product-unit/create.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\modules\product\models\ProductUnit */
  8 +
  9 +$this->title = Yii::t('product', 'Create Product Unit');
  10 +$this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Product Units'), 'url' => ['index']];
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="product-unit-create">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 +
  17 + <?= $this->render('_form', [
  18 + 'model' => $model,
  19 + ]) ?>
  20 +
  21 +</div>
... ...
common/modules/product/views/product-unit/index.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\grid\GridView;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $searchModel common\modules\product\models\ProductUnitSearch */
  8 +/* @var $dataProvider yii\data\ActiveDataProvider */
  9 +
  10 +$this->title = Yii::t('product', 'Product Units');
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="product-unit-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', 'Create Product Unit'), ['create'], ['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 + 'code:html',
  29 + 'is_default:boolean',
  30 +
  31 + ['class' => 'yii\grid\ActionColumn'],
  32 + ],
  33 + ]); ?>
  34 +</div>
... ...
common/modules/product/views/product-unit/update.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +
  5 +/* @var $this yii\web\View */
  6 +/* @var $model common\modules\product\models\ProductUnit */
  7 +
  8 +$this->title = Yii::t('product', 'Update {modelClass}: ', [
  9 + 'modelClass' => 'Product Unit',
  10 +]) . $model->name;
  11 +$this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Product Units'), 'url' => ['index']];
  12 +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->product_unit_id]];
  13 +$this->params['breadcrumbs'][] = Yii::t('product', 'Update');
  14 +?>
  15 +<div class="product-unit-update">
  16 +
  17 + <h1><?= Html::encode($this->title) ?></h1>
  18 +
  19 + <?= $this->render('_form', [
  20 + 'model' => $model,
  21 + ]) ?>
  22 +
  23 +</div>
... ...
common/modules/product/views/product-unit/view.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\DetailView;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\modules\product\models\ProductUnit */
  8 +
  9 +$this->title = $model->name;
  10 +$this->params['breadcrumbs'][] = ['label' => Yii::t('product', 'Product Units'), 'url' => ['index']];
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="product-unit-view">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 +
  17 + <p>
  18 + <?= Html::a(Yii::t('product', 'Update'), ['update', 'id' => $model->product_unit_id], ['class' => 'btn btn-primary']) ?>
  19 + <?= Html::a(Yii::t('product', 'Delete'), ['delete', 'id' => $model->product_unit_id], [
  20 + 'class' => 'btn btn-danger',
  21 + 'data' => [
  22 + 'confirm' => Yii::t('product', 'Are you sure you want to delete this item?'),
  23 + 'method' => 'post',
  24 + ],
  25 + ]) ?>
  26 + </p>
  27 +
  28 + <?= DetailView::widget([
  29 + 'model' => $model,
  30 + 'attributes' => [
  31 + 'product_unit_id',
  32 + 'name',
  33 + 'code',
  34 + 'is_default:boolean',
  35 + ],
  36 + ]) ?>
  37 +
  38 +</div>
... ...
common/modules/product/widgets/views/brandsCarousel.php
... ... @@ -3,7 +3,7 @@
3 3 <div class="prods_carousel">
4 4 <ul>
5 5 <?php foreach($brands as $brand) :?>
6   - <li><span><a href="<?= \yii\helpers\Url::to('/brands/'. $brand->alias)?>" title="<?= $brand->name?>"><img src="<?= $brand->image?>"></a></span></li>
  6 + <li><span><a href="<?= \yii\helpers\Url::to('/brands/'. $brand->alias)?>" title="<?= $brand->name?>"><img src="<?= $brand->imageUrl?>"></a></span></li>
7 7 <?php endforeach?>
8 8 </ul>
9 9 </div>
... ...
common/modules/product/widgets/views/submenu.php
... ... @@ -12,7 +12,7 @@
12 12 <?php if (empty($_item->image)) :?>
13 13 <img valign="top" src="/images/no_photo.png">
14 14 <?php else :?>
15   - <img valign="top" src="<?= $_item->image?>">
  15 + <img valign="top" src="<?= $_item->imageUrl?>">
16 16 <?php endif?>
17 17 </div>
18 18 <div class="title"><?= $_item->categoryName->value?></div>
... ... @@ -34,7 +34,7 @@
34 34 <?php if (empty($_item['item']->image)) :?>
35 35 <img valign="top" src="/images/no_photo.png">
36 36 <?php else :?>
37   - <img valign="top" src="<?= $_item['item']->image?>" alt="<?= $_item['item']->categoryName->value?>">
  37 + <img valign="top" src="<?= $_item['item']->imageUrl?>" alt="<?= $_item['item']->categoryName->value?>">
38 38 <?php endif?>
39 39 </div>
40 40 <div class="title"><?= $_item['item']->categoryName->value?></div>
... ...
common/translation/ru/product.php
1 1 <?php
2 2 return [
  3 + 'Create' => 'Создать',
  4 + 'Create and continue' => 'Создать и продолжить',
  5 + 'Update' => 'Изменить',
  6 + 'Delete' => 'Удалить',
  7 + 'Is Default' => 'По-умолчанию',
  8 + 'Name' => 'Наименование',
  9 + 'Code' => 'Код',
  10 + 'Description' => 'Описание',
  11 + 'Video embeded' => 'Встраиваемое видео',
  12 + 'Category' => 'Категория',
3 13 'Categories' => 'Категории',
  14 + 'Select categories' => 'Выберите категории',
4 15 'Create Category' => 'Создать Категорию',
5   - 'Name' => 'Наименование',
  16 + 'Product' => 'Товар',
  17 + 'Products' => 'Товары',
  18 + 'Variants' => 'Варианты',
  19 + 'Variant' => 'Вариант',
  20 + 'Sku' => 'Артикул',
  21 + 'SKU' => 'Артикул',
  22 + 'Unit' => 'Ед.измерения',
  23 + 'Stock' => 'Остаток',
  24 + 'Is top' => 'ТОП',
  25 + 'Is new' => 'Новинка',
  26 + 'Create Product' => 'Создать Товар',
  27 + 'Price' => 'Цена',
  28 + 'Old price' => 'Старая цена',
6 29 'Set populary' => 'Сделать популярной',
7 30 'Set not populary' => 'Сделать не популярной',
8 31 'Remote ID' => 'ID в 1С',
9 32 'Search for "{keywords}"' => 'Поиск по "{keywords}"',
10 33 'Search for "{keywords}" in category "{category}"' => 'Поиск по "{keywords}" в категории "{category}"',
  34 + 'Name of the brand' => 'Имя бренда',
  35 + 'Brand' => 'Бренд',
  36 + 'Brands' => 'Бренды',
  37 + 'Select brand' => 'Выберите бренд',
  38 + 'Create Brand' => 'Создать бренд',
  39 + 'Category Name' => 'Имя категории',
  40 + 'Alias' => 'Псевдоним',
  41 + 'Product Units' => 'Единицы измерения',
  42 + 'Product Unit' => 'Единица измерения',
  43 + 'Image' => 'Изображение',
11 44 ];
12 45 \ No newline at end of file
... ...
common/translation/ru/rubrication.php 0 → 100644
  1 +<?php
  2 +
  3 +return [
  4 + 'Root category' => 'Корневая категория',
  5 + 'Parent category' => 'Родительская категория',
  6 +];
0 7 \ No newline at end of file
... ...