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 | 41 | $query = $filterHelper->buildQuery() |
42 | 42 | ->innerJoinWith('category', false) |
43 | 43 | ->andWhere([ 'product_to_category.category_id' => $model->id ]) |
44 | - ->with('image', 'variants', 'lang'); | |
44 | + ->with('image', 'variants.image', 'lang'); | |
45 | 45 | $dataProvider = new ActiveDataProvider( |
46 | 46 | [ |
47 | 47 | 'query' => $query, |
... | ... | @@ -84,6 +84,9 @@ |
84 | 84 | $alias = Alias::find() |
85 | 85 | ->where([ 'value' => $category ]) |
86 | 86 | ->one(); |
87 | + if (empty($alias)) { | |
88 | + throw new NotFoundHttpException('Category not found'); | |
89 | + } | |
87 | 90 | $id = $filter->getIdFromRoute($alias->route); |
88 | 91 | /** |
89 | 92 | * @var Category $model | ... | ... |
frontend/controllers/ProductController.php
1 | 1 | <?php |
2 | + | |
2 | 3 | namespace frontend\controllers; |
3 | 4 | |
4 | 5 | use artbox\catalog\models\Product; |
... | ... | @@ -9,7 +10,6 @@ |
9 | 10 | use yii\helpers\Url; |
10 | 11 | use yii\web\Controller; |
11 | 12 | use yii\web\NotFoundHttpException; |
12 | - use Yii; | |
13 | 13 | use yii\web\Response; |
14 | 14 | |
15 | 15 | /** |
... | ... | @@ -25,28 +25,43 @@ |
25 | 25 | * @param int $id |
26 | 26 | * |
27 | 27 | * @return string |
28 | + * @throws \yii\web\NotFoundHttpException | |
28 | 29 | */ |
29 | 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 | 124 | ->andWhere( |
110 | 125 | [ |
111 | 126 | 'variant_id' => \Yii::$app->request->post('variant'), |
112 | - | |
127 | + | |
113 | 128 | ] |
114 | 129 | ) |
115 | 130 | ->one(); |
... | ... | @@ -133,7 +148,7 @@ |
133 | 148 | 'message' => \Yii::t('app', 'Товар убран из избранного'), |
134 | 149 | ]; |
135 | 150 | } |
136 | - | |
151 | + | |
137 | 152 | return [ |
138 | 153 | 'button' => Html::button( |
139 | 154 | Html::tag('i', '', [ 'class' => 'fa fa-heart' ]), |
... | ... | @@ -169,7 +184,7 @@ |
169 | 184 | $model->user_id = \Yii::$app->request->post('user'); |
170 | 185 | $model->variant_id = \Yii::$app->request->post('variant'); |
171 | 186 | $model->product_id = \Yii::$app->request->post('product'); |
172 | - | |
187 | + | |
173 | 188 | if ($model->save()) { |
174 | 189 | return [ |
175 | 190 | 'button' => Html::button( |
... | ... | @@ -190,7 +205,7 @@ |
190 | 205 | 'message' => 'Товар добавлен в избранное', |
191 | 206 | ]; |
192 | 207 | } |
193 | - | |
208 | + | |
194 | 209 | return [ |
195 | 210 | 'button' => Html::button( |
196 | 211 | Html::tag('i', '', [ 'class' => 'fa fa-heart-o' ]), | ... | ... |
frontend/controllers/SiteController.php
... | ... | @@ -76,17 +76,17 @@ |
76 | 76 | ->where([ 'level' => 0 ]) |
77 | 77 | ->all(); |
78 | 78 | $topItems = Product::find() |
79 | - ->with('lang', 'image', 'variants') | |
79 | + ->with('lang', 'image', 'variants.image') | |
80 | 80 | ->is('mask', 1) |
81 | 81 | ->limit(20) |
82 | 82 | ->all(); |
83 | 83 | $newItems = Product::find() |
84 | - ->with('lang', 'image', 'variants') | |
84 | + ->with('lang', 'image', 'variants.image') | |
85 | 85 | ->is('mask', 2) |
86 | 86 | ->limit(20) |
87 | 87 | ->all(); |
88 | 88 | $saleItems = Product::find() |
89 | - ->with('lang', 'image', 'variants') | |
89 | + ->with('lang', 'image', 'variants.image') | |
90 | 90 | ->is('mask', 4) |
91 | 91 | ->limit(20) |
92 | 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 | 99 | \ No newline at end of file | ... | ... |
frontend/views/category/_product_item.php
... | ... | @@ -31,6 +31,36 @@ |
31 | 31 | ); |
32 | 32 | ?> |
33 | 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 | 64 | <!-- /.image --> |
35 | 65 | <div class="text"> |
36 | 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 | 15 | <ul class="dropdown-menu <?php echo $isHome ? 'sidebar' : 'multi-level'; ?>" role="menu" aria-labelledby="dLabel" <?php echo $isHome ? 'id="home-category-anchor"' : ''; ?>> |
16 | 16 | <?php |
17 | 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 | 34 | <ul class="dropdown-menu"> |
34 | 35 | <?php |
35 | 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 | 51 | </ul> |
49 | - <?php | |
50 | - } | |
51 | - ?> | |
52 | - </li> | |
53 | - <?php | |
52 | + <?php | |
53 | + } | |
54 | + ?> | |
55 | + </li> | |
56 | + <?php | |
57 | + } | |
54 | 58 | } |
55 | 59 | ?> |
56 | 60 | </ul> | ... | ... |
frontend/views/layouts/main.php
... | ... | @@ -6,7 +6,6 @@ |
6 | 6 | * @var User $user |
7 | 7 | */ |
8 | 8 | use artbox\core\components\SeoComponent; |
9 | - use artbox\core\helpers\ImageHelper; | |
10 | 9 | use artbox\core\models\Feedback; |
11 | 10 | use artbox\core\models\Image; |
12 | 11 | use artbox\core\models\Page; |
... | ... | @@ -181,7 +180,7 @@ _________________________________________________________ --> |
181 | 180 | <?php |
182 | 181 | echo Html::a( |
183 | 182 | Html::img( |
184 | - $logo, | |
183 | + $logo ? : '/img/no-image.png', | |
185 | 184 | [ |
186 | 185 | 'alt' => 'logo', |
187 | 186 | ] |
... | ... | @@ -257,29 +256,29 @@ _________________________________________________________ --> |
257 | 256 | </ul> |
258 | 257 | </div> |
259 | 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 | 283 | <div class="search-block" id="search"> |
285 | 284 | <?php |
... | ... | @@ -394,17 +393,17 @@ _________________________________________________________ --> |
394 | 393 | echo $login->field($loginForm, 'rememberMe') |
395 | 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 | 407 | <p class="text-center text-muted"> |
409 | 408 | <?php echo \Yii::t('app', 'Not registered yet?'); ?></p> |
410 | 409 | <p class="text-center text-muted"> |
... | ... | @@ -521,225 +520,15 @@ _________________________________________________________ --> |
521 | 520 | </div> |
522 | 521 | </div> |
523 | 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 | 532 | <?php |
744 | 533 | if (!$isHome) { |
745 | 534 | ?> |
... | ... | @@ -770,7 +559,7 @@ _________________________________________________________ --> |
770 | 559 | <div class="container"> |
771 | 560 | <div class="col-md-3 col-sm-6"> |
772 | 561 | <h4>О нас</h4> |
773 | - | |
562 | + | |
774 | 563 | <p><?= $settings->about ?></p> |
775 | 564 | |
776 | 565 | <hr class="hidden-md hidden-lg hidden-sm"> |
... | ... | @@ -844,9 +633,16 @@ _________________________________________________________ --> |
844 | 633 | <br> |
845 | 634 | <strong><?= $settings->country ?></strong> |
846 | 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 | 646 | <hr class="hidden-md hidden-lg hidden-sm"> |
851 | 647 | |
852 | 648 | </div> | ... | ... |
frontend/views/site/_slider_product.php
... | ... | @@ -31,39 +31,37 @@ |
31 | 31 | ); |
32 | 32 | ?> |
33 | 33 | </div> |
34 | - | |
35 | - <div class="vcovers"> | |
36 | - <div class="content"> | |
34 | + | |
35 | + <div class="vcovers"> | |
36 | + <div class="content"> | |
37 | 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 | 63 | </div> |
64 | + </div> | |
67 | 65 | <!-- /.image --> |
68 | 66 | <div class="text"> |
69 | 67 | <h3> |
... | ... | @@ -134,10 +132,10 @@ |
134 | 132 | } |
135 | 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 | 139 | <?php |
142 | 140 | } |
143 | 141 | ?> | ... | ... |
frontend/views/site/index.php
... | ... | @@ -229,14 +229,16 @@ _________________________________________________________ --> |
229 | 229 | <div class="heading text-center"> |
230 | 230 | <h2><?php echo \Yii::t('app', 'Бренды'); ?></h2> |
231 | 231 | </div> |
232 | - | |
233 | - <ul class="owl-carousel customers"> | |
232 | + | |
233 | + <ul class="owl-carousel customers brand-carousel"> | |
234 | 234 | <?php |
235 | 235 | foreach ($brands as $brand) { |
236 | 236 | echo Html::tag( |
237 | 237 | 'div', |
238 | 238 | Html::img( |
239 | - $brand->image->getUrl(), | |
239 | + ImageHelper::set($brand->image->getPath()) | |
240 | + ->setWidth(150) | |
241 | + ->render(), | |
240 | 242 | [ |
241 | 243 | 'class' => 'img-responsive', |
242 | 244 | ] |
... | ... | @@ -264,8 +266,9 @@ _________________________________________________________ --> |
264 | 266 | <div class="heading text-center"> |
265 | 267 | <h2>Полезные статьи</h2> |
266 | 268 | </div> |
267 | - | |
268 | - <p class="lead">Идейные соображения высшего порядка, а также постоянное информационно-пропагандистское обеспечение нашей деятельности требуют от нас анализа позиций, занимаемых участниками в отношении поставленных задач. Не следует, однако забывать, что консультация с широким активом влечет за собой процесс внедрения и модернизации позиций, занимаемых участниками в отношении поставленных задач. <span class="accent">Почитайте наш блог!</span> | |
269 | + | |
270 | + <p class="lead">Идейные соображения высшего порядка, а также постоянное информационно-пропагандистское обеспечение нашей деятельности требуют от нас анализа позиций, занимаемых участниками в отношении поставленных задач. Не следует, однако забывать, что консультация с широким активом влечет за собой процесс внедрения и модернизации позиций, занимаемых участниками в отношении поставленных задач. | |
271 | + <span class="accent">Почитайте наш блог!</span> | |
269 | 272 | </p> |
270 | 273 | |
271 | 274 | <!-- *** BLOG HOMEPAGE *** |
... | ... | @@ -297,7 +300,10 @@ _________________________________________________________ --> |
297 | 300 | 'blog/article', |
298 | 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 | 307 | </p> |
302 | 308 | </div> |
303 | 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 | 4752 | |
4753 | 4753 | .vcovers .vcover img:hover{ |
4754 | 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 | 4773 | \ No newline at end of file | ... | ... |
frontend/web/js/script.js
... | ... | @@ -93,7 +93,14 @@ $(function() { |
93 | 93 | e.preventDefault(); |
94 | 94 | var id = $(this) |
95 | 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 | 104 | if ($('.alert-cart').length > 0) { |
98 | 105 | } else { |
99 | 106 | $('body') |
... | ... | @@ -136,12 +143,20 @@ $(function() { |
136 | 143 | .parents('.product-row-basket') |
137 | 144 | .data('id'); |
138 | 145 | showLoader('#basket'); |
146 | + showLoader('#basket-modal'); | |
139 | 147 | var xhr = basket.set(id, $(this) |
140 | 148 | .val()); |
141 | 149 | xhr.done(function() { |
150 | + if ($('#basket').length) { | |
151 | + $.pjax.reload({ | |
152 | + container: '#basket', | |
153 | + fragment: '#basket', | |
154 | + timeout: 5000 | |
155 | + }); | |
156 | + } | |
142 | 157 | $.pjax.reload({ |
143 | - container: '#basket', | |
144 | - fragment: '#basket', | |
158 | + container: '#basket-modal', | |
159 | + fragment: '#basket-modal', | |
145 | 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 | 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 | 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 | 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 | 33 | \ No newline at end of file | ... | ... |