From fc66ded4b7166f769922378dcb08c3e0c701915b Mon Sep 17 00:00:00 2001 From: Yarik Date: Thu, 1 Jun 2017 14:09:41 +0300 Subject: [PATCH] Artbox great prepairings --- frontend/controllers/CategoryController.php | 5 ++++- frontend/controllers/ProductController.php | 57 ++++++++++++++++++++++++++++++++++++--------------------- frontend/controllers/SiteController.php | 6 +++--- frontend/controllers/VariantController.php | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/views/category/_product_item.php | 30 ++++++++++++++++++++++++++++++ frontend/views/layouts/_basket_modal.php | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/views/layouts/_category_menu.php | 64 ++++++++++++++++++++++++++++++++++------------------------------ frontend/views/layouts/main.php | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- frontend/views/site/_slider_product.php | 64 +++++++++++++++++++++++++++++++--------------------------------- frontend/views/site/index.php | 18 ++++++++++++------ frontend/views/variant/view.php | 508 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/web/css/style.css | 17 +++++++++++++++++ frontend/web/js/script.js | 21 ++++++++++++++++++--- frontend/widgets/OptionPicker.php | 22 ++++++++++++++++++++++ frontend/widgets/VariantGroupHelper.php | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/widgets/VariantHelper.php | 30 ++++++++++++++++++++++++++++++ frontend/widgets/VariantOptionHelper.php | 32 ++++++++++++++++++++++++++++++++ 17 files changed, 1204 insertions(+), 356 deletions(-) create mode 100755 frontend/controllers/VariantController.php create mode 100644 frontend/views/layouts/_basket_modal.php create mode 100755 frontend/views/variant/view.php create mode 100644 frontend/widgets/OptionPicker.php create mode 100644 frontend/widgets/VariantGroupHelper.php create mode 100644 frontend/widgets/VariantHelper.php create mode 100644 frontend/widgets/VariantOptionHelper.php diff --git a/frontend/controllers/CategoryController.php b/frontend/controllers/CategoryController.php index 2230acb..c94c145 100755 --- a/frontend/controllers/CategoryController.php +++ b/frontend/controllers/CategoryController.php @@ -41,7 +41,7 @@ $query = $filterHelper->buildQuery() ->innerJoinWith('category', false) ->andWhere([ 'product_to_category.category_id' => $model->id ]) - ->with('image', 'variants', 'lang'); + ->with('image', 'variants.image', 'lang'); $dataProvider = new ActiveDataProvider( [ 'query' => $query, @@ -84,6 +84,9 @@ $alias = Alias::find() ->where([ 'value' => $category ]) ->one(); + if (empty($alias)) { + throw new NotFoundHttpException('Category not found'); + } $id = $filter->getIdFromRoute($alias->route); /** * @var Category $model diff --git a/frontend/controllers/ProductController.php b/frontend/controllers/ProductController.php index 5e2121c..8571950 100755 --- a/frontend/controllers/ProductController.php +++ b/frontend/controllers/ProductController.php @@ -1,4 +1,5 @@ findModel($id); - /** - * @var SeoComponent $seo - */ - $seo = Yii::$app->get('seo'); - $seo->setModel($model->lang); - $variant = $model->variants[ 0 ]; - $groups = $variant->getSortedGroups(); - $similar = $model->getSimilarProducts(8); - - return $this->render( - 'view', + $model = Product::find() + ->with('variant') + ->where([ 'id' => $id ]) + ->one(); + if (!$model || empty($model->variant)) { + throw new NotFoundHttpException('Product not found'); + } + return $this->redirect( [ - 'model' => $model, - 'variant' => $variant, - 'groups' => $groups, - 'similar' => $similar, + 'variant/view', + 'id' => $model->variant->id, ] ); + //Uncomment to have product page + // $model = $this->findModel($id); + // /** + // * @var SeoComponent $seo + // */ + // $seo = Yii::$app->get('seo'); + // $seo->setModel($model->lang); + // $variant = $model->variants[ 0 ]; + // $groups = $variant->getSortedGroups(); + // $similar = $model->getSimilarProducts(8); + // + // return $this->render( + // 'view', + // [ + // 'model' => $model, + // 'variant' => $variant, + // 'groups' => $groups, + // 'similar' => $similar, + // ] + // ); } /** @@ -109,7 +124,7 @@ ->andWhere( [ 'variant_id' => \Yii::$app->request->post('variant'), - + ] ) ->one(); @@ -133,7 +148,7 @@ 'message' => \Yii::t('app', 'Товар убран из избранного'), ]; } - + return [ 'button' => Html::button( Html::tag('i', '', [ 'class' => 'fa fa-heart' ]), @@ -169,7 +184,7 @@ $model->user_id = \Yii::$app->request->post('user'); $model->variant_id = \Yii::$app->request->post('variant'); $model->product_id = \Yii::$app->request->post('product'); - + if ($model->save()) { return [ 'button' => Html::button( @@ -190,7 +205,7 @@ 'message' => 'Товар добавлен в избранное', ]; } - + return [ 'button' => Html::button( Html::tag('i', '', [ 'class' => 'fa fa-heart-o' ]), diff --git a/frontend/controllers/SiteController.php b/frontend/controllers/SiteController.php index b1f2b46..abab6ba 100755 --- a/frontend/controllers/SiteController.php +++ b/frontend/controllers/SiteController.php @@ -76,17 +76,17 @@ ->where([ 'level' => 0 ]) ->all(); $topItems = Product::find() - ->with('lang', 'image', 'variants') + ->with('lang', 'image', 'variants.image') ->is('mask', 1) ->limit(20) ->all(); $newItems = Product::find() - ->with('lang', 'image', 'variants') + ->with('lang', 'image', 'variants.image') ->is('mask', 2) ->limit(20) ->all(); $saleItems = Product::find() - ->with('lang', 'image', 'variants') + ->with('lang', 'image', 'variants.image') ->is('mask', 4) ->limit(20) ->all(); diff --git a/frontend/controllers/VariantController.php b/frontend/controllers/VariantController.php new file mode 100755 index 0000000..500e7fb --- /dev/null +++ b/frontend/controllers/VariantController.php @@ -0,0 +1,98 @@ +findModel($id); + /** + * @var SeoComponent $seo + */ + $seo = Yii::$app->get('seo'); + $seo->setModel($model->lang); + $groups = $model->getSortedGroups(); + $similar = $model->product->getSimilarProducts(8); + + return $this->render( + 'view', + [ + 'model' => $model, + 'groups' => $groups, + 'similar' => $similar, + ] + ); + } + + /** + * Find variant by ID + * + * @param $id + * + * @return \artbox\catalog\models\Variant + * @throws \yii\web\NotFoundHttpException + */ + protected function findModel($id) + { + /** + * @var SeoComponent $seo + */ + $seo = \Yii::$app->get('seo'); + /** + * @var Variant $model + */ + $model = Variant::findWithFilters() + ->with('lang', 'image') + ->with( + [ + 'product' => function ($query) { + /** + * @var ActiveQuery $query + */ + $query->with('images') + ->with( + [ + 'category' => function ($query) { + /** + * @var ActiveQuery $query + */ + $query->with('lang') + ->with('parent.lang'); + }, + ] + ); + }, + ] + ) + ->where([ 'id' => $id ]) + ->one(); + if (!empty($model)) { + if ($model->lang->alias_id !== $seo->aliasId) { + throw new NotFoundHttpException(\Yii::t('app', 'Wrong language')); + } + return $model; + } else { + throw new NotFoundHttpException(\Yii::t('app', 'Model not found')); + } + } + } \ No newline at end of file diff --git a/frontend/views/category/_product_item.php b/frontend/views/category/_product_item.php index acb4ada..1836bb3 100755 --- a/frontend/views/category/_product_item.php +++ b/frontend/views/category/_product_item.php @@ -31,6 +31,36 @@ ); ?> +
+
+ variants as $variant) { + ?> +
+ image ? $variant->image->getPath() : '@frontend/web/img/no-image.png' + ) + ->fillResize(40, 40) + ->render(), + [ + 'class' => 'img-responsive-image1', + ] + ), + [ + 'variant/view', + 'id' => $variant->id, + ] + ); + ?> +
+ +
+

diff --git a/frontend/views/layouts/_basket_modal.php b/frontend/views/layouts/_basket_modal.php new file mode 100644 index 0000000..a5c9677 --- /dev/null +++ b/frontend/views/layouts/_basket_modal.php @@ -0,0 +1,218 @@ + diff --git a/frontend/views/layouts/_category_menu.php b/frontend/views/layouts/_category_menu.php index 200a9a4..bd8bdec 100755 --- a/frontend/views/layouts/_category_menu.php +++ b/frontend/views/layouts/_category_menu.php @@ -15,42 +15,46 @@ diff --git a/frontend/views/layouts/main.php b/frontend/views/layouts/main.php index 3b3eb9a..17504d7 100755 --- a/frontend/views/layouts/main.php +++ b/frontend/views/layouts/main.php @@ -6,7 +6,6 @@ * @var User $user */ use artbox\core\components\SeoComponent; - use artbox\core\helpers\ImageHelper; use artbox\core\models\Feedback; use artbox\core\models\Image; use artbox\core\models\Page; @@ -181,7 +180,7 @@ _________________________________________________________ --> 'logo', ] @@ -257,29 +256,29 @@ _________________________________________________________ -->

- -
- 0 - 'sub-title', - ] - ), - [ - '#', - ], - [ - 'class' => 'cart-item-link', - 'data-toggle' => 'modal', - 'data-target' => '#basket-modal', - ] - ); - ?> -
+ +
+ 0 + 'sub-title', + ] + ), + [ + '#', + ], + [ + 'class' => 'cart-item-link', + 'data-toggle' => 'modal', + 'data-target' => '#basket-modal', + ] + ); + ?> +
- - - - - + + + + + @@ -770,7 +559,7 @@ _________________________________________________________ -->

О нас

- +

about ?>

@@ -844,9 +633,16 @@ _________________________________________________________ -->
country ?>

- - Написать нам - + 'btn btn-small btn-template-main', + ] + ); + ?> +
diff --git a/frontend/views/site/_slider_product.php b/frontend/views/site/_slider_product.php index e8d5798..38598b6 100755 --- a/frontend/views/site/_slider_product.php +++ b/frontend/views/site/_slider_product.php @@ -31,39 +31,37 @@ ); ?>
- -
-
+ +
+
- -
- image ? $product->image->getPath() : '@frontend/web/img/no-image.png' - ) - ->fillResize(40, 40) - ->render(), - [ - 'class' => 'img-responsive-image1', - ] - ), - [ - 'product/view', - 'id' => $product->id, - ] - ); + foreach ($product->variants as $variant) { ?> -
- + image ? $variant->image->getPath() : '@frontend/web/img/no-image.png' + ) + ->fillResize(40, 40) + ->render(), + [ + 'class' => 'img-responsive-image1', + ] + ), + [ + 'variant/view', + 'id' => $variant->id, + ] + ); + ?> +
+ -
+

@@ -134,10 +132,10 @@ } if ($product->is('top')) { ?> -
-
-
-
+
+
+
+
diff --git a/frontend/views/site/index.php b/frontend/views/site/index.php index 7b7330a..52381ca 100755 --- a/frontend/views/site/index.php +++ b/frontend/views/site/index.php @@ -229,14 +229,16 @@ _________________________________________________________ -->

- -

diff --git a/frontend/views/variant/view.php b/frontend/views/variant/view.php new file mode 100755 index 0000000..89faba2 --- /dev/null +++ b/frontend/views/variant/view.php @@ -0,0 +1,508 @@ +get('seo'); + if (!empty($model->product->category)) { + if (!empty($model->product->category->parent)) { + $this->params[ 'breadcrumbs' ][] = [ + 'label' => $model->product->category->parent->lang->title, + 'url' => [ + '/category/view', + 'category' => $model->product->category->parent->lang->alias->value, + ], + ]; + } + $this->params[ 'breadcrumbs' ][] = [ + 'label' => $model->product->category->lang->title, + 'url' => [ + '/category/view', + 'category' => $model->product->category->lang->alias->value, + ], + ]; + } + $this->params[ 'breadcrumbs' ][] = $model->product->lang->title; + $this->params[ 'breadcrumbs' ][] = $seo->title; + $images = $model->product->images; + if (!empty($model->product->image)) { + array_unshift($images, $model->product->image); + } + if (!empty($model->image)) { + array_unshift($images, $model->image); + } +?> +
+
+
+
+ +
+
+
+ getPath()) + ->fillResize(555, 555) + ->renderImage( + [ + 'class' => 'img-responsive', + 'alt' => $model->lang->title, + 'title' => $model->lang->title, + ] + ); + } else { + echo ImageHelper::set('@frontend/web/img/no-image.png') + ->fillResize(555, 555) + ->renderImage( + [ + 'class' => 'img-responsive', + 'alt' => $model->lang->title, + 'title' => $model->lang->title, + ] + ); + } + ?> +
+ + product->is('akcia')) { + ?> +
+
АКЦИЯ
+
+
+ + product->is('new')) { + ?> +
+
НОВОЕ
+
+
+ + product->is('top')) { + ?> +
+
ТОП
+
+
+ + + +
+ getPath()) + ->fillResize(70, 60) + ->renderImage( + [ + 'class' => 'img-responsive', + 'alt' => $model->lang->title, + 'title' => $model->lang->title, + ] + ), + ImageHelper::set($image->getPath()) + ->fillResize(555, 555) + ->render(), + [ + 'class' => 'thumb', + ] + ), + [ + 'class' => 'col-xs-2', + ] + ); + } + } else { + echo Html::tag( + 'div', + Html::a( + ImageHelper::set('@frontend/web/img/no-image.png') + ->fillResize(70, 60) + ->renderImage( + [ + 'class' => 'img-responsive', + 'alt' => $model->lang->title, + 'title' => $model->lang->title, + ] + ), + ImageHelper::set('@frontend/web/img/no-image.png') + ->fillResize(555, 555) + ->render(), + [ + 'class' => 'thumb', + ] + ), + [ + 'class' => 'col-xs-2', + ] + ); + } + ?> +
+ product->video)) { + ?> +
+
+ +
+
+ product->video; ?> +
+
+ +
+
+
+

lang->title; ?>

+

sku; ?>

+

+ Цена:price ? : 0; ?> грн  + canBuy()) { + echo Html::a( + Html::tag( + 'i', + '', + [ + 'class' => 'fa fa-shopping-cart', + ] + ) . \Yii::t('app', 'Добавить в корзину'), + '#', + [ + 'class' => 'btn btn-success add-to-basket', + 'data-id' => $model->id, + ] + ); + } else { + echo Html::a( + \Yii::t('app', 'Нет в наличии'), + '#', + [ + 'class' => 'btn btn-info disabled', + 'data-id' => $model->id, + ] + ); + } + ?> + user->isGuest) { + echo Html::button( + Html::tag('i', '', [ 'class' => 'fa fa-heart-o' ]), + [ + 'title' => 'Добавить в избранное', + 'data' => [ + 'toggle' => 'tooltip', + 'placement' => 'top', + ], + 'class' => 'btn btn-default pull-right disabled', + ] + ); + } elseif (in_array($model->id, \Yii::$app->user->identity->wishlist)) { + echo Html::button( + Html::tag('i', '', [ 'class' => 'fa fa-heart' ]), + [ + 'title' => 'Убрать из избранного', + 'data' => [ + 'toggle' => 'tooltip', + 'placement' => 'top', + 'product' => $model->product->id, + 'variant' => $model->id, + 'user' => \Yii::$app->user->identity->getId(), + 'url' => Url::to([ 'product/wishlist-rm' ]), + ], + 'class' => 'wishlist-rm btn btn-success pull-right', + ] + ); + } else { + echo Html::button( + Html::tag('i', '', [ 'class' => 'fa fa-heart-o' ]), + [ + 'title' => 'Добавить в избранное', + 'data' => [ + 'toggle' => 'tooltip', + 'placement' => 'top', + 'product' => $model->product->id, + 'variant' => $model->id, + 'user' => \Yii::$app->user->identity->getId(), + 'url' => Url::to([ 'product/wishlist-add' ]), + ], + 'class' => 'wishlist-add btn btn-success pull-right', + ] + ); + } + ?> +

+
+ canBuy()) { + echo Html::a( + Html::icon( + 'phone', + [ + 'prefix' => 'fa fa-', + ] + ) . \Yii::t('app', 'Купить в один клик'), + '#', + [ + 'data' => [ + 'toggle' => 'modal', + 'target' => '#oneclick-modal', + ], + 'class' => 'btn btn-template-main', + ] + ); + } + ?> +
+
+ product); + $productVariantGroups = $helper->getGroups(); + foreach ($productVariantGroups as $productVariantGroup) { + ?> +
+

+ lang->title . ": "; + ?> +

+
+ getOptions() as $option) { + /** + * @var \artbox\catalog\models\VariantOptionExcl $productVariantOptionModel + */ + $productVariantOptionModel = $option[ 'option' ]; + /** + * @var \frontend\widgets\VariantHelper $variantHelper + */ + $variantHelper = $option[ 'variants' ]; + $variant = $variantHelper->getVariant(); + /** + * @var \artbox\core\models\Image $img + */ + $img = $productVariantOptionModel->image ? : $variant->image ? : null; + echo Html::a( + Html::tag( + 'div', + $img ? ImageHelper::set($img->getPath()) + ->fillResize(90, 55) + ->renderImage( + [ + 'alt' => $productVariantOptionModel->lang->value, + 'title' => $productVariantOptionModel->lang->value, + 'class' => 'product-variant-group-option-img', + ] + ) : $productVariantOptionModel->lang->value, + [ + 'class' => 'product-variant-group-option', + ] + ), + [ + 'variant/view', + 'id' => $variant->id, + ] + ); + } + ?> +
+
+ +
+
+

+ lang->description ? : \Yii::t('app', 'Нет описания'); ?> +
+ +
+

+ + + + lang->title, + [ 'class' => 'td-title' ] + ) . Html::tag( + 'td', + implode( + ', ', + ArrayHelper::getColumn( + $optionGroup->currentOptions, + 'lang.value' + ) + ) + ) + ); + } + } + ?> + +
+ +
+
+ +
+ + +
+

+
+ + + +
+ +
+ +
+ +
+ + diff --git a/frontend/web/css/style.css b/frontend/web/css/style.css index 20756a1..098f8c0 100755 --- a/frontend/web/css/style.css +++ b/frontend/web/css/style.css @@ -4752,4 +4752,21 @@ a i.fa, button i.fa, span.fa { .vcovers .vcover img:hover{ border: 1px solid rgb(0, 91, 172); +} + +.product-variant-group-option { + display: inline-block; + margin: 5px; + width: 90px; + height: 55px; +} + +.product-variant-group-option-img { + width: 100%; + height: 100%; +} + +.owl-carousel.brand-carousel .owl-item { + float: none; + display: inline-block; } \ No newline at end of file diff --git a/frontend/web/js/script.js b/frontend/web/js/script.js index ad38dee..258d628 100755 --- a/frontend/web/js/script.js +++ b/frontend/web/js/script.js @@ -93,7 +93,14 @@ $(function() { e.preventDefault(); var id = $(this) .data('id'); - basket.add(id, 1); + var xhr = basket.add(id, 1); + xhr.done(function() { + $.pjax.reload({ + container: '#basket-modal', + fragment: '#basket-modal', + timeout: 5000 + }); + }); if ($('.alert-cart').length > 0) { } else { $('body') @@ -136,12 +143,20 @@ $(function() { .parents('.product-row-basket') .data('id'); showLoader('#basket'); + showLoader('#basket-modal'); var xhr = basket.set(id, $(this) .val()); xhr.done(function() { + if ($('#basket').length) { + $.pjax.reload({ + container: '#basket', + fragment: '#basket', + timeout: 5000 + }); + } $.pjax.reload({ - container: '#basket', - fragment: '#basket', + container: '#basket-modal', + fragment: '#basket-modal', timeout: 5000 }); }); diff --git a/frontend/widgets/OptionPicker.php b/frontend/widgets/OptionPicker.php new file mode 100644 index 0000000..9dbec8c --- /dev/null +++ b/frontend/widgets/OptionPicker.php @@ -0,0 +1,22 @@ +getVariants() + ->all(); + foreach ($variants as $variant) { + $helper->addVariant($variant); + } + return $helper; + } + } \ No newline at end of file diff --git a/frontend/widgets/VariantGroupHelper.php b/frontend/widgets/VariantGroupHelper.php new file mode 100644 index 0000000..578ce99 --- /dev/null +++ b/frontend/widgets/VariantGroupHelper.php @@ -0,0 +1,56 @@ +id, $this->groups)) { + $this->groups[ $group->id ][ 'group' ] = $group; + $this->groups[ $group->id ][ 'options' ] = new VariantOptionHelper(); + } + } + + public function addOption(VariantOptionExcl $option) + { + if (empty($this->groups[ $option->groupId ])) { + $this->addGroup($option->variantOptionGroupExcl); + } + /** + * @var \frontend\widgets\VariantOptionHelper $variantOptionHelper + */ + $variantOptionHelper = $this->groups[ $option->groupId ][ 'options' ]; + $variantOptionHelper->addOption($option); + } + + public function addVariant(Variant $variant) + { + $options = $variant->variantOptionExcls; + foreach ($options as $option) { + $this->addOption($option); + $variantContainer = $this->getVariantContainer($option); + $variantContainer->addVariant($variant); + } + } + + public function getVariantContainer(VariantOptionExcl $option) + { + /** + * @var \frontend\widgets\VariantOptionHelper $variantOptionHelper + */ + $variantOptionHelper = $this->groups[ $option->groupId ][ 'options' ]; + return $variantOptionHelper->getVariantContainer($option); + } + + public function getGroups() + { + return $this->groups; + } + } \ No newline at end of file diff --git a/frontend/widgets/VariantHelper.php b/frontend/widgets/VariantHelper.php new file mode 100644 index 0000000..d63c8f2 --- /dev/null +++ b/frontend/widgets/VariantHelper.php @@ -0,0 +1,30 @@ +id, $this->variants)) { + $this->variants[ $variant->id ] = $variant; + } + } + + public function getVariants() + { + return $this->variants; + } + + public function getVariant() + { + return $this->variants[ array_keys($this->variants)[ 0 ] ]; + } + } \ No newline at end of file diff --git a/frontend/widgets/VariantOptionHelper.php b/frontend/widgets/VariantOptionHelper.php new file mode 100644 index 0000000..fab4294 --- /dev/null +++ b/frontend/widgets/VariantOptionHelper.php @@ -0,0 +1,32 @@ +id, $this->options)) { + $this->options[ $option->id ][ 'option' ] = $option; + $this->options[ $option->id ][ 'variants' ] = new VariantHelper(); + } + } + + public function getVariantContainer(VariantOptionExcl $option) + { + /** + * @var \frontend\widgets\VariantHelper $variantHelper + */ + $variantHelper = $this->options[ $option->id ][ 'variants' ]; + return $variantHelper; + } + + public function getOptions() + { + return $this->options; + } + } \ No newline at end of file -- libgit2 0.21.4