Commit 4902c7475133d38c547767bdb4657398dd53c89d
1 parent
564ca613
-
Showing
12 changed files
with
141 additions
and
66 deletions
 
Show diff stats
common/modules/product/models/Product.php
| ... | ... | @@ -127,8 +127,8 @@ class Product extends \yii\db\ActiveRecord | 
| 127 | 127 | */ | 
| 128 | 128 | public function getImageUrl() | 
| 129 | 129 | { | 
| 130 | - // return a default image placeholder if your source image is not found | |
| 131 | - return !empty($this->image) ? $this->image->imageUrl : '/images/no_photo.png'; | |
| 130 | + $image = empty($this->variant) ? null : $this->variant->image; | |
| 131 | + return !empty($image) ? $image->imageUrl : '/images/no_photo.png'; | |
| 132 | 132 | } | 
| 133 | 133 | |
| 134 | 134 | /** | 
| ... | ... | @@ -136,7 +136,7 @@ class Product extends \yii\db\ActiveRecord | 
| 136 | 136 | */ | 
| 137 | 137 | public function getImages() | 
| 138 | 138 | { | 
| 139 | - return $this->hasMany(ProductImage::className(), ['product_id' => 'product_id']); | |
| 139 | + return $this->hasMany(ProductImage::className(), ['product_id' => 'product_id'])->filterWhere(['is', 'product_variant_id', NULL]); | |
| 140 | 140 | } | 
| 141 | 141 | |
| 142 | 142 | /** | 
| ... | ... | @@ -144,7 +144,7 @@ class Product extends \yii\db\ActiveRecord | 
| 144 | 144 | */ | 
| 145 | 145 | public function getVariant() | 
| 146 | 146 | { | 
| 147 | - return $this->hasOne(ProductVariant::className(), ['product_id' => 'product_id']); | |
| 147 | + return $this->hasOne(ProductVariant::className(), ['product_id' => 'product_id'])->orderBy('product_variant.product_variant_id', SORT_ASC); | |
| 148 | 148 | } | 
| 149 | 149 | |
| 150 | 150 | public function getVariantPrice() { | 
| ... | ... | @@ -215,27 +215,29 @@ class Product extends \yii\db\ActiveRecord | 
| 215 | 215 | // | 
| 216 | 216 | // } | 
| 217 | 217 | |
| 218 | - $todel = []; | |
| 219 | - foreach ($this->variants ? : [] as $_variant) { | |
| 220 | - $todel[$_variant->product_variant_id] = $_variant->product_variant_id; | |
| 221 | - } | |
| 222 | - foreach ($this->_variants as $_variant) { | |
| 223 | - if (!is_array($_variant)) { | |
| 224 | - return; | |
| 218 | + if (!empty($this->_variants)) { | |
| 219 | + $todel = []; | |
| 220 | + foreach ($this->variants ?: [] as $_variant) { | |
| 221 | + $todel[$_variant->product_variant_id] = $_variant->product_variant_id; | |
| 225 | 222 | } | 
| 226 | - if (!empty($_variant['product_variant_id'])) { | |
| 227 | - unset($todel[$_variant['product_variant_id']]); | |
| 228 | - $model = ProductVariant::findOne($_variant['product_variant_id']); | |
| 229 | - } else { | |
| 230 | - $model = new ProductVariant(); | |
| 223 | + foreach ($this->_variants as $_variant) { | |
| 224 | + if (!is_array($_variant)) { | |
| 225 | + return; | |
| 226 | + } | |
| 227 | + if (!empty($_variant['product_variant_id'])) { | |
| 228 | + unset($todel[$_variant['product_variant_id']]); | |
| 229 | + $model = ProductVariant::findOne($_variant['product_variant_id']); | |
| 230 | + } else { | |
| 231 | + $model = new ProductVariant(); | |
| 232 | + } | |
| 233 | + $_variant['product_id'] = $this->product_id; | |
| 234 | + $model->load(['ProductVariant' => $_variant]); | |
| 235 | + $model->product_id = $this->product_id; | |
| 236 | + $model->save(); | |
| 237 | + } | |
| 238 | + if (!empty($todel)) { | |
| 239 | + ProductVariant::deleteAll(['product_variant_id' => $todel]); | |
| 231 | 240 | } | 
| 232 | - $_variant['product_id'] = $this->product_id; | |
| 233 | - $model->load(['ProductVariant' => $_variant]); | |
| 234 | - $model->product_id = $this->product_id; | |
| 235 | - $model->save(); | |
| 236 | - } | |
| 237 | - if (!empty($todel)) { | |
| 238 | - ProductVariant::deleteAll(['product_variant_id' => $todel]); | |
| 239 | 241 | } | 
| 240 | 242 | } | 
| 241 | 243 | ... | ... | 
common/modules/product/models/ProductSearch.php
| ... | ... | @@ -14,6 +14,8 @@ use yii\web\NotFoundHttpException; | 
| 14 | 14 | class ProductSearch extends Product | 
| 15 | 15 | { | 
| 16 | 16 | public $brand_name; | 
| 17 | + public $brand_id; | |
| 18 | + public $category_id; | |
| 17 | 19 | public $category_name; | 
| 18 | 20 | public $variant_sku; | 
| 19 | 21 | |
| ... | ... | @@ -23,7 +25,7 @@ class ProductSearch extends Product | 
| 23 | 25 | public function rules() | 
| 24 | 26 | { | 
| 25 | 27 | return [ | 
| 26 | - [['name', 'brand_name', 'category_name', 'variant_sku'], 'safe'], | |
| 28 | + [['name', 'brand_name', 'brand_id', 'category_id', 'category_name', 'variant_sku'], 'safe'], | |
| 27 | 29 | [['tax_brand_id', 'product_id'], 'integer'], | 
| 28 | 30 | [['is_top', 'is_new', 'akciya'], 'boolean'], | 
| 29 | 31 | ]; | 
| ... | ... | @@ -49,17 +51,16 @@ class ProductSearch extends Product | 
| 49 | 51 | { | 
| 50 | 52 | $query = Product::find(); | 
| 51 | 53 | |
| 52 | - // add conditions that should always apply here | |
| 54 | + $query->joinWith(['brand', 'brand.brandNames', 'categories', 'categories.categoryNames', 'variant']); | |
| 55 | + | |
| 56 | + $query->groupBy(['product.product_id']); | |
| 57 | + $query->orderBy('product.product_id', 'DESC'); | |
| 53 | 58 | |
| 54 | 59 | $dataProvider = new ActiveDataProvider([ | 
| 55 | 60 | 'query' => $query, | 
| 56 | 61 | ]); | 
| 57 | 62 | |
| 58 | - $this->load($params); | |
| 59 | - | |
| 60 | - if (!$this->validate()) { | |
| 61 | - // uncomment the following line if you do not want to return any records when validation fails | |
| 62 | - // $query->where('0=1'); | |
| 63 | + if ( !($this->load($params) && $this->validate()) ) { | |
| 63 | 64 | return $dataProvider; | 
| 64 | 65 | } | 
| 65 | 66 | |
| ... | ... | @@ -77,8 +78,6 @@ class ProductSearch extends Product | 
| 77 | 78 | ] | 
| 78 | 79 | ]); | 
| 79 | 80 | |
| 80 | - $query->joinWith(['brand', 'brand.brandNames', 'categories', 'categories.categoryNames', 'variant']); | |
| 81 | - | |
| 82 | 81 | if (isset($this->is_top)) { | 
| 83 | 82 | $query->andFilterWhere([ | 
| 84 | 83 | 'is_top' => (bool)$this->is_top, | 
| ... | ... | @@ -95,18 +94,16 @@ class ProductSearch extends Product | 
| 95 | 94 | ]); | 
| 96 | 95 | } | 
| 97 | 96 | $query->andFilterWhere([ | 
| 98 | - 'tax_brand_id' => $this->tax_brand_id, | |
| 99 | - 'product_id' => $this->product_id, | |
| 97 | + 'product.brand_id' => $this->brand_id, | |
| 98 | + 'product.product_id' => $this->product_id, | |
| 99 | + 'product_category.category_id' => $this->category_id | |
| 100 | 100 | ]); | 
| 101 | 101 | |
| 102 | - $query->andFilterWhere(['ilike', 'name', $this->name]); | |
| 102 | + $query->andFilterWhere(['ilike', 'product.name', $this->name]); | |
| 103 | 103 | $query->andFilterWhere(['ilike', 'brand_name.value', $this->brand_name]); | 
| 104 | 104 | $query->andFilterWhere(['ilike', 'category_name.value', $this->category_name]); | 
| 105 | 105 | $query->andFilterWhere(['ilike', 'product_variant.sku', $this->variant_sku]); | 
| 106 | 106 | |
| 107 | - $query->groupBy(['product.product_id']); | |
| 108 | - $query->orderBy('product.product_id', 'DESC'); | |
| 109 | - | |
| 110 | 107 | return $dataProvider; | 
| 111 | 108 | } | 
| 112 | 109 | ... | ... | 
common/modules/product/models/ProductVariant.php
| ... | ... | @@ -111,7 +111,7 @@ class ProductVariant extends \yii\db\ActiveRecord | 
| 111 | 111 | } | 
| 112 | 112 | |
| 113 | 113 | public function getStock_caption() { | 
| 114 | - return is_null($this->stock) ? 'โ' : intval($this->stock); | |
| 114 | + return is_null($this->stock) ? 'โ' : ($this->stock > 0 ? Yii::t('product', 'Enable') : Yii::t('product', 'Disable')); // intval($this->stock); | |
| 115 | 115 | } | 
| 116 | 116 | |
| 117 | 117 | /** | ... | ... | 
common/modules/product/views/manage/index.php
| ... | ... | @@ -2,6 +2,11 @@ | 
| 2 | 2 | |
| 3 | 3 | use yii\helpers\Html; | 
| 4 | 4 | use yii\grid\GridView; | 
| 5 | +use yii\helpers\ArrayHelper; | |
| 6 | +use kartik\select2\Select2; | |
| 7 | +use common\components\artboxtree\ArtboxTreeHelper; | |
| 8 | +use common\modules\product\helpers\ProductHelper; | |
| 9 | + | |
| 5 | 10 | /* @var $this yii\web\View */ | 
| 6 | 11 | /* @var $searchModel common\modules\product\models\ProductSearch */ | 
| 7 | 12 | /* @var $dataProvider yii\data\ActiveDataProvider */ | 
| ... | ... | @@ -28,11 +33,45 @@ $this->params['breadcrumbs'][] = $this->title; | 
| 28 | 33 | 'label' => Yii::t('product', 'Brand'), | 
| 29 | 34 | 'attribute' => 'brand_name', | 
| 30 | 35 | 'value' => 'brand.name', | 
| 36 | + 'format' => 'raw', | |
| 37 | + 'filter' => Select2::widget([ | |
| 38 | + 'model' => $searchModel, | |
| 39 | + 'attribute' => 'brand_id', | |
| 40 | + 'data' => ArrayHelper::map(ProductHelper::getBrands()->all(), 'brand_id', 'name'), | |
| 41 | + 'language' => 'ru', | |
| 42 | + 'options' => [ | |
| 43 | + 'placeholder' => Yii::t('product', 'Select brand'), | |
| 44 | + 'multiple' => false, | |
| 45 | + ], | |
| 46 | + 'pluginOptions' => [ | |
| 47 | + 'allowClear' => true | |
| 48 | + ], | |
| 49 | + ]) | |
| 31 | 50 | ], | 
| 32 | 51 | [ | 
| 33 | 52 | 'label' => Yii::t('product', 'Category'), | 
| 34 | 53 | 'attribute' => 'category_name', | 
| 35 | - 'value' => 'category.name', | |
| 54 | + 'value' => function($model) { | |
| 55 | + $categories = []; | |
| 56 | + foreach ($model->categories as $category) { | |
| 57 | + $categories[] = $category->name; | |
| 58 | + } | |
| 59 | + return implode(", ", $categories); | |
| 60 | + }, | |
| 61 | + 'format' => 'raw', | |
| 62 | + 'filter' => Select2::widget([ | |
| 63 | + 'model' => $searchModel, | |
| 64 | + 'attribute' => 'category_id', | |
| 65 | + 'data' => ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'category_id', 'name'), | |
| 66 | + 'language' => 'ru', | |
| 67 | + 'options' => [ | |
| 68 | + 'placeholder' => Yii::t('product', 'Select category'), | |
| 69 | + 'multiple' => false, | |
| 70 | + ], | |
| 71 | + 'pluginOptions' => [ | |
| 72 | + 'allowClear' => true | |
| 73 | + ], | |
| 74 | + ]) | |
| 36 | 75 | ], | 
| 37 | 76 | [ | 
| 38 | 77 | 'label' => Yii::t('product', 'SKU'), | 
| ... | ... | @@ -40,9 +79,12 @@ $this->params['breadcrumbs'][] = $this->title; | 
| 40 | 79 | 'value' => 'variant.sku', | 
| 41 | 80 | ], | 
| 42 | 81 | 'variant.price', | 
| 43 | - 'variant.stock_caption', | |
| 44 | - | |
| 45 | - | |
| 82 | + 'variant.price_old', | |
| 83 | + [ | |
| 84 | + 'label' => Yii::t('product', 'Stock'), | |
| 85 | + 'attribute' => 'variant_stock', | |
| 86 | + 'value' => 'variant.stock_caption', | |
| 87 | + ], | |
| 46 | 88 | [ | 
| 47 | 89 | 'class' => 'yii\grid\ActionColumn', | 
| 48 | 90 | 'template' => '{view} |{is_top} {is_new} {akciya} | {update} {delete}', | ... | ... | 
common/modules/product/widgets/views/product_smart.php
| ... | ... | @@ -12,6 +12,19 @@ use yii\helpers\Url; | 
| 12 | 12 | <?= \common\components\artboximage\ArtboxImageHelper::getImage($product->imageUrl, 'list')?> | 
| 13 | 13 | </a> | 
| 14 | 14 | </div> | 
| 15 | + <?php if(!empty($product->is_top) || !empty($product->is_new) || !empty($product->akciya)) :?> | |
| 16 | + <ul class="product-special"> | |
| 17 | + <?php if(!empty($product->is_top)) :?> | |
| 18 | + <li class="top">top </li> | |
| 19 | + <?php endif?> | |
| 20 | + <?php if(!empty($product->is_new)) :?> | |
| 21 | + <li class="new">new </li> | |
| 22 | + <?php endif?> | |
| 23 | + <?php if(!empty($product->akciya)) :?> | |
| 24 | + <li class="promo">promo </li> | |
| 25 | + <?php endif?> | |
| 26 | + </ul> | |
| 27 | + <?php endif?> | |
| 15 | 28 | <a href="<?= Url::to([ | 
| 16 | 29 | 'catalog/product', | 
| 17 | 30 | 'product' => $product]) | ... | ... | 
common/modules/product/widgets/views/products_block.php
| 1 | 1 | <?php | 
| 2 | 2 | use yii\web\View; | 
| 3 | 3 | ?> | 
| 4 | +<?php if(!empty($products)) :?> | |
| 4 | 5 | <div class="_prd_spec-wr"> | 
| 5 | - <div class="special-products products<?= | |
| 6 | - | |
| 7 | - (!empty($class) ? ' '. $class : '')?>"> | |
| 6 | + <div class="special-products products<?= (!empty($class) ? ' '. $class : '')?>"> | |
| 8 | 7 | <h3><?= $title?></h3> | 
| 9 | 8 | <div class="owl-carousel"> | 
| 10 | 9 | <?php foreach($products as $product) :?> | 
| ... | ... | @@ -14,7 +13,7 @@ | 
| 14 | 13 | <div class="both"></div> | 
| 15 | 14 | </div> | 
| 16 | 15 | </div> | 
| 17 | - | |
| 18 | 16 | <?php $js = '$(".owl-carousel").owlCarousel()'; | 
| 19 | 17 | $this->registerJs($js, View::POS_READY); | 
| 20 | -?> | |
| 21 | 18 | \ No newline at end of file | 
| 19 | +?> | |
| 20 | +<?php endif?> | ... | ... | 
common/translation/ru/product.php
| ... | ... | @@ -13,4 +13,17 @@ return [ | 
| 13 | 13 | 'Top products' => 'ะะพะฟัะปััะฝัะต', | 
| 14 | 14 | 'Brands' => 'ะัะตะฝะดั', | 
| 15 | 15 | 'Brand' => 'ะัะตะฝะด', | 
| 16 | + 'Categories' => 'ะะฐัะตะณะพัะธะธ', | |
| 17 | + 'Category' => 'ะะฐัะตะณะพัะธั', | |
| 18 | + 'Select brand' => 'ะัะฑะตัะธัะต ะฑัะตะฝะด', | |
| 19 | + 'Select category' => 'ะัะฑะตัะธัะต ะบะฐัะตะณะพัะธั', | |
| 20 | + 'SKU' => 'ะััะธะบัะป', | |
| 21 | + 'Stock' => 'ะััะฐัะพะบ', | |
| 22 | + 'Price' => 'ะฆะตะฝะฐ', | |
| 23 | + 'Price Old' => 'ะกัะฐัะฐั ะฆะตะฝะฐ', | |
| 24 | + 'Products' => 'ะขะพะฒะฐัั', | |
| 25 | + 'Product' => 'ะขะพะฒะฐั', | |
| 26 | + 'Create Product' => 'ะกะพะทะดะฐัั ะขะพะฒะฐั', | |
| 27 | + 'Enable' => 'ะะพัััะฟะฝะพ', | |
| 28 | + 'Disable' => 'ะัััััะฒัะตั', | |
| 16 | 29 | ]; | 
| 17 | 30 | \ No newline at end of file | ... | ... | 
No preview for this file type
frontend/models/ProductFrontendSearch.php
| ... | ... | @@ -51,18 +51,18 @@ class ProductFrontendSearch extends Product { | 
| 51 | 51 | } else { | 
| 52 | 52 | $query = Product::find(); | 
| 53 | 53 | } | 
| 54 | - $query->joinWith('variant'); | |
| 55 | - $query->joinWith('brand'); | |
| 56 | - $query->joinWith('image'); | |
| 57 | - $query->joinWith('categories'); | |
| 58 | - if (empty($_GET['sort']) || ($_GET['sort'] != 'price' && $_GET['sort'] != '-price')) { | |
| 59 | - $query->groupBy('product.product_id'); | |
| 60 | - } | |
| 54 | + $query->with(['variant', 'variant.image', 'brand', 'brand.brandName', 'category', 'category.categoryName']); | |
| 55 | + | |
| 56 | + $query->groupBy('product.product_id'); | |
| 57 | + | |
| 58 | +// if (empty($_GET['sort']) || ($_GET['sort'] != 'price' && $_GET['sort'] != '-price')) { | |
| 59 | +// $query->groupBy('product.product_id'); | |
| 60 | +// } | |
| 61 | 61 | |
| 62 | 62 | $dataProvider = new ActiveDataProvider([ | 
| 63 | 63 | 'query' => $query, | 
| 64 | 64 | 'pagination' => [ | 
| 65 | - 'pageSize' => 15, | |
| 65 | + 'pageSize' => 16, | |
| 66 | 66 | ], | 
| 67 | 67 | 'sort' => [ | 
| 68 | 68 | 'attributes' => [ | ... | ... | 
frontend/views/catalog/product.php
| ... | ... | @@ -160,7 +160,7 @@ $this->registerJs (" | 
| 160 | 160 | <?php if(!empty($product->video)) :?> | 
| 161 | 161 | <li><a href="#">ะะธะดะตะพ</a> | 
| 162 | 162 | <div class="info product-thumb-video"> | 
| 163 | - <?= \cics\widgets\VideoEmbed::widget(['responsive' => false, 'url' => $product->video]); ?> | |
| 163 | + <?= strpos($product->video, '<iframe') !== FALSE || strpos($product->video, '<object') !== FALSE ? $product->video : \cics\widgets\VideoEmbed::widget(['responsive' => false, 'url' => $product->video]); ?> | |
| 164 | 164 | </div> | 
| 165 | 165 | </li> | 
| 166 | 166 | <?php endif?> | 
| ... | ... | @@ -182,6 +182,11 @@ $this->registerJs (" | 
| 182 | 182 | </ul> | 
| 183 | 183 | </div> | 
| 184 | 184 | <div class="both"></div> | 
| 185 | + | |
| 186 | + <?= \common\modules\product\widgets\specialProducts::widget(['type' => 'promo'])?> | |
| 187 | + <?= \common\modules\product\widgets\specialProducts::widget(['type' => 'new'])?> | |
| 188 | + <?= \common\modules\product\widgets\specialProducts::widget(['type' => 'top'])?> | |
| 189 | + <?= \common\modules\product\widgets\lastProducts::widget()?> | |
| 185 | 190 | </div> | 
| 186 | 191 | <?php | 
| 187 | 192 | $this->registerJs (" | ... | ... | 
frontend/views/catalog/product_item.php
| ... | ... | @@ -6,19 +6,19 @@ use yii\helpers\Url; | 
| 6 | 6 | <div class="boxitem"> | 
| 7 | 7 | <div class="pixbox"> | 
| 8 | 8 | <a href="<?= Url::to(['catalog/product', 'product' => $product,'#' => 'm' .$product->variant->product_variant_id]) ?>"> | 
| 9 | - <?= \common\components\artboximage\ArtboxImageHelper::getImage($product->variant->image->imageUrl, 'list')?> | |
| 9 | + <?= \common\components\artboximage\ArtboxImageHelper::getImage($product->variant->imageUrl, 'list')?> | |
| 10 | 10 | </a> | 
| 11 | 11 | </div> | 
| 12 | 12 | <?php if(!empty($product->is_top) || !empty($product->is_new) || !empty($product->akciya)) :?> | 
| 13 | 13 | <ul class="product-special"> | 
| 14 | 14 | <?php if(!empty($product->is_top)) :?> | 
| 15 | - <li class="top">top </li> | |
| 15 | + <li class="top">top</li> | |
| 16 | 16 | <?php endif?> | 
| 17 | 17 | <?php if(!empty($product->is_new)) :?> | 
| 18 | - <li class="new">new </li> | |
| 18 | + <li class="new">new</li> | |
| 19 | 19 | <?php endif?> | 
| 20 | 20 | <?php if(!empty($product->akciya)) :?> | 
| 21 | - <li class="promo">promo </li> | |
| 21 | + <li class="promo">promo</li> | |
| 22 | 22 | <?php endif?> | 
| 23 | 23 | </ul> | 
| 24 | 24 | <?php endif?> | 
| ... | ... | @@ -54,11 +54,13 @@ use yii\helpers\Url; | 
| 54 | 54 | |
| 55 | 55 | <div class="mycarousel"> | 
| 56 | 56 | <ul class="jcarousel jcarousel-skin-tango"> | 
| 57 | - <?php foreach (array_reverse($product->variants) as $variant) : ?> | |
| 58 | - <?php if (!is_null($variant->stock) && empty($variant->stock)) continue;?> | |
| 57 | + <?php foreach ($product->variants as $variant) : ?> | |
| 59 | 58 | <?php if (!empty($variant->image)) :?> | 
| 60 | 59 | <li> | 
| 61 | - <a href="<?= Url::to(['catalog/product', 'product' => $product, '#' => 'm' . $variant->product_variant_id]) ?>"> | |
| 60 | + <a href="<?= Url::to([ | |
| 61 | + 'catalog/product', | |
| 62 | + 'product' => $product, | |
| 63 | + '#' => 'm' . $variant->product_variant_id]) ?>"> | |
| 62 | 64 | <?= \common\components\artboximage\ArtboxImageHelper::getImage($variant->imageUrl, 'product_variant')?> | 
| 63 | 65 | </a> | 
| 64 | 66 | </li> | ... | ... | 
frontend/views/catalog/products.php
| ... | ... | @@ -164,7 +164,6 @@ $this->registerJsFile (Yii::getAlias('@web/js/ion.rangeSlider.js')); | 
| 164 | 164 | <?= \yii\widgets\LinkSorter::widget([ | 
| 165 | 165 | 'sort' => $productProvider->sort, | 
| 166 | 166 | 'attributes' => [ | 
| 167 | - 'name', | |
| 168 | 167 | 'price', | 
| 169 | 168 | ] | 
| 170 | 169 | ]); | 
| ... | ... | @@ -174,7 +173,7 @@ $this->registerJsFile (Yii::getAlias('@web/js/ion.rangeSlider.js')); | 
| 174 | 173 | <div class="products pn"> | 
| 175 | 174 | <ul> | 
| 176 | 175 | <?php foreach($productProvider->models as $product) :?> | 
| 177 | - <?php require(__DIR__ .'/product_item.php')?> | |
| 176 | + <?= $this->render('/catalog/product_item.php', ['product' => $product])?> | |
| 178 | 177 | <?php endforeach?> | 
| 179 | 178 | </ul> | 
| 180 | 179 | <div class="both"></div> | 
| ... | ... | @@ -191,5 +190,8 @@ $this->registerJsFile (Yii::getAlias('@web/js/ion.rangeSlider.js')); | 
| 191 | 190 | </div> | 
| 192 | 191 | <div class="both"></div> | 
| 193 | 192 | |
| 193 | + <?= \common\modules\product\widgets\specialProducts::widget(['type' => 'promo'])?> | |
| 194 | + <?= \common\modules\product\widgets\specialProducts::widget(['type' => 'new'])?> | |
| 195 | + <?= \common\modules\product\widgets\specialProducts::widget(['type' => 'top'])?> | |
| 194 | 196 | <?= \common\modules\product\widgets\lastProducts::widget()?> | 
| 195 | 197 | </div> | 
| 196 | 198 | \ No newline at end of file | ... | ... | 
