Commit fc66ded4b7166f769922378dcb08c3e0c701915b
1 parent
aee73024
Artbox great prepairings
Showing
17 changed files
with
1204 additions
and
356 deletions
Show diff stats
frontend/controllers/CategoryController.php
@@ -41,7 +41,7 @@ | @@ -41,7 +41,7 @@ | ||
41 | $query = $filterHelper->buildQuery() | 41 | $query = $filterHelper->buildQuery() |
42 | ->innerJoinWith('category', false) | 42 | ->innerJoinWith('category', false) |
43 | ->andWhere([ 'product_to_category.category_id' => $model->id ]) | 43 | ->andWhere([ 'product_to_category.category_id' => $model->id ]) |
44 | - ->with('image', 'variants', 'lang'); | 44 | + ->with('image', 'variants.image', 'lang'); |
45 | $dataProvider = new ActiveDataProvider( | 45 | $dataProvider = new ActiveDataProvider( |
46 | [ | 46 | [ |
47 | 'query' => $query, | 47 | 'query' => $query, |
@@ -84,6 +84,9 @@ | @@ -84,6 +84,9 @@ | ||
84 | $alias = Alias::find() | 84 | $alias = Alias::find() |
85 | ->where([ 'value' => $category ]) | 85 | ->where([ 'value' => $category ]) |
86 | ->one(); | 86 | ->one(); |
87 | + if (empty($alias)) { | ||
88 | + throw new NotFoundHttpException('Category not found'); | ||
89 | + } | ||
87 | $id = $filter->getIdFromRoute($alias->route); | 90 | $id = $filter->getIdFromRoute($alias->route); |
88 | /** | 91 | /** |
89 | * @var Category $model | 92 | * @var Category $model |
frontend/controllers/ProductController.php
1 | <?php | 1 | <?php |
2 | + | ||
2 | namespace frontend\controllers; | 3 | namespace frontend\controllers; |
3 | 4 | ||
4 | use artbox\catalog\models\Product; | 5 | use artbox\catalog\models\Product; |
@@ -9,7 +10,6 @@ | @@ -9,7 +10,6 @@ | ||
9 | use yii\helpers\Url; | 10 | use yii\helpers\Url; |
10 | use yii\web\Controller; | 11 | use yii\web\Controller; |
11 | use yii\web\NotFoundHttpException; | 12 | use yii\web\NotFoundHttpException; |
12 | - use Yii; | ||
13 | use yii\web\Response; | 13 | use yii\web\Response; |
14 | 14 | ||
15 | /** | 15 | /** |
@@ -25,28 +25,43 @@ | @@ -25,28 +25,43 @@ | ||
25 | * @param int $id | 25 | * @param int $id |
26 | * | 26 | * |
27 | * @return string | 27 | * @return string |
28 | + * @throws \yii\web\NotFoundHttpException | ||
28 | */ | 29 | */ |
29 | public function actionView($id) | 30 | public function actionView($id) |
30 | { | 31 | { |
31 | - $model = $this->findModel($id); | ||
32 | - /** | ||
33 | - * @var SeoComponent $seo | ||
34 | - */ | ||
35 | - $seo = Yii::$app->get('seo'); | ||
36 | - $seo->setModel($model->lang); | ||
37 | - $variant = $model->variants[ 0 ]; | ||
38 | - $groups = $variant->getSortedGroups(); | ||
39 | - $similar = $model->getSimilarProducts(8); | ||
40 | - | ||
41 | - return $this->render( | ||
42 | - 'view', | 32 | + $model = Product::find() |
33 | + ->with('variant') | ||
34 | + ->where([ 'id' => $id ]) | ||
35 | + ->one(); | ||
36 | + if (!$model || empty($model->variant)) { | ||
37 | + throw new NotFoundHttpException('Product not found'); | ||
38 | + } | ||
39 | + return $this->redirect( | ||
43 | [ | 40 | [ |
44 | - 'model' => $model, | ||
45 | - 'variant' => $variant, | ||
46 | - 'groups' => $groups, | ||
47 | - 'similar' => $similar, | 41 | + 'variant/view', |
42 | + 'id' => $model->variant->id, | ||
48 | ] | 43 | ] |
49 | ); | 44 | ); |
45 | + //Uncomment to have product page | ||
46 | + // $model = $this->findModel($id); | ||
47 | + // /** | ||
48 | + // * @var SeoComponent $seo | ||
49 | + // */ | ||
50 | + // $seo = Yii::$app->get('seo'); | ||
51 | + // $seo->setModel($model->lang); | ||
52 | + // $variant = $model->variants[ 0 ]; | ||
53 | + // $groups = $variant->getSortedGroups(); | ||
54 | + // $similar = $model->getSimilarProducts(8); | ||
55 | + // | ||
56 | + // return $this->render( | ||
57 | + // 'view', | ||
58 | + // [ | ||
59 | + // 'model' => $model, | ||
60 | + // 'variant' => $variant, | ||
61 | + // 'groups' => $groups, | ||
62 | + // 'similar' => $similar, | ||
63 | + // ] | ||
64 | + // ); | ||
50 | } | 65 | } |
51 | 66 | ||
52 | /** | 67 | /** |
@@ -109,7 +124,7 @@ | @@ -109,7 +124,7 @@ | ||
109 | ->andWhere( | 124 | ->andWhere( |
110 | [ | 125 | [ |
111 | 'variant_id' => \Yii::$app->request->post('variant'), | 126 | 'variant_id' => \Yii::$app->request->post('variant'), |
112 | - | 127 | + |
113 | ] | 128 | ] |
114 | ) | 129 | ) |
115 | ->one(); | 130 | ->one(); |
@@ -133,7 +148,7 @@ | @@ -133,7 +148,7 @@ | ||
133 | 'message' => \Yii::t('app', 'Товар убран из избранного'), | 148 | 'message' => \Yii::t('app', 'Товар убран из избранного'), |
134 | ]; | 149 | ]; |
135 | } | 150 | } |
136 | - | 151 | + |
137 | return [ | 152 | return [ |
138 | 'button' => Html::button( | 153 | 'button' => Html::button( |
139 | Html::tag('i', '', [ 'class' => 'fa fa-heart' ]), | 154 | Html::tag('i', '', [ 'class' => 'fa fa-heart' ]), |
@@ -169,7 +184,7 @@ | @@ -169,7 +184,7 @@ | ||
169 | $model->user_id = \Yii::$app->request->post('user'); | 184 | $model->user_id = \Yii::$app->request->post('user'); |
170 | $model->variant_id = \Yii::$app->request->post('variant'); | 185 | $model->variant_id = \Yii::$app->request->post('variant'); |
171 | $model->product_id = \Yii::$app->request->post('product'); | 186 | $model->product_id = \Yii::$app->request->post('product'); |
172 | - | 187 | + |
173 | if ($model->save()) { | 188 | if ($model->save()) { |
174 | return [ | 189 | return [ |
175 | 'button' => Html::button( | 190 | 'button' => Html::button( |
@@ -190,7 +205,7 @@ | @@ -190,7 +205,7 @@ | ||
190 | 'message' => 'Товар добавлен в избранное', | 205 | 'message' => 'Товар добавлен в избранное', |
191 | ]; | 206 | ]; |
192 | } | 207 | } |
193 | - | 208 | + |
194 | return [ | 209 | return [ |
195 | 'button' => Html::button( | 210 | 'button' => Html::button( |
196 | Html::tag('i', '', [ 'class' => 'fa fa-heart-o' ]), | 211 | Html::tag('i', '', [ 'class' => 'fa fa-heart-o' ]), |
frontend/controllers/SiteController.php
@@ -76,17 +76,17 @@ | @@ -76,17 +76,17 @@ | ||
76 | ->where([ 'level' => 0 ]) | 76 | ->where([ 'level' => 0 ]) |
77 | ->all(); | 77 | ->all(); |
78 | $topItems = Product::find() | 78 | $topItems = Product::find() |
79 | - ->with('lang', 'image', 'variants') | 79 | + ->with('lang', 'image', 'variants.image') |
80 | ->is('mask', 1) | 80 | ->is('mask', 1) |
81 | ->limit(20) | 81 | ->limit(20) |
82 | ->all(); | 82 | ->all(); |
83 | $newItems = Product::find() | 83 | $newItems = Product::find() |
84 | - ->with('lang', 'image', 'variants') | 84 | + ->with('lang', 'image', 'variants.image') |
85 | ->is('mask', 2) | 85 | ->is('mask', 2) |
86 | ->limit(20) | 86 | ->limit(20) |
87 | ->all(); | 87 | ->all(); |
88 | $saleItems = Product::find() | 88 | $saleItems = Product::find() |
89 | - ->with('lang', 'image', 'variants') | 89 | + ->with('lang', 'image', 'variants.image') |
90 | ->is('mask', 4) | 90 | ->is('mask', 4) |
91 | ->limit(20) | 91 | ->limit(20) |
92 | ->all(); | 92 | ->all(); |
1 | +<?php | ||
2 | + | ||
3 | + namespace frontend\controllers; | ||
4 | + | ||
5 | + use artbox\catalog\models\Variant; | ||
6 | + use artbox\core\components\SeoComponent; | ||
7 | + use yii\db\ActiveQuery; | ||
8 | + use yii\web\Controller; | ||
9 | + use yii\web\NotFoundHttpException; | ||
10 | + use Yii; | ||
11 | + | ||
12 | + /** | ||
13 | + * Class VariantController | ||
14 | + * | ||
15 | + * @package frontend\controllers | ||
16 | + */ | ||
17 | + class VariantController extends Controller | ||
18 | + { | ||
19 | + /** | ||
20 | + * Show product by ID | ||
21 | + * | ||
22 | + * @param int $id | ||
23 | + * | ||
24 | + * @return string | ||
25 | + */ | ||
26 | + public function actionView($id) | ||
27 | + { | ||
28 | + $model = $this->findModel($id); | ||
29 | + /** | ||
30 | + * @var SeoComponent $seo | ||
31 | + */ | ||
32 | + $seo = Yii::$app->get('seo'); | ||
33 | + $seo->setModel($model->lang); | ||
34 | + $groups = $model->getSortedGroups(); | ||
35 | + $similar = $model->product->getSimilarProducts(8); | ||
36 | + | ||
37 | + return $this->render( | ||
38 | + 'view', | ||
39 | + [ | ||
40 | + 'model' => $model, | ||
41 | + 'groups' => $groups, | ||
42 | + 'similar' => $similar, | ||
43 | + ] | ||
44 | + ); | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Find variant by ID | ||
49 | + * | ||
50 | + * @param $id | ||
51 | + * | ||
52 | + * @return \artbox\catalog\models\Variant | ||
53 | + * @throws \yii\web\NotFoundHttpException | ||
54 | + */ | ||
55 | + protected function findModel($id) | ||
56 | + { | ||
57 | + /** | ||
58 | + * @var SeoComponent $seo | ||
59 | + */ | ||
60 | + $seo = \Yii::$app->get('seo'); | ||
61 | + /** | ||
62 | + * @var Variant $model | ||
63 | + */ | ||
64 | + $model = Variant::findWithFilters() | ||
65 | + ->with('lang', 'image') | ||
66 | + ->with( | ||
67 | + [ | ||
68 | + 'product' => function ($query) { | ||
69 | + /** | ||
70 | + * @var ActiveQuery $query | ||
71 | + */ | ||
72 | + $query->with('images') | ||
73 | + ->with( | ||
74 | + [ | ||
75 | + 'category' => function ($query) { | ||
76 | + /** | ||
77 | + * @var ActiveQuery $query | ||
78 | + */ | ||
79 | + $query->with('lang') | ||
80 | + ->with('parent.lang'); | ||
81 | + }, | ||
82 | + ] | ||
83 | + ); | ||
84 | + }, | ||
85 | + ] | ||
86 | + ) | ||
87 | + ->where([ 'id' => $id ]) | ||
88 | + ->one(); | ||
89 | + if (!empty($model)) { | ||
90 | + if ($model->lang->alias_id !== $seo->aliasId) { | ||
91 | + throw new NotFoundHttpException(\Yii::t('app', 'Wrong language')); | ||
92 | + } | ||
93 | + return $model; | ||
94 | + } else { | ||
95 | + throw new NotFoundHttpException(\Yii::t('app', 'Model not found')); | ||
96 | + } | ||
97 | + } | ||
98 | + } | ||
0 | \ No newline at end of file | 99 | \ No newline at end of file |
frontend/views/category/_product_item.php
@@ -31,6 +31,36 @@ | @@ -31,6 +31,36 @@ | ||
31 | ); | 31 | ); |
32 | ?> | 32 | ?> |
33 | </div> | 33 | </div> |
34 | + <div class="vcovers"> | ||
35 | + <div class="content"> | ||
36 | + <?php | ||
37 | + foreach ($product->variants as $variant) { | ||
38 | + ?> | ||
39 | + <div class="vcover"> | ||
40 | + <?php | ||
41 | + echo Html::a( | ||
42 | + Html::img( | ||
43 | + ImageHelper::set( | ||
44 | + $variant->image ? $variant->image->getPath() : '@frontend/web/img/no-image.png' | ||
45 | + ) | ||
46 | + ->fillResize(40, 40) | ||
47 | + ->render(), | ||
48 | + [ | ||
49 | + 'class' => 'img-responsive-image1', | ||
50 | + ] | ||
51 | + ), | ||
52 | + [ | ||
53 | + 'variant/view', | ||
54 | + 'id' => $variant->id, | ||
55 | + ] | ||
56 | + ); | ||
57 | + ?> | ||
58 | + </div> | ||
59 | + <?php | ||
60 | + } | ||
61 | + ?> | ||
62 | + </div> | ||
63 | + </div> | ||
34 | <!-- /.image --> | 64 | <!-- /.image --> |
35 | <div class="text"> | 65 | <div class="text"> |
36 | <h3> | 66 | <h3> |
1 | +<div class="modal-dialog modal-lg"> | ||
2 | + <div class="modal-content"> | ||
3 | + <div class="modal-header"> | ||
4 | + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | ||
5 | + <h4 class="modal-title callback text-center" id="Login"> | ||
6 | + <?php | ||
7 | + use artbox\core\helpers\ImageHelper; | ||
8 | + use yii\bootstrap\Html; | ||
9 | + | ||
10 | + echo Html::a( | ||
11 | + Html::tag( | ||
12 | + 'span', | ||
13 | + \Yii::t('app', 'Ваша корзина') | ||
14 | + ), | ||
15 | + [ | ||
16 | + '/checkout/index', | ||
17 | + ] | ||
18 | + ); | ||
19 | + ?> | ||
20 | + </h4> | ||
21 | + </div> | ||
22 | + <div class="modal-body"> | ||
23 | + <?php | ||
24 | + /** | ||
25 | + * @var \artbox\order\models\Basket $basket | ||
26 | + */ | ||
27 | + $basket = \Yii::$app->get('basket'); | ||
28 | + $data = $basket->getData(); | ||
29 | + $variants = []; | ||
30 | + if (!empty($data)) { | ||
31 | + $variants = $basket->findModels(array_keys($data)); | ||
32 | + } | ||
33 | + $formatter = \Yii::$app->formatter; | ||
34 | + $sum = 0; | ||
35 | + $sumDiscount = 0; | ||
36 | + foreach ($basket->findModels(array_keys($basket->getData())) as $variant) { | ||
37 | + $count = $basket->getItem($variant->id)[ 'count' ]; | ||
38 | + $sum += $variant->price * $count; | ||
39 | + if (!empty($variant->price_old)) { | ||
40 | + $sumDiscount += ( $variant->price_old - $variant->price ) * $count; | ||
41 | + } | ||
42 | + } | ||
43 | + | ||
44 | + if (!empty($variants)) { | ||
45 | + ?> | ||
46 | + <div class="clearfix"> | ||
47 | + <div class="col-md-12 clearfix"> | ||
48 | + <table class="table"> | ||
49 | + <thead> | ||
50 | + <tr> | ||
51 | + <th colspan="2"><?php echo \Yii::t('app', 'Продукт'); ?></th> | ||
52 | + <th><?php echo \Yii::t('app', 'Количество'); ?></th> | ||
53 | + <th><?php echo \Yii::t('app', 'Цена за единицу'); ?></th> | ||
54 | + <th><?php echo \Yii::t('app', 'Скидка'); ?></th> | ||
55 | + <th colspan="2"><?php echo \Yii::t('app', 'Всего'); ?></th> | ||
56 | + </tr> | ||
57 | + </thead> | ||
58 | + <tbody> | ||
59 | + <?php | ||
60 | + foreach ($variants as $variant) { | ||
61 | + $count = $basket->getItem($variant->id)[ 'count' ]; | ||
62 | + ?> | ||
63 | + <tr data-id="<?php echo $variant->id; ?>" class="product-row-basket"> | ||
64 | + <td> | ||
65 | + <?php | ||
66 | + echo Html::a( | ||
67 | + ImageHelper::set( | ||
68 | + $variant->product->image ? $variant->product->image->getPath( | ||
69 | + ) : '@frontend/img/no-image.png' | ||
70 | + ) | ||
71 | + ->fillResize(50, 50) | ||
72 | + ->renderImage( | ||
73 | + [ | ||
74 | + 'alt' => $variant->product->lang->title, | ||
75 | + 'title' => $variant->product->lang->title, | ||
76 | + ] | ||
77 | + ), | ||
78 | + [ | ||
79 | + '/product/view', | ||
80 | + 'id' => $variant->product->id, | ||
81 | + ], | ||
82 | + [ | ||
83 | + 'target' => '_blank', | ||
84 | + ] | ||
85 | + ); | ||
86 | + ?> | ||
87 | + </td> | ||
88 | + <td> | ||
89 | + <?php | ||
90 | + echo Html::a( | ||
91 | + $variant->product->lang->title, | ||
92 | + [ | ||
93 | + '/product/view', | ||
94 | + 'id' => $variant->product->id, | ||
95 | + ], | ||
96 | + [ | ||
97 | + 'target' => '_blank', | ||
98 | + ] | ||
99 | + ); | ||
100 | + ?> | ||
101 | + </td> | ||
102 | + <td> | ||
103 | + <?php | ||
104 | + echo Html::input( | ||
105 | + 'number', | ||
106 | + '', | ||
107 | + $count, | ||
108 | + [ | ||
109 | + 'class' => 'form-control increase-product-basket', | ||
110 | + ] | ||
111 | + ); | ||
112 | + ?> | ||
113 | + </td> | ||
114 | + <td> | ||
115 | + <?php | ||
116 | + echo $formatter->asDecimal($variant->price ? : 0, 2); | ||
117 | + ?> | ||
118 | + </td> | ||
119 | + <td> | ||
120 | + <?php | ||
121 | + if (!empty($variant->price_old)) { | ||
122 | + echo $formatter->asDecimal($variant->price_old - $variant->price, 2); | ||
123 | + } else { | ||
124 | + echo $formatter->asDecimal(0, 2); | ||
125 | + } | ||
126 | + ?> | ||
127 | + </td> | ||
128 | + <td> | ||
129 | + <?php | ||
130 | + echo $formatter->asDecimal( | ||
131 | + ( $variant->price ? : 0 ) * $count, | ||
132 | + 2 | ||
133 | + ); | ||
134 | + ?> | ||
135 | + </td> | ||
136 | + <td><a href="#" class="remove-product-cart"><i class="fa fa-trash-o"></i></a> | ||
137 | + </td> | ||
138 | + </tr> | ||
139 | + <?php | ||
140 | + } | ||
141 | + ?> | ||
142 | + </tbody> | ||
143 | + <tfoot> | ||
144 | + <tr> | ||
145 | + <th colspan="5"><?php echo \Yii::t('app', 'Всего'); ?></th> | ||
146 | + <th colspan="2"><?php echo $formatter->asDecimal($sum, 2); ?></th> | ||
147 | + </tr> | ||
148 | + </tfoot> | ||
149 | + </table> | ||
150 | + </div> | ||
151 | + <div class="col-md-12 clearfix"> | ||
152 | + <div class="box" id="order-summary"> | ||
153 | + <div class="box-header"> | ||
154 | + <h3>Итоговый счет</h3> | ||
155 | + </div> | ||
156 | + <p class="text-muted small"><?php echo \Yii::t( | ||
157 | + 'app', | ||
158 | + 'Стоимость доставки рассчитывается в зависимости от адреса и способа доставки' | ||
159 | + ); ?></p> | ||
160 | + | ||
161 | + <div class="table-responsive"> | ||
162 | + <table class="table"> | ||
163 | + <tbody> | ||
164 | + <tr> | ||
165 | + <td><?php echo \Yii::t('app', 'Всего за товары'); ?></td> | ||
166 | + <th><?php echo $formatter->asDecimal($sum, 2); ?></th> | ||
167 | + </tr> | ||
168 | + <tr> | ||
169 | + <td><?php echo \Yii::t('app', 'Сумма скидки'); ?></td> | ||
170 | + <th><?php echo $formatter->asDecimal($sumDiscount, 2); ?></th> | ||
171 | + </tr> | ||
172 | + <tr class="total"> | ||
173 | + <td><?php echo \Yii::t('app', 'Итого к оплате'); ?></td> | ||
174 | + <th><?php echo $formatter->asDecimal($sum, 2); ?></th> | ||
175 | + </tr> | ||
176 | + </tbody> | ||
177 | + </table> | ||
178 | + </div> | ||
179 | + </div> | ||
180 | + </div> | ||
181 | + <div class="col-md-12 clearfix"> | ||
182 | + | ||
183 | + <div class="box"> | ||
184 | + | ||
185 | + <div class="table-responsive"> | ||
186 | + | ||
187 | + | ||
188 | + </div> | ||
189 | + <!-- /.table-responsive --> | ||
190 | + | ||
191 | + <div class="box-footer"> | ||
192 | + <div class="pull-right"> | ||
193 | + <?php | ||
194 | + echo Html::a( | ||
195 | + \Yii::t( | ||
196 | + 'app', | ||
197 | + ' Оформить заказ ' | ||
198 | + ) . Html::icon('chevron-right', [ 'prefix' => 'fa fa-' ]), | ||
199 | + [ 'checkout/info' ], | ||
200 | + [ | ||
201 | + 'class' => 'btn btn-success', | ||
202 | + ] | ||
203 | + ) | ||
204 | + ?> | ||
205 | + </div> | ||
206 | + </div> | ||
207 | + </div> | ||
208 | + | ||
209 | + </div> | ||
210 | + </div> | ||
211 | + <?php | ||
212 | + } else { | ||
213 | + echo Html::tag('p', \Yii::t('app', 'Ваша корзина пуста!')); | ||
214 | + } | ||
215 | + ?> | ||
216 | + </div> | ||
217 | + </div> | ||
218 | +</div> |
frontend/views/layouts/_category_menu.php
@@ -15,42 +15,46 @@ | @@ -15,42 +15,46 @@ | ||
15 | <ul class="dropdown-menu <?php echo $isHome ? 'sidebar' : 'multi-level'; ?>" role="menu" aria-labelledby="dLabel" <?php echo $isHome ? 'id="home-category-anchor"' : ''; ?>> | 15 | <ul class="dropdown-menu <?php echo $isHome ? 'sidebar' : 'multi-level'; ?>" role="menu" aria-labelledby="dLabel" <?php echo $isHome ? 'id="home-category-anchor"' : ''; ?>> |
16 | <?php | 16 | <?php |
17 | foreach ($categories as $category) { | 17 | foreach ($categories as $category) { |
18 | - ?> | ||
19 | - <li class="dropdown-submenu"> | ||
20 | - <?php | ||
21 | - echo Html::a( | ||
22 | - $category->lang->title, | ||
23 | - [ | ||
24 | - 'category/view', | ||
25 | - 'category' => $category->lang->alias->value, | ||
26 | - ], | ||
27 | - [ | ||
28 | - 'tabindex' => -1, | ||
29 | - ] | ||
30 | - ); | ||
31 | - if (!empty( $category->categories )) { | ||
32 | - ?> | 18 | + if ($category->lang->alias) { |
19 | + ?> | ||
20 | + <li class="dropdown-submenu"> | ||
21 | + <?php | ||
22 | + echo Html::a( | ||
23 | + $category->lang->title, | ||
24 | + [ | ||
25 | + 'category/view', | ||
26 | + 'category' => $category->lang->alias->value, | ||
27 | + ], | ||
28 | + [ | ||
29 | + 'tabindex' => -1, | ||
30 | + ] | ||
31 | + ); | ||
32 | + if (!empty($category->categories)) { | ||
33 | + ?> | ||
33 | <ul class="dropdown-menu"> | 34 | <ul class="dropdown-menu"> |
34 | <?php | 35 | <?php |
35 | foreach ($category->categories as $childCategory) { | 36 | foreach ($category->categories as $childCategory) { |
36 | - echo Html::tag( | ||
37 | - 'li', | ||
38 | - Html::a( | ||
39 | - $childCategory->lang->title, | ||
40 | - [ | ||
41 | - 'category/view', | ||
42 | - 'category' => $childCategory->lang->alias->value, | ||
43 | - ] | ||
44 | - ) | ||
45 | - ); | 37 | + if ($childCategory->lang->alias) { |
38 | + echo Html::tag( | ||
39 | + 'li', | ||
40 | + Html::a( | ||
41 | + $childCategory->lang->title, | ||
42 | + [ | ||
43 | + 'category/view', | ||
44 | + 'category' => $childCategory->lang->alias->value, | ||
45 | + ] | ||
46 | + ) | ||
47 | + ); | ||
48 | + } | ||
46 | } | 49 | } |
47 | ?> | 50 | ?> |
48 | </ul> | 51 | </ul> |
49 | - <?php | ||
50 | - } | ||
51 | - ?> | ||
52 | - </li> | ||
53 | - <?php | 52 | + <?php |
53 | + } | ||
54 | + ?> | ||
55 | + </li> | ||
56 | + <?php | ||
57 | + } | ||
54 | } | 58 | } |
55 | ?> | 59 | ?> |
56 | </ul> | 60 | </ul> |
frontend/views/layouts/main.php
@@ -6,7 +6,6 @@ | @@ -6,7 +6,6 @@ | ||
6 | * @var User $user | 6 | * @var User $user |
7 | */ | 7 | */ |
8 | use artbox\core\components\SeoComponent; | 8 | use artbox\core\components\SeoComponent; |
9 | - use artbox\core\helpers\ImageHelper; | ||
10 | use artbox\core\models\Feedback; | 9 | use artbox\core\models\Feedback; |
11 | use artbox\core\models\Image; | 10 | use artbox\core\models\Image; |
12 | use artbox\core\models\Page; | 11 | use artbox\core\models\Page; |
@@ -181,7 +180,7 @@ _________________________________________________________ --> | @@ -181,7 +180,7 @@ _________________________________________________________ --> | ||
181 | <?php | 180 | <?php |
182 | echo Html::a( | 181 | echo Html::a( |
183 | Html::img( | 182 | Html::img( |
184 | - $logo, | 183 | + $logo ? : '/img/no-image.png', |
185 | [ | 184 | [ |
186 | 'alt' => 'logo', | 185 | 'alt' => 'logo', |
187 | ] | 186 | ] |
@@ -257,29 +256,29 @@ _________________________________________________________ --> | @@ -257,29 +256,29 @@ _________________________________________________________ --> | ||
257 | </ul> | 256 | </ul> |
258 | </div> | 257 | </div> |
259 | <!--/.nav-collapse --> | 258 | <!--/.nav-collapse --> |
260 | - | ||
261 | - <div class="cart-item" id="cart"> | ||
262 | - <span class="badge">0</span> | ||
263 | - <?php | ||
264 | - echo Html::a( | ||
265 | - Html::tag( | ||
266 | - 'span', | ||
267 | - \Yii::t('app', 'Корзина'), | ||
268 | - [ | ||
269 | - 'class' => 'sub-title', | ||
270 | - ] | ||
271 | - ), | ||
272 | - [ | ||
273 | - '#', | ||
274 | - ], | ||
275 | - [ | ||
276 | - 'class' => 'cart-item-link', | ||
277 | - 'data-toggle' => 'modal', | ||
278 | - 'data-target' => '#basket-modal', | ||
279 | - ] | ||
280 | - ); | ||
281 | - ?> | ||
282 | - </div> | 259 | + |
260 | + <div class="cart-item" id="cart"> | ||
261 | + <span class="badge">0</span> | ||
262 | + <?php | ||
263 | + echo Html::a( | ||
264 | + Html::tag( | ||
265 | + 'span', | ||
266 | + \Yii::t('app', 'Корзина'), | ||
267 | + [ | ||
268 | + 'class' => 'sub-title', | ||
269 | + ] | ||
270 | + ), | ||
271 | + [ | ||
272 | + '#', | ||
273 | + ], | ||
274 | + [ | ||
275 | + 'class' => 'cart-item-link', | ||
276 | + 'data-toggle' => 'modal', | ||
277 | + 'data-target' => '#basket-modal', | ||
278 | + ] | ||
279 | + ); | ||
280 | + ?> | ||
281 | + </div> | ||
283 | 282 | ||
284 | <div class="search-block" id="search"> | 283 | <div class="search-block" id="search"> |
285 | <?php | 284 | <?php |
@@ -394,17 +393,17 @@ _________________________________________________________ --> | @@ -394,17 +393,17 @@ _________________________________________________________ --> | ||
394 | echo $login->field($loginForm, 'rememberMe') | 393 | echo $login->field($loginForm, 'rememberMe') |
395 | ->checkbox(); | 394 | ->checkbox(); |
396 | ?> | 395 | ?> |
397 | - <div class="text-center"> | ||
398 | - <?php | ||
399 | - echo Html::submitButton( | ||
400 | - \Yii::t('app', 'Login'), | ||
401 | - [ | ||
402 | - 'class' => 'btn btn-success', | ||
403 | - ] | ||
404 | - ); | ||
405 | - $login::end(); | ||
406 | - ?> | ||
407 | - </div> | 396 | + <div class="text-center"> |
397 | + <?php | ||
398 | + echo Html::submitButton( | ||
399 | + \Yii::t('app', 'Login'), | ||
400 | + [ | ||
401 | + 'class' => 'btn btn-success', | ||
402 | + ] | ||
403 | + ); | ||
404 | + $login::end(); | ||
405 | + ?> | ||
406 | + </div> | ||
408 | <p class="text-center text-muted"> | 407 | <p class="text-center text-muted"> |
409 | <?php echo \Yii::t('app', 'Not registered yet?'); ?></p> | 408 | <?php echo \Yii::t('app', 'Not registered yet?'); ?></p> |
410 | <p class="text-center text-muted"> | 409 | <p class="text-center text-muted"> |
@@ -521,225 +520,15 @@ _________________________________________________________ --> | @@ -521,225 +520,15 @@ _________________________________________________________ --> | ||
521 | </div> | 520 | </div> |
522 | </div> | 521 | </div> |
523 | <!-- *** FEEDBACK MODAL END *** --> | 522 | <!-- *** FEEDBACK MODAL END *** --> |
524 | - | ||
525 | - <!-- *** MODAL BASKET START *** --> | ||
526 | - | ||
527 | - <div class="modal fade" id="basket-modal" tabindex="-1" role="dialog" aria-labelledby="Login" aria-hidden="true"> | ||
528 | - <div class="modal-dialog modal-lg"> | ||
529 | - | ||
530 | - <div class="modal-content"> | ||
531 | - <div class="modal-header"> | ||
532 | - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | ||
533 | - <h4 class="modal-title callback text-center" id="Login"> | ||
534 | - <?php | ||
535 | - echo Html::a( | ||
536 | - Html::tag( | ||
537 | - 'span', | ||
538 | - \Yii::t('app', 'Ваша корзина') | ||
539 | - ), | ||
540 | - [ | ||
541 | - '/checkout/index', | ||
542 | - ] | ||
543 | - ); | ||
544 | - ?> | ||
545 | - </h4> | ||
546 | - </div> | ||
547 | - <div class="modal-body"> | ||
548 | - <?php | ||
549 | - /** | ||
550 | - * @var \artbox\order\models\Basket $basket | ||
551 | - */ | ||
552 | - $basket = \Yii::$app->get('basket'); | ||
553 | - $data = $basket->getData(); | ||
554 | - $variants = []; | ||
555 | - if (!empty($data)) { | ||
556 | - $variants = $basket->findModels(array_keys($data)); | ||
557 | - } | ||
558 | - $formatter = \Yii::$app->formatter; | ||
559 | - $sum = 0; | ||
560 | - $sumDiscount = 0; | ||
561 | - foreach ($basket->findModels(array_keys($basket->getData())) as $variant) { | ||
562 | - $count = $basket->getItem($variant->id)[ 'count' ]; | ||
563 | - $sum += $variant->price * $count; | ||
564 | - if (!empty($variant->price_old)) { | ||
565 | - $sumDiscount += ( $variant->price_old - $variant->price ) * $count; | ||
566 | - } | ||
567 | - } | ||
568 | - | ||
569 | - if (!empty($variants)) { | ||
570 | - ?> | ||
571 | - <div class="clearfix"> | ||
572 | - <div class="col-md-12 clearfix"> | ||
573 | - <table class="table"> | ||
574 | - <thead> | ||
575 | - <tr> | ||
576 | - <th colspan="2"><?php echo \Yii::t('app', 'Продукт'); ?></th> | ||
577 | - <th><?php echo \Yii::t('app', 'Количество'); ?></th> | ||
578 | - <th><?php echo \Yii::t('app', 'Цена за единицу'); ?></th> | ||
579 | - <th><?php echo \Yii::t('app', 'Скидка'); ?></th> | ||
580 | - <th colspan="2"><?php echo \Yii::t('app', 'Всего'); ?></th> | ||
581 | - </tr> | ||
582 | - </thead> | ||
583 | - <tbody> | ||
584 | - <?php | ||
585 | - foreach ($variants as $variant) { | ||
586 | - $count = $basket->getItem($variant->id)[ 'count' ]; | ||
587 | - ?> | ||
588 | - <tr data-id="<?php echo $variant->id; ?>" class="product-row-basket"> | ||
589 | - <td> | ||
590 | - <?php | ||
591 | - echo Html::a( | ||
592 | - ImageHelper::set($variant->product->image->getPath()) | ||
593 | - ->fillResize(50, 50) | ||
594 | - ->renderImage( | ||
595 | - [ | ||
596 | - 'alt' => $variant->product->lang->title, | ||
597 | - 'title' => $variant->product->lang->title, | ||
598 | - ] | ||
599 | - ), | ||
600 | - [ | ||
601 | - '/product/view', | ||
602 | - 'id' => $variant->product->id, | ||
603 | - ], | ||
604 | - [ | ||
605 | - 'target' => '_blank', | ||
606 | - ] | ||
607 | - ); | ||
608 | - ?> | ||
609 | - </td> | ||
610 | - <td> | ||
611 | - <?php | ||
612 | - echo Html::a( | ||
613 | - $variant->product->lang->title, | ||
614 | - [ | ||
615 | - '/product/view', | ||
616 | - 'id' => $variant->product->id, | ||
617 | - ], | ||
618 | - [ | ||
619 | - 'target' => '_blank', | ||
620 | - ] | ||
621 | - ); | ||
622 | - ?> | ||
623 | - </td> | ||
624 | - <td> | ||
625 | - <?php | ||
626 | - echo Html::input( | ||
627 | - 'number', | ||
628 | - '', | ||
629 | - $count, | ||
630 | - [ | ||
631 | - 'class' => 'form-control increase-product-basket', | ||
632 | - ] | ||
633 | - ); | ||
634 | - ?> | ||
635 | - </td> | ||
636 | - <td> | ||
637 | - <?php | ||
638 | - echo $formatter->asDecimal($variant->price ? : 0, 2); | ||
639 | - ?> | ||
640 | - </td> | ||
641 | - <td> | ||
642 | - <?php | ||
643 | - if (!empty($variant->price_old)) { | ||
644 | - echo $formatter->asDecimal($variant->price_old - $variant->price, 2); | ||
645 | - } else { | ||
646 | - echo $formatter->asDecimal(0, 2); | ||
647 | - } | ||
648 | - ?> | ||
649 | - </td> | ||
650 | - <td> | ||
651 | - <?php | ||
652 | - echo $formatter->asDecimal( | ||
653 | - ( $variant->price ? : 0 ) * $count, | ||
654 | - 2 | ||
655 | - ); | ||
656 | - ?> | ||
657 | - </td> | ||
658 | - <td><a href="#" class="remove-product-cart"><i class="fa fa-trash-o"></i></a> | ||
659 | - </td> | ||
660 | - </tr> | ||
661 | - <?php | ||
662 | - } | ||
663 | - ?> | ||
664 | - </tbody> | ||
665 | - <tfoot> | ||
666 | - <tr> | ||
667 | - <th colspan="5"><?php echo \Yii::t('app', 'Всего'); ?></th> | ||
668 | - <th colspan="2"><?php echo $formatter->asDecimal($sum, 2); ?></th> | ||
669 | - </tr> | ||
670 | - </tfoot> | ||
671 | - </table> | ||
672 | - </div> | ||
673 | - <div class="col-md-12 clearfix"> | ||
674 | - <div class="box" id="order-summary"> | ||
675 | - <div class="box-header"> | ||
676 | - <h3>Итоговый счет</h3> | ||
677 | - </div> | ||
678 | - <p class="text-muted small"><?php echo \Yii::t( | ||
679 | - 'app', | ||
680 | - 'Стоимость доставки рассчитывается в зависимости от адреса и способа доставки' | ||
681 | - ); ?></p> | ||
682 | - | ||
683 | - <div class="table-responsive"> | ||
684 | - <table class="table"> | ||
685 | - <tbody> | ||
686 | - <tr> | ||
687 | - <td><?php echo \Yii::t('app', 'Всего за товары'); ?></td> | ||
688 | - <th><?php echo $formatter->asDecimal($sum, 2); ?></th> | ||
689 | - </tr> | ||
690 | - <tr> | ||
691 | - <td><?php echo \Yii::t('app', 'Сумма скидки'); ?></td> | ||
692 | - <th><?php echo $formatter->asDecimal($sumDiscount, 2); ?></th> | ||
693 | - </tr> | ||
694 | - <tr class="total"> | ||
695 | - <td><?php echo \Yii::t('app', 'Итого к оплате'); ?></td> | ||
696 | - <th><?php echo $formatter->asDecimal($sum, 2); ?></th> | ||
697 | - </tr> | ||
698 | - </tbody> | ||
699 | - </table> | ||
700 | - </div> | ||
701 | - </div> | ||
702 | - </div> | ||
703 | - <div class="col-md-12 clearfix"> | ||
704 | - | ||
705 | - <div class="box"> | ||
706 | - | ||
707 | - <div class="table-responsive"> | ||
708 | - | ||
709 | - | ||
710 | - </div> | ||
711 | - <!-- /.table-responsive --> | ||
712 | - | ||
713 | - <div class="box-footer"> | ||
714 | - <div class="pull-right"> | ||
715 | - <?php | ||
716 | - echo Html::a( | ||
717 | - \Yii::t( | ||
718 | - 'app', | ||
719 | - ' Оформить заказ ' | ||
720 | - ) . Html::icon('chevron-right', [ 'prefix' => 'fa fa-' ]), | ||
721 | - [ 'checkout/info' ], | ||
722 | - [ | ||
723 | - 'class' => 'btn btn-success', | ||
724 | - ] | ||
725 | - ) | ||
726 | - ?> | ||
727 | - </div> | ||
728 | - </div> | ||
729 | - </div> | ||
730 | - | ||
731 | - </div> | ||
732 | - </div> | ||
733 | - <?php | ||
734 | - } else { | ||
735 | - echo Html::tag('p', \Yii::t('app', 'Ваша корзина пуста!')); | ||
736 | - } | ||
737 | - ?> | ||
738 | - </div> | ||
739 | - </div> | ||
740 | - </div> | ||
741 | - </div> | ||
742 | - <!-- *** MODAL BASKET END *** --> | 523 | + |
524 | + <!-- *** MODAL BASKET START *** --> | ||
525 | + | ||
526 | + <div class="modal fade" id="basket-modal" tabindex="-1" role="dialog" aria-hidden="true"> | ||
527 | + <?php | ||
528 | + echo $this->render('_basket_modal'); | ||
529 | + ?> | ||
530 | + </div> | ||
531 | + <!-- *** MODAL BASKET END *** --> | ||
743 | <?php | 532 | <?php |
744 | if (!$isHome) { | 533 | if (!$isHome) { |
745 | ?> | 534 | ?> |
@@ -770,7 +559,7 @@ _________________________________________________________ --> | @@ -770,7 +559,7 @@ _________________________________________________________ --> | ||
770 | <div class="container"> | 559 | <div class="container"> |
771 | <div class="col-md-3 col-sm-6"> | 560 | <div class="col-md-3 col-sm-6"> |
772 | <h4>О нас</h4> | 561 | <h4>О нас</h4> |
773 | - | 562 | + |
774 | <p><?= $settings->about ?></p> | 563 | <p><?= $settings->about ?></p> |
775 | 564 | ||
776 | <hr class="hidden-md hidden-lg hidden-sm"> | 565 | <hr class="hidden-md hidden-lg hidden-sm"> |
@@ -844,9 +633,16 @@ _________________________________________________________ --> | @@ -844,9 +633,16 @@ _________________________________________________________ --> | ||
844 | <br> | 633 | <br> |
845 | <strong><?= $settings->country ?></strong> | 634 | <strong><?= $settings->country ?></strong> |
846 | </p> | 635 | </p> |
847 | - | ||
848 | - <a href="contact.html" class="btn btn-small btn-template-main">Написать нам</a> | ||
849 | - | 636 | + <?php |
637 | + echo Html::a( | ||
638 | + \Yii::t('app', 'Написать нам'), | ||
639 | + [ 'site/contact' ], | ||
640 | + [ | ||
641 | + 'class' => 'btn btn-small btn-template-main', | ||
642 | + ] | ||
643 | + ); | ||
644 | + ?> | ||
645 | + | ||
850 | <hr class="hidden-md hidden-lg hidden-sm"> | 646 | <hr class="hidden-md hidden-lg hidden-sm"> |
851 | 647 | ||
852 | </div> | 648 | </div> |
frontend/views/site/_slider_product.php
@@ -31,39 +31,37 @@ | @@ -31,39 +31,37 @@ | ||
31 | ); | 31 | ); |
32 | ?> | 32 | ?> |
33 | </div> | 33 | </div> |
34 | - | ||
35 | - <div class="vcovers"> | ||
36 | - <div class="content"> | 34 | + |
35 | + <div class="vcovers"> | ||
36 | + <div class="content"> | ||
37 | <?php | 37 | <?php |
38 | - $qwe = 0; | ||
39 | - while($qwe < 7){?> | ||
40 | - | ||
41 | - <div class="vcover"> | ||
42 | - <?php | ||
43 | - echo Html::a( | ||
44 | - Html::img( | ||
45 | - ImageHelper::set( | ||
46 | - $product->image ? $product->image->getPath() : '@frontend/web/img/no-image.png' | ||
47 | - ) | ||
48 | - ->fillResize(40, 40) | ||
49 | - ->render(), | ||
50 | - [ | ||
51 | - 'class' => 'img-responsive-image1', | ||
52 | - ] | ||
53 | - ), | ||
54 | - [ | ||
55 | - 'product/view', | ||
56 | - 'id' => $product->id, | ||
57 | - ] | ||
58 | - ); | 38 | + foreach ($product->variants as $variant) { |
59 | ?> | 39 | ?> |
60 | - </div> | ||
61 | - <?php | ||
62 | - $qwe++; | ||
63 | - } | 40 | + <div class="vcover"> |
41 | + <?php | ||
42 | + echo Html::a( | ||
43 | + Html::img( | ||
44 | + ImageHelper::set( | ||
45 | + $variant->image ? $variant->image->getPath() : '@frontend/web/img/no-image.png' | ||
46 | + ) | ||
47 | + ->fillResize(40, 40) | ||
48 | + ->render(), | ||
49 | + [ | ||
50 | + 'class' => 'img-responsive-image1', | ||
51 | + ] | ||
52 | + ), | ||
53 | + [ | ||
54 | + 'variant/view', | ||
55 | + 'id' => $variant->id, | ||
56 | + ] | ||
57 | + ); | ||
58 | + ?> | ||
59 | + </div> | ||
60 | + <?php | ||
61 | + } | ||
64 | ?> | 62 | ?> |
65 | - </div> | ||
66 | </div> | 63 | </div> |
64 | + </div> | ||
67 | <!-- /.image --> | 65 | <!-- /.image --> |
68 | <div class="text"> | 66 | <div class="text"> |
69 | <h3> | 67 | <h3> |
@@ -134,10 +132,10 @@ | @@ -134,10 +132,10 @@ | ||
134 | } | 132 | } |
135 | if ($product->is('top')) { | 133 | if ($product->is('top')) { |
136 | ?> | 134 | ?> |
137 | - <div class="ribbon top"> | ||
138 | - <div class="theribbon"><?php echo \Yii::t('app', 'Топ'); ?></div> | ||
139 | - <div class="ribbon-background"></div> | ||
140 | - </div> | 135 | + <div class="ribbon top"> |
136 | + <div class="theribbon"><?php echo \Yii::t('app', 'Топ'); ?></div> | ||
137 | + <div class="ribbon-background"></div> | ||
138 | + </div> | ||
141 | <?php | 139 | <?php |
142 | } | 140 | } |
143 | ?> | 141 | ?> |
frontend/views/site/index.php
@@ -229,14 +229,16 @@ _________________________________________________________ --> | @@ -229,14 +229,16 @@ _________________________________________________________ --> | ||
229 | <div class="heading text-center"> | 229 | <div class="heading text-center"> |
230 | <h2><?php echo \Yii::t('app', 'Бренды'); ?></h2> | 230 | <h2><?php echo \Yii::t('app', 'Бренды'); ?></h2> |
231 | </div> | 231 | </div> |
232 | - | ||
233 | - <ul class="owl-carousel customers"> | 232 | + |
233 | + <ul class="owl-carousel customers brand-carousel"> | ||
234 | <?php | 234 | <?php |
235 | foreach ($brands as $brand) { | 235 | foreach ($brands as $brand) { |
236 | echo Html::tag( | 236 | echo Html::tag( |
237 | 'div', | 237 | 'div', |
238 | Html::img( | 238 | Html::img( |
239 | - $brand->image->getUrl(), | 239 | + ImageHelper::set($brand->image->getPath()) |
240 | + ->setWidth(150) | ||
241 | + ->render(), | ||
240 | [ | 242 | [ |
241 | 'class' => 'img-responsive', | 243 | 'class' => 'img-responsive', |
242 | ] | 244 | ] |
@@ -264,8 +266,9 @@ _________________________________________________________ --> | @@ -264,8 +266,9 @@ _________________________________________________________ --> | ||
264 | <div class="heading text-center"> | 266 | <div class="heading text-center"> |
265 | <h2>Полезные статьи</h2> | 267 | <h2>Полезные статьи</h2> |
266 | </div> | 268 | </div> |
267 | - | ||
268 | - <p class="lead">Идейные соображения высшего порядка, а также постоянное информационно-пропагандистское обеспечение нашей деятельности требуют от нас анализа позиций, занимаемых участниками в отношении поставленных задач. Не следует, однако забывать, что консультация с широким активом влечет за собой процесс внедрения и модернизации позиций, занимаемых участниками в отношении поставленных задач. <span class="accent">Почитайте наш блог!</span> | 269 | + |
270 | + <p class="lead">Идейные соображения высшего порядка, а также постоянное информационно-пропагандистское обеспечение нашей деятельности требуют от нас анализа позиций, занимаемых участниками в отношении поставленных задач. Не следует, однако забывать, что консультация с широким активом влечет за собой процесс внедрения и модернизации позиций, занимаемых участниками в отношении поставленных задач. | ||
271 | + <span class="accent">Почитайте наш блог!</span> | ||
269 | </p> | 272 | </p> |
270 | 273 | ||
271 | <!-- *** BLOG HOMEPAGE *** | 274 | <!-- *** BLOG HOMEPAGE *** |
@@ -297,7 +300,10 @@ _________________________________________________________ --> | @@ -297,7 +300,10 @@ _________________________________________________________ --> | ||
297 | 'blog/article', | 300 | 'blog/article', |
298 | 'id' => $article->id, | 301 | 'id' => $article->id, |
299 | ] | 302 | ] |
300 | - ) ?>" class="btn btn-template-transparent-primary"><i class="fa fa-link"></i> <?php echo \Yii::t('app', 'Read more'); ?></a> | 303 | + ) ?>" class="btn btn-template-transparent-primary"><i class="fa fa-link"></i> <?php echo \Yii::t( |
304 | + 'app', | ||
305 | + 'Read more' | ||
306 | + ); ?></a> | ||
301 | </p> | 307 | </p> |
302 | </div> | 308 | </div> |
303 | </div> | 309 | </div> |
1 | +<?php | ||
2 | + use artbox\catalog\models\OptionGroup; | ||
3 | + use artbox\catalog\models\Product; | ||
4 | + use artbox\catalog\models\Variant; | ||
5 | + use artbox\core\components\SeoComponent; | ||
6 | + use artbox\core\helpers\ImageHelper; | ||
7 | + use frontend\models\Order; | ||
8 | + use frontend\widgets\OptionPicker; | ||
9 | + use yii\bootstrap\ActiveForm; | ||
10 | + use yii\bootstrap\Html; | ||
11 | + use yii\helpers\ArrayHelper; | ||
12 | + use yii\helpers\Url; | ||
13 | + use yii\web\View; | ||
14 | + | ||
15 | + /** | ||
16 | + * @var View $this | ||
17 | + * @var Variant $model | ||
18 | + * @var SeoComponent $seo | ||
19 | + * @var array $groups | ||
20 | + * @var Product[] $similar | ||
21 | + */ | ||
22 | + $seo = \Yii::$app->get('seo'); | ||
23 | + if (!empty($model->product->category)) { | ||
24 | + if (!empty($model->product->category->parent)) { | ||
25 | + $this->params[ 'breadcrumbs' ][] = [ | ||
26 | + 'label' => $model->product->category->parent->lang->title, | ||
27 | + 'url' => [ | ||
28 | + '/category/view', | ||
29 | + 'category' => $model->product->category->parent->lang->alias->value, | ||
30 | + ], | ||
31 | + ]; | ||
32 | + } | ||
33 | + $this->params[ 'breadcrumbs' ][] = [ | ||
34 | + 'label' => $model->product->category->lang->title, | ||
35 | + 'url' => [ | ||
36 | + '/category/view', | ||
37 | + 'category' => $model->product->category->lang->alias->value, | ||
38 | + ], | ||
39 | + ]; | ||
40 | + } | ||
41 | + $this->params[ 'breadcrumbs' ][] = $model->product->lang->title; | ||
42 | + $this->params[ 'breadcrumbs' ][] = $seo->title; | ||
43 | + $images = $model->product->images; | ||
44 | + if (!empty($model->product->image)) { | ||
45 | + array_unshift($images, $model->product->image); | ||
46 | + } | ||
47 | + if (!empty($model->image)) { | ||
48 | + array_unshift($images, $model->image); | ||
49 | + } | ||
50 | +?> | ||
51 | +<div id="content"> | ||
52 | + <div class="container"> | ||
53 | + <div class="row"> | ||
54 | + <div class="col-md-12"> | ||
55 | + | ||
56 | + <div class="row" id="productMain"> | ||
57 | + <div class="col-sm-6"> | ||
58 | + <div id="mainImage"> | ||
59 | + <?php | ||
60 | + if (!empty($images)) { | ||
61 | + echo ImageHelper::set($images[ 0 ]->getPath()) | ||
62 | + ->fillResize(555, 555) | ||
63 | + ->renderImage( | ||
64 | + [ | ||
65 | + 'class' => 'img-responsive', | ||
66 | + 'alt' => $model->lang->title, | ||
67 | + 'title' => $model->lang->title, | ||
68 | + ] | ||
69 | + ); | ||
70 | + } else { | ||
71 | + echo ImageHelper::set('@frontend/web/img/no-image.png') | ||
72 | + ->fillResize(555, 555) | ||
73 | + ->renderImage( | ||
74 | + [ | ||
75 | + 'class' => 'img-responsive', | ||
76 | + 'alt' => $model->lang->title, | ||
77 | + 'title' => $model->lang->title, | ||
78 | + ] | ||
79 | + ); | ||
80 | + } | ||
81 | + ?> | ||
82 | + </div> | ||
83 | + | ||
84 | + <?php | ||
85 | + if ($model->product->is('akcia')) { | ||
86 | + ?> | ||
87 | + <div class="ribbon sale"> | ||
88 | + <div class="theribbon">АКЦИЯ</div> | ||
89 | + <div class="ribbon-background"></div> | ||
90 | + </div> | ||
91 | + <!-- /.ribbon --> | ||
92 | + <?php | ||
93 | + } | ||
94 | + if ($model->product->is('new')) { | ||
95 | + ?> | ||
96 | + <div class="ribbon new"> | ||
97 | + <div class="theribbon">НОВОЕ</div> | ||
98 | + <div class="ribbon-background"></div> | ||
99 | + </div> | ||
100 | + <!-- /.ribbon --> | ||
101 | + <?php | ||
102 | + } | ||
103 | + if ($model->product->is('top')) { | ||
104 | + ?> | ||
105 | + <div class="ribbon top"> | ||
106 | + <div class="theribbon">ТОП</div> | ||
107 | + <div class="ribbon-background"></div> | ||
108 | + </div> | ||
109 | + <!-- /.ribbon --> | ||
110 | + <?php | ||
111 | + } | ||
112 | + ?> | ||
113 | + | ||
114 | + <div class="row" id="thumbs"> | ||
115 | + <?php | ||
116 | + if (!empty($images)) { | ||
117 | + foreach ($images as $image) { | ||
118 | + echo Html::tag( | ||
119 | + 'div', | ||
120 | + Html::a( | ||
121 | + ImageHelper::set($image->getPath()) | ||
122 | + ->fillResize(70, 60) | ||
123 | + ->renderImage( | ||
124 | + [ | ||
125 | + 'class' => 'img-responsive', | ||
126 | + 'alt' => $model->lang->title, | ||
127 | + 'title' => $model->lang->title, | ||
128 | + ] | ||
129 | + ), | ||
130 | + ImageHelper::set($image->getPath()) | ||
131 | + ->fillResize(555, 555) | ||
132 | + ->render(), | ||
133 | + [ | ||
134 | + 'class' => 'thumb', | ||
135 | + ] | ||
136 | + ), | ||
137 | + [ | ||
138 | + 'class' => 'col-xs-2', | ||
139 | + ] | ||
140 | + ); | ||
141 | + } | ||
142 | + } else { | ||
143 | + echo Html::tag( | ||
144 | + 'div', | ||
145 | + Html::a( | ||
146 | + ImageHelper::set('@frontend/web/img/no-image.png') | ||
147 | + ->fillResize(70, 60) | ||
148 | + ->renderImage( | ||
149 | + [ | ||
150 | + 'class' => 'img-responsive', | ||
151 | + 'alt' => $model->lang->title, | ||
152 | + 'title' => $model->lang->title, | ||
153 | + ] | ||
154 | + ), | ||
155 | + ImageHelper::set('@frontend/web/img/no-image.png') | ||
156 | + ->fillResize(555, 555) | ||
157 | + ->render(), | ||
158 | + [ | ||
159 | + 'class' => 'thumb', | ||
160 | + ] | ||
161 | + ), | ||
162 | + [ | ||
163 | + 'class' => 'col-xs-2', | ||
164 | + ] | ||
165 | + ); | ||
166 | + } | ||
167 | + ?> | ||
168 | + </div> | ||
169 | + <?php | ||
170 | + if (!empty($model->product->video)) { | ||
171 | + ?> | ||
172 | + <div class="product-video"> | ||
173 | + <div class="h3"> | ||
174 | + <?php echo \Yii::t('app', 'Видеообзор продукта'); ?> | ||
175 | + </div> | ||
176 | + <div class="video-box"> | ||
177 | + <?php echo $model->product->video; ?> | ||
178 | + </div> | ||
179 | + </div> | ||
180 | + <?php | ||
181 | + } | ||
182 | + ?> | ||
183 | + </div> | ||
184 | + <div class="col-sm-6"> | ||
185 | + <div class="box"> | ||
186 | + <h1><?php echo $model->lang->title; ?></h1> | ||
187 | + <p class="no-margin"><?php echo $model->sku; ?></p> | ||
188 | + <p class="price"> | ||
189 | + <span class="price-title">Цена:</span><?php echo $model->price ? : 0; ?> грн  | ||
190 | + <?php | ||
191 | + if ($model->canBuy()) { | ||
192 | + echo Html::a( | ||
193 | + Html::tag( | ||
194 | + 'i', | ||
195 | + '', | ||
196 | + [ | ||
197 | + 'class' => 'fa fa-shopping-cart', | ||
198 | + ] | ||
199 | + ) . \Yii::t('app', 'Добавить в корзину'), | ||
200 | + '#', | ||
201 | + [ | ||
202 | + 'class' => 'btn btn-success add-to-basket', | ||
203 | + 'data-id' => $model->id, | ||
204 | + ] | ||
205 | + ); | ||
206 | + } else { | ||
207 | + echo Html::a( | ||
208 | + \Yii::t('app', 'Нет в наличии'), | ||
209 | + '#', | ||
210 | + [ | ||
211 | + 'class' => 'btn btn-info disabled', | ||
212 | + 'data-id' => $model->id, | ||
213 | + ] | ||
214 | + ); | ||
215 | + } | ||
216 | + ?> | ||
217 | + <?php | ||
218 | + if (\Yii::$app->user->isGuest) { | ||
219 | + echo Html::button( | ||
220 | + Html::tag('i', '', [ 'class' => 'fa fa-heart-o' ]), | ||
221 | + [ | ||
222 | + 'title' => 'Добавить в избранное', | ||
223 | + 'data' => [ | ||
224 | + 'toggle' => 'tooltip', | ||
225 | + 'placement' => 'top', | ||
226 | + ], | ||
227 | + 'class' => 'btn btn-default pull-right disabled', | ||
228 | + ] | ||
229 | + ); | ||
230 | + } elseif (in_array($model->id, \Yii::$app->user->identity->wishlist)) { | ||
231 | + echo Html::button( | ||
232 | + Html::tag('i', '', [ 'class' => 'fa fa-heart' ]), | ||
233 | + [ | ||
234 | + 'title' => 'Убрать из избранного', | ||
235 | + 'data' => [ | ||
236 | + 'toggle' => 'tooltip', | ||
237 | + 'placement' => 'top', | ||
238 | + 'product' => $model->product->id, | ||
239 | + 'variant' => $model->id, | ||
240 | + 'user' => \Yii::$app->user->identity->getId(), | ||
241 | + 'url' => Url::to([ 'product/wishlist-rm' ]), | ||
242 | + ], | ||
243 | + 'class' => 'wishlist-rm btn btn-success pull-right', | ||
244 | + ] | ||
245 | + ); | ||
246 | + } else { | ||
247 | + echo Html::button( | ||
248 | + Html::tag('i', '', [ 'class' => 'fa fa-heart-o' ]), | ||
249 | + [ | ||
250 | + 'title' => 'Добавить в избранное', | ||
251 | + 'data' => [ | ||
252 | + 'toggle' => 'tooltip', | ||
253 | + 'placement' => 'top', | ||
254 | + 'product' => $model->product->id, | ||
255 | + 'variant' => $model->id, | ||
256 | + 'user' => \Yii::$app->user->identity->getId(), | ||
257 | + 'url' => Url::to([ 'product/wishlist-add' ]), | ||
258 | + ], | ||
259 | + 'class' => 'wishlist-add btn btn-success pull-right', | ||
260 | + ] | ||
261 | + ); | ||
262 | + } | ||
263 | + ?> | ||
264 | + </p> | ||
265 | + <hr> | ||
266 | + <?php | ||
267 | + if ($model->canBuy()) { | ||
268 | + echo Html::a( | ||
269 | + Html::icon( | ||
270 | + 'phone', | ||
271 | + [ | ||
272 | + 'prefix' => 'fa fa-', | ||
273 | + ] | ||
274 | + ) . \Yii::t('app', 'Купить в один клик'), | ||
275 | + '#', | ||
276 | + [ | ||
277 | + 'data' => [ | ||
278 | + 'toggle' => 'modal', | ||
279 | + 'target' => '#oneclick-modal', | ||
280 | + ], | ||
281 | + 'class' => 'btn btn-template-main', | ||
282 | + ] | ||
283 | + ); | ||
284 | + } | ||
285 | + ?> | ||
286 | + </div> | ||
287 | + <div class="product-variant-block"> | ||
288 | + <?php | ||
289 | + $helper = OptionPicker::getHelper($model->product); | ||
290 | + $productVariantGroups = $helper->getGroups(); | ||
291 | + foreach ($productVariantGroups as $productVariantGroup) { | ||
292 | + ?> | ||
293 | + <div class="product-variant-group"> | ||
294 | + <p class="product-variant-group-title"> | ||
295 | + <?php | ||
296 | + /** | ||
297 | + * @var \artbox\catalog\models\VariantOptionGroupExcl $productVariantGroupModel | ||
298 | + */ | ||
299 | + $productVariantGroupModel = $productVariantGroup[ 'group' ]; | ||
300 | + echo $productVariantGroupModel->lang->title . ": "; | ||
301 | + ?> | ||
302 | + </p> | ||
303 | + <div class="product-variant-group-options"> | ||
304 | + <?php | ||
305 | + /** | ||
306 | + * @var \frontend\widgets\VariantOptionHelper $variantOptionHelper | ||
307 | + */ | ||
308 | + $variantOptionHelper = $productVariantGroup[ 'options' ]; | ||
309 | + foreach ($variantOptionHelper->getOptions() as $option) { | ||
310 | + /** | ||
311 | + * @var \artbox\catalog\models\VariantOptionExcl $productVariantOptionModel | ||
312 | + */ | ||
313 | + $productVariantOptionModel = $option[ 'option' ]; | ||
314 | + /** | ||
315 | + * @var \frontend\widgets\VariantHelper $variantHelper | ||
316 | + */ | ||
317 | + $variantHelper = $option[ 'variants' ]; | ||
318 | + $variant = $variantHelper->getVariant(); | ||
319 | + /** | ||
320 | + * @var \artbox\core\models\Image $img | ||
321 | + */ | ||
322 | + $img = $productVariantOptionModel->image ? : $variant->image ? : null; | ||
323 | + echo Html::a( | ||
324 | + Html::tag( | ||
325 | + 'div', | ||
326 | + $img ? ImageHelper::set($img->getPath()) | ||
327 | + ->fillResize(90, 55) | ||
328 | + ->renderImage( | ||
329 | + [ | ||
330 | + 'alt' => $productVariantOptionModel->lang->value, | ||
331 | + 'title' => $productVariantOptionModel->lang->value, | ||
332 | + 'class' => 'product-variant-group-option-img', | ||
333 | + ] | ||
334 | + ) : $productVariantOptionModel->lang->value, | ||
335 | + [ | ||
336 | + 'class' => 'product-variant-group-option', | ||
337 | + ] | ||
338 | + ), | ||
339 | + [ | ||
340 | + 'variant/view', | ||
341 | + 'id' => $variant->id, | ||
342 | + ] | ||
343 | + ); | ||
344 | + } | ||
345 | + ?> | ||
346 | + </div> | ||
347 | + </div> | ||
348 | + <?php | ||
349 | + } | ||
350 | + ?> | ||
351 | + </div> | ||
352 | + <div class="box" id="details"> | ||
353 | + <h2><?php echo \Yii::t('app', 'Описание товара'); ?></h2> | ||
354 | + <?php echo $model->lang->description ? : \Yii::t('app', 'Нет описания'); ?> | ||
355 | + </div> | ||
356 | + | ||
357 | + <div class="box" id="details"> | ||
358 | + <h2><?php echo \Yii::t('app', 'Характеристики'); ?></h2> | ||
359 | + <?php | ||
360 | + if (!empty($groups)) { | ||
361 | + ?> | ||
362 | + <table class="table"> | ||
363 | + <tbody> | ||
364 | + <?php | ||
365 | + foreach ($groups as $group) { | ||
366 | + foreach ($group as $optionGroup) { | ||
367 | + /** | ||
368 | + * @var OptionGroup $optionGroup | ||
369 | + */ | ||
370 | + echo Html::tag( | ||
371 | + 'tr', | ||
372 | + Html::tag( | ||
373 | + 'td', | ||
374 | + $optionGroup->lang->title, | ||
375 | + [ 'class' => 'td-title' ] | ||
376 | + ) . Html::tag( | ||
377 | + 'td', | ||
378 | + implode( | ||
379 | + ', ', | ||
380 | + ArrayHelper::getColumn( | ||
381 | + $optionGroup->currentOptions, | ||
382 | + 'lang.value' | ||
383 | + ) | ||
384 | + ) | ||
385 | + ) | ||
386 | + ); | ||
387 | + } | ||
388 | + } | ||
389 | + ?> | ||
390 | + </tbody> | ||
391 | + </table> | ||
392 | + <?php | ||
393 | + } else { | ||
394 | + echo \Yii::t('app', 'Нет характеристик'); | ||
395 | + } | ||
396 | + ?> | ||
397 | + </div> | ||
398 | + </div> | ||
399 | + | ||
400 | + </div> | ||
401 | + | ||
402 | + <?php | ||
403 | + if (!empty($similar)) { | ||
404 | + ?> | ||
405 | + <div class="heading text-center"> | ||
406 | + <h2><?php echo \Yii::t('app', 'Похожие товары'); ?></h2> | ||
407 | + </div> | ||
408 | + | ||
409 | + <div class="product-carousel"> | ||
410 | + <div class="homepage owl-carousel"> | ||
411 | + <?php | ||
412 | + $newItemsArrays = array_chunk($similar, 4); | ||
413 | + foreach ($newItemsArrays as $newItemsArray) { | ||
414 | + ?> | ||
415 | + <div class="products"> | ||
416 | + <?php | ||
417 | + foreach ($newItemsArray as $product) { | ||
418 | + echo $this->render( | ||
419 | + '@frontend/views/site/_slider_product', | ||
420 | + [ | ||
421 | + 'product' => $product, | ||
422 | + ] | ||
423 | + ); | ||
424 | + } | ||
425 | + ?> | ||
426 | + </div> | ||
427 | + <?php | ||
428 | + } | ||
429 | + ?> | ||
430 | + </div> | ||
431 | + </div> | ||
432 | + <?php | ||
433 | + } | ||
434 | + ?> | ||
435 | + </div> | ||
436 | + <!-- /.col-md-9 --> | ||
437 | + </div> | ||
438 | + <!-- /.row --> | ||
439 | + </div> | ||
440 | + <!-- /.container --> | ||
441 | +</div> | ||
442 | +<!-- /#content --> | ||
443 | +<div class="modal fade" id="oneclick-modal" tabindex="-1" role="dialog"> | ||
444 | + <div class="modal-dialog modal-sm"> | ||
445 | + | ||
446 | + <div class="modal-content"> | ||
447 | + <div class="modal-header"> | ||
448 | + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | ||
449 | + <h4 class="modal-title callback"><?php echo \Yii::t('app', 'Купить в один клик'); ?></h4> | ||
450 | + </div> | ||
451 | + <div class="modal-body"> | ||
452 | + <?php | ||
453 | + $order = new Order( | ||
454 | + [ | ||
455 | + 'scenario' => Order::SCENARIO_FAST, | ||
456 | + 'variantId' => $model->id, | ||
457 | + 'returnUrl' => \Yii::$app->request->absoluteUrl, | ||
458 | + ] | ||
459 | + ); | ||
460 | + $form = ActiveForm::begin( | ||
461 | + [ | ||
462 | + 'action' => [ 'checkout/fast' ], | ||
463 | + 'id' => 'fast-buy-form', | ||
464 | + ] | ||
465 | + ); | ||
466 | + echo $form->field($order, 'variantId') | ||
467 | + ->label(false) | ||
468 | + ->hiddenInput(); | ||
469 | + echo $form->field($order, 'returnUrl') | ||
470 | + ->label(false) | ||
471 | + ->hiddenInput(); | ||
472 | + echo $form->field($order, 'name') | ||
473 | + ->label(false) | ||
474 | + ->textInput( | ||
475 | + [ | ||
476 | + 'placeholder' => $order->getAttributeLabel('name'), | ||
477 | + ] | ||
478 | + ); | ||
479 | + echo $form->field($order, 'phone') | ||
480 | + ->label(false) | ||
481 | + ->textInput( | ||
482 | + [ | ||
483 | + 'placeholder' => $order->getAttributeLabel('phone'), | ||
484 | + ] | ||
485 | + ); | ||
486 | + echo Html::tag( | ||
487 | + 'p', | ||
488 | + Html::submitButton( | ||
489 | + Html::icon( | ||
490 | + 'shopping-cart', | ||
491 | + [ | ||
492 | + 'prefix' => 'fa fa-', | ||
493 | + ] | ||
494 | + ) . \Yii::t('app', ' Отправить'), | ||
495 | + [ | ||
496 | + 'class' => 'btn btn-template-main', | ||
497 | + ] | ||
498 | + ), | ||
499 | + [ | ||
500 | + 'class' => 'text-center', | ||
501 | + ] | ||
502 | + ); | ||
503 | + $form::end(); | ||
504 | + ?> | ||
505 | + </div> | ||
506 | + </div> | ||
507 | + </div> | ||
508 | +</div> |
frontend/web/css/style.css
@@ -4752,4 +4752,21 @@ a i.fa, button i.fa, span.fa { | @@ -4752,4 +4752,21 @@ a i.fa, button i.fa, span.fa { | ||
4752 | 4752 | ||
4753 | .vcovers .vcover img:hover{ | 4753 | .vcovers .vcover img:hover{ |
4754 | border: 1px solid rgb(0, 91, 172); | 4754 | border: 1px solid rgb(0, 91, 172); |
4755 | +} | ||
4756 | + | ||
4757 | +.product-variant-group-option { | ||
4758 | + display: inline-block; | ||
4759 | + margin: 5px; | ||
4760 | + width: 90px; | ||
4761 | + height: 55px; | ||
4762 | +} | ||
4763 | + | ||
4764 | +.product-variant-group-option-img { | ||
4765 | + width: 100%; | ||
4766 | + height: 100%; | ||
4767 | +} | ||
4768 | + | ||
4769 | +.owl-carousel.brand-carousel .owl-item { | ||
4770 | + float: none; | ||
4771 | + display: inline-block; | ||
4755 | } | 4772 | } |
4756 | \ No newline at end of file | 4773 | \ No newline at end of file |
frontend/web/js/script.js
@@ -93,7 +93,14 @@ $(function() { | @@ -93,7 +93,14 @@ $(function() { | ||
93 | e.preventDefault(); | 93 | e.preventDefault(); |
94 | var id = $(this) | 94 | var id = $(this) |
95 | .data('id'); | 95 | .data('id'); |
96 | - basket.add(id, 1); | 96 | + var xhr = basket.add(id, 1); |
97 | + xhr.done(function() { | ||
98 | + $.pjax.reload({ | ||
99 | + container: '#basket-modal', | ||
100 | + fragment: '#basket-modal', | ||
101 | + timeout: 5000 | ||
102 | + }); | ||
103 | + }); | ||
97 | if ($('.alert-cart').length > 0) { | 104 | if ($('.alert-cart').length > 0) { |
98 | } else { | 105 | } else { |
99 | $('body') | 106 | $('body') |
@@ -136,12 +143,20 @@ $(function() { | @@ -136,12 +143,20 @@ $(function() { | ||
136 | .parents('.product-row-basket') | 143 | .parents('.product-row-basket') |
137 | .data('id'); | 144 | .data('id'); |
138 | showLoader('#basket'); | 145 | showLoader('#basket'); |
146 | + showLoader('#basket-modal'); | ||
139 | var xhr = basket.set(id, $(this) | 147 | var xhr = basket.set(id, $(this) |
140 | .val()); | 148 | .val()); |
141 | xhr.done(function() { | 149 | xhr.done(function() { |
150 | + if ($('#basket').length) { | ||
151 | + $.pjax.reload({ | ||
152 | + container: '#basket', | ||
153 | + fragment: '#basket', | ||
154 | + timeout: 5000 | ||
155 | + }); | ||
156 | + } | ||
142 | $.pjax.reload({ | 157 | $.pjax.reload({ |
143 | - container: '#basket', | ||
144 | - fragment: '#basket', | 158 | + container: '#basket-modal', |
159 | + fragment: '#basket-modal', | ||
145 | timeout: 5000 | 160 | timeout: 5000 |
146 | }); | 161 | }); |
147 | }); | 162 | }); |
1 | +<?php | ||
2 | + | ||
3 | + namespace frontend\widgets; | ||
4 | + | ||
5 | + use artbox\catalog\models\Product; | ||
6 | + | ||
7 | + class OptionPicker | ||
8 | + { | ||
9 | + public static function getHelper(Product $product) | ||
10 | + { | ||
11 | + $helper = new VariantGroupHelper(); | ||
12 | + /** | ||
13 | + * @var \artbox\catalog\models\Variant[] $variants | ||
14 | + */ | ||
15 | + $variants = $product->getVariants() | ||
16 | + ->all(); | ||
17 | + foreach ($variants as $variant) { | ||
18 | + $helper->addVariant($variant); | ||
19 | + } | ||
20 | + return $helper; | ||
21 | + } | ||
22 | + } | ||
0 | \ No newline at end of file | 23 | \ No newline at end of file |
1 | +<?php | ||
2 | + | ||
3 | + namespace frontend\widgets; | ||
4 | + | ||
5 | + use artbox\catalog\models\Variant; | ||
6 | + use artbox\catalog\models\VariantOptionExcl; | ||
7 | + use artbox\catalog\models\VariantOptionGroupExcl; | ||
8 | + | ||
9 | + class VariantGroupHelper | ||
10 | + { | ||
11 | + protected $groups = []; | ||
12 | + | ||
13 | + public function addGroup(VariantOptionGroupExcl $group) | ||
14 | + { | ||
15 | + if (!array_key_exists($group->id, $this->groups)) { | ||
16 | + $this->groups[ $group->id ][ 'group' ] = $group; | ||
17 | + $this->groups[ $group->id ][ 'options' ] = new VariantOptionHelper(); | ||
18 | + } | ||
19 | + } | ||
20 | + | ||
21 | + public function addOption(VariantOptionExcl $option) | ||
22 | + { | ||
23 | + if (empty($this->groups[ $option->groupId ])) { | ||
24 | + $this->addGroup($option->variantOptionGroupExcl); | ||
25 | + } | ||
26 | + /** | ||
27 | + * @var \frontend\widgets\VariantOptionHelper $variantOptionHelper | ||
28 | + */ | ||
29 | + $variantOptionHelper = $this->groups[ $option->groupId ][ 'options' ]; | ||
30 | + $variantOptionHelper->addOption($option); | ||
31 | + } | ||
32 | + | ||
33 | + public function addVariant(Variant $variant) | ||
34 | + { | ||
35 | + $options = $variant->variantOptionExcls; | ||
36 | + foreach ($options as $option) { | ||
37 | + $this->addOption($option); | ||
38 | + $variantContainer = $this->getVariantContainer($option); | ||
39 | + $variantContainer->addVariant($variant); | ||
40 | + } | ||
41 | + } | ||
42 | + | ||
43 | + public function getVariantContainer(VariantOptionExcl $option) | ||
44 | + { | ||
45 | + /** | ||
46 | + * @var \frontend\widgets\VariantOptionHelper $variantOptionHelper | ||
47 | + */ | ||
48 | + $variantOptionHelper = $this->groups[ $option->groupId ][ 'options' ]; | ||
49 | + return $variantOptionHelper->getVariantContainer($option); | ||
50 | + } | ||
51 | + | ||
52 | + public function getGroups() | ||
53 | + { | ||
54 | + return $this->groups; | ||
55 | + } | ||
56 | + } | ||
0 | \ No newline at end of file | 57 | \ No newline at end of file |
1 | +<?php | ||
2 | + | ||
3 | + namespace frontend\widgets; | ||
4 | + | ||
5 | + use artbox\catalog\models\Variant; | ||
6 | + | ||
7 | + class VariantHelper | ||
8 | + { | ||
9 | + /** | ||
10 | + * @var Variant[] $variants | ||
11 | + */ | ||
12 | + protected $variants = []; | ||
13 | + | ||
14 | + public function addVariant(Variant $variant) | ||
15 | + { | ||
16 | + if (!array_key_exists($variant->id, $this->variants)) { | ||
17 | + $this->variants[ $variant->id ] = $variant; | ||
18 | + } | ||
19 | + } | ||
20 | + | ||
21 | + public function getVariants() | ||
22 | + { | ||
23 | + return $this->variants; | ||
24 | + } | ||
25 | + | ||
26 | + public function getVariant() | ||
27 | + { | ||
28 | + return $this->variants[ array_keys($this->variants)[ 0 ] ]; | ||
29 | + } | ||
30 | + } | ||
0 | \ No newline at end of file | 31 | \ No newline at end of file |
1 | +<?php | ||
2 | + | ||
3 | + namespace frontend\widgets; | ||
4 | + | ||
5 | + use artbox\catalog\models\VariantOptionExcl; | ||
6 | + | ||
7 | + class VariantOptionHelper | ||
8 | + { | ||
9 | + protected $options = []; | ||
10 | + | ||
11 | + public function addOption(VariantOptionExcl $option) | ||
12 | + { | ||
13 | + if (!array_key_exists($option->id, $this->options)) { | ||
14 | + $this->options[ $option->id ][ 'option' ] = $option; | ||
15 | + $this->options[ $option->id ][ 'variants' ] = new VariantHelper(); | ||
16 | + } | ||
17 | + } | ||
18 | + | ||
19 | + public function getVariantContainer(VariantOptionExcl $option) | ||
20 | + { | ||
21 | + /** | ||
22 | + * @var \frontend\widgets\VariantHelper $variantHelper | ||
23 | + */ | ||
24 | + $variantHelper = $this->options[ $option->id ][ 'variants' ]; | ||
25 | + return $variantHelper; | ||
26 | + } | ||
27 | + | ||
28 | + public function getOptions() | ||
29 | + { | ||
30 | + return $this->options; | ||
31 | + } | ||
32 | + } | ||
0 | \ No newline at end of file | 33 | \ No newline at end of file |