Commit 2b3158498c4a5e029650159473412701eb9eaa15

Authored by Alexey Boroda
1 parent f540c70b

-Product card (without video)

CatalogUrlManager.php 100644 → 100755
behaviors/DefaultVariantBehavior.php 100644 → 100755
composer.json 100644 → 100755
console/GenerateController.php 100644 → 100755
controllers/ManageController.php
... ... @@ -2,6 +2,7 @@
2 2  
3 3 namespace artweb\artbox\ecommerce\controllers;
4 4  
  5 + use artweb\artbox\ecommerce\models\ProductVideo;
5 6 use artweb\artbox\language\models\Language;
6 7 use artweb\artbox\ecommerce\models\Export;
7 8 use artweb\artbox\ecommerce\models\Import;
... ... @@ -147,6 +148,7 @@
147 148 'model' => $model,
148 149 'modelLangs' => $model->modelLangs,
149 150 'groups' => $groups,
  151 + 'videos' => !empty( $model->videos ) ? $model->videos : [ new ProductVideo() ],
150 152 ]
151 153 );
152 154 }
... ... @@ -354,7 +356,7 @@
354 356 throw new \HttpRequestException('Must be AJAX');
355 357 }
356 358 }
357   -
  359 +
358 360 /**
359 361 * Perform export
360 362 *
... ... @@ -397,7 +399,7 @@
397 399 if (( $model = Product::find()
398 400 ->where([ 'id' => $id ])
399 401 ->with('lang')
400   - ->one() ) !== null
  402 + ->one() ) !== NULL
401 403 ) {
402 404 return $model;
403 405 } else {
... ...
models/Product.php
... ... @@ -21,6 +21,7 @@
21 21 *
22 22 * @property integer $brand_id
23 23 * @property integer $id
  24 + * @property ProductVideo[] $videos
24 25 * @property Category $category
25 26 * @property Category[] $categories
26 27 * @property ProductVariant $variant
... ... @@ -340,8 +341,12 @@
340 341 public function getFullName():string
341 342 {
342 343 $name = '';
343   - if (!empty($this->category->lang->category_synonym)) $name = $name . $this->category->lang->category_synonym . ' ';
344   - if (!empty($this->brand)) $name = $name . $this->brand->lang->title . ' ';
  344 + if (!empty( $this->category->lang->category_synonym )) {
  345 + $name = $name . $this->category->lang->category_synonym . ' ';
  346 + }
  347 + if (!empty( $this->brand )) {
  348 + $name = $name . $this->brand->lang->title . ' ';
  349 + }
345 350 $name .= $this->lang->title;
346 351 return $name;
347 352 }
... ... @@ -455,6 +460,11 @@
455 460 return $groups;
456 461 }
457 462  
  463 + public function getVideos()
  464 + {
  465 + return $this->hasMany(ProductVideo::className(), [ 'product_id' => 'id' ]);
  466 + }
  467 +
458 468 /**
459 469 * Get Stock query where current Product is in stock
460 470 *
... ...
models/ProductFrontendSearch.php 100644 → 100755
models/ProductToRating.php 100644 → 100755
models/ProductVariant.php
... ... @@ -67,6 +67,10 @@
67 67 */
68 68 class ProductVariant extends ActiveRecord
69 69 {
  70 +
  71 + public $customOption = [];
  72 +
  73 +
70 74 /**
71 75 * @var int[] $options
72 76 */
... ... @@ -113,7 +117,7 @@
113 117 'model' => ProductImage::className(),
114 118 'config' => [
115 119 'caption' => 'image',
116   - 'delete_action' => '/product/variant/delete-image',
  120 + 'delete_action' => 'variant/delete-image',
117 121 'id' => 'id',
118 122 ],
119 123 ],
... ... @@ -275,6 +279,28 @@
275 279 return $this->hasMany(TaxOption::className(), [ 'id' => 'option_id' ])
276 280 ->viaTable('product_variant_option', [ 'product_variant_id' => 'id' ]);
277 281 }
  282 +
  283 + /**
  284 + * Get one variant's option whith needed conditions, or random if condition is empty
  285 + *
  286 + * @param array $conditions
  287 + *
  288 + * @return ActiveQuery
  289 + */
  290 + public function getOption(array $conditions = [])
  291 + {
  292 + $query = $this->hasOne(TaxOption::className(), [ 'id' => 'option_id' ])
  293 + ->viaTable('product_variant_option', [ 'product_variant_id' => 'id' ]);
  294 + foreach ($conditions as $condition)
  295 + {
  296 + if (!empty($condition) && is_array($condition))
  297 + {
  298 + $query->andFilterWhere($condition);
  299 + }
  300 + }
  301 +
  302 + return $query;
  303 + }
278 304  
279 305 /**
280 306 * Get TaxOptions with preloaded TaxGroups for current ProductVariant
... ... @@ -307,13 +333,15 @@
307 333 {
308 334 $this->options = $values;
309 335 }
310   -
  336 +
311 337 /**
312 338 * Get all TaxGroups for current ProductVariant filled with $customOptions that satisfy current ProductVariant
313 339 *
314   - * @return TaxGroup[]
  340 + * @param array $conditions
  341 + *
  342 + * @return \artweb\artbox\ecommerce\models\TaxGroup[]
315 343 */
316   - public function getProperties()
  344 + public function getProperties(array $conditions = [])
317 345 {
318 346 $groups = $options = [];
319 347 foreach ($this->getOptions()
... ... @@ -324,11 +352,18 @@
324 352 */
325 353 $options[ $option->tax_group_id ][] = $option;
326 354 }
327   - foreach (TaxGroup::find()
  355 + $query = TaxGroup::find()
328 356 ->where([ 'tax_group.id' => array_keys($options) ])
329 357 ->orderBy([ 'sort' => SORT_ASC ])
330   - ->with('lang')
331   - ->all() as $group) {
  358 + ->with('lang');
  359 +
  360 + if (!empty($conditions)) {
  361 + foreach ($conditions as $condition) {
  362 + $query->andFilterWhere($condition);
  363 + }
  364 + }
  365 + foreach (
  366 + $query->all() as $group) {
332 367 /**
333 368 * @var TaxGroup $group
334 369 */
... ...
models/ProductVideo.php 0 → 100644
  1 +<?php
  2 +
  3 + namespace artweb\artbox\ecommerce\models;
  4 +
  5 + use yii\db\ActiveRecord;
  6 +
  7 + /**
  8 + * This is the model class for table "product_video".
  9 + *
  10 + * @property integer $id
  11 + * @property integer $product_id
  12 + * @property string $url
  13 + * @property Product $product
  14 + */
  15 + class ProductVideo extends ActiveRecord
  16 + {
  17 + /**
  18 + * @inheritdoc
  19 + */
  20 + public static function tableName()
  21 + {
  22 + return 'product_video';
  23 + }
  24 +
  25 + /**
  26 + * @inheritdoc
  27 + */
  28 + public function rules()
  29 + {
  30 + return [
  31 + [
  32 + [ 'product_id' ],
  33 + 'integer',
  34 + ],
  35 + [
  36 + [ 'url' ],
  37 + 'string',
  38 + 'max' => 255,
  39 + ],
  40 + [
  41 + [ 'product_id' ],
  42 + 'exist',
  43 + 'skipOnError' => true,
  44 + 'targetClass' => Product::className(),
  45 + 'targetAttribute' => [ 'product_id' => 'id' ],
  46 + ],
  47 + ];
  48 + }
  49 +
  50 + /**
  51 + * @inheritdoc
  52 + */
  53 + public function attributeLabels()
  54 + {
  55 + return [
  56 + 'id' => \Yii::t('app', 'ID'),
  57 + 'product_id' => \Yii::t('app', 'Product ID'),
  58 + 'url' => \Yii::t('app', 'Url'),
  59 + ];
  60 + }
  61 +
  62 + /**
  63 + * @return \yii\db\ActiveQuery
  64 + */
  65 + public function getProduct()
  66 + {
  67 + return $this->hasOne(Product::className(), [ 'id' => 'product_id' ]);
  68 + }
  69 + }
... ...
models/StockLang.php 100644 → 100755
models/TaxGroup.php
... ... @@ -24,6 +24,7 @@
24 24 * @property TaxOption[] $options
25 25 * @property TaxOption[] $customOptions
26 26 * @property string $alias
  27 + * @property integer $position
27 28 * * From language behavior *
28 29 * @property TaxGroupLang $lang
29 30 * @property TaxGroupLang[] $langs
... ... @@ -94,6 +95,7 @@
94 95 [
95 96 'level',
96 97 'sort',
  98 + 'position',
97 99 ],
98 100 'integer',
99 101 ],
... ... @@ -116,6 +118,7 @@
116 118 'display' => 'Display',
117 119 'is_menu' => 'Отображать в меню',
118 120 'level' => 'уровень',
  121 + 'ppsition' => 'Позиция',
119 122 ];
120 123 }
121 124  
... ...
views/manage/_form.php
1 1 <?php
2 2  
  3 + use artweb\artbox\ecommerce\models\ProductVideo;
3 4 use artweb\artbox\language\widgets\LanguageForm;
4 5 use artweb\artbox\ecommerce\models\Brand;
5 6 use artweb\artbox\ecommerce\models\ProductLang;
6 7 use artweb\artbox\ecommerce\models\TaxGroup;
  8 + use wbraganca\dynamicform\DynamicFormWidget;
7 9 use yii\db\ActiveQuery;
8 10 use yii\helpers\Html;
9 11 use yii\widgets\ActiveForm;
... ... @@ -11,14 +13,31 @@
11 13 use artweb\artbox\components\artboxtree\ArtboxTreeHelper;
12 14 use artweb\artbox\ecommerce\helpers\ProductHelper;
13 15 use kartik\select2\Select2;
  16 + use yii\web\View;
14 17  
15 18 /**
16   - * @var yii\web\View $this
  19 + * @var yii\web\View $this
17 20 * @var artweb\artbox\ecommerce\models\Product $model
18   - * @var ProductLang[] $modelLangs
19   - * @var yii\widgets\ActiveForm $form
20   - * @var ActiveQuery $groups
  21 + * @var ProductLang[] $modelLangs
  22 + * @var yii\widgets\ActiveForm $form
  23 + * @var ActiveQuery $groups
  24 + * @var ProductVideo[] $videos
21 25 */
  26 +
  27 + $js = '
  28 +$(".dynamicform_wrapper").on("beforeDelete", function(e, item) {
  29 + if (! confirm("Are you sure you want to delete this item?")) {
  30 + return false;
  31 + }
  32 + return true;
  33 +});
  34 +
  35 +$(".dynamicform_wrapper").on("limitReached", function(e, item) {
  36 + alert("Limit reached");
  37 +});
  38 +';
  39 +
  40 + $this->registerJs($js, View::POS_END);
22 41 ?>
23 42  
24 43 <div class="product-form">
... ... @@ -39,6 +58,68 @@
39 58 <?= $form->field($model, 'video')
40 59 ->textarea(); ?>
41 60  
  61 + <?php DynamicFormWidget::begin(
  62 + [
  63 + 'widgetContainer' => 'dynamicform_wrapper',
  64 + // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
  65 + 'widgetBody' => '.container-items',
  66 + // required: css class selector
  67 + 'widgetItem' => '.item',
  68 + // required: css class
  69 + 'limit' => 10,
  70 + // the maximum times, an element can be added (default 999)
  71 + 'min' => 1,
  72 + // 0 or 1 (default 1)
  73 + 'insertButton' => '.add-item',
  74 + // css class
  75 + 'deleteButton' => '.remove-item',
  76 + // css class
  77 + 'model' => $videos[ 0 ],
  78 + 'formId' => 'dynamic-form',
  79 + 'formFields' => [
  80 + 'url',
  81 + ],
  82 + ]
  83 + ); ?>
  84 +
  85 + <div class="panel panel-default">
  86 + <div class="panel-heading">
  87 + <h4>
  88 + <i class="glyphicon glyphicon-envelope"></i> Склады
  89 + <button type="button" class="add-item btn btn-success btn-sm pull-right">
  90 + <i class="glyphicon glyphicon-plus"></i> Add
  91 + </button>
  92 + </h4>
  93 + </div>
  94 + <div class="panel-body">
  95 + <div class="container-items"><!-- widgetBody -->
  96 + <?php foreach ($videos as $i => $video) { ?>
  97 + <div class="item panel panel-default"><!-- widgetItem -->
  98 + <div class="panel-body">
  99 +<!-- --><?php
  100 +// // necessary for update action.
  101 +// if (!$stock->isNewRecord) {
  102 +// echo Html::activeHiddenInput($stock, "[{$i}]stock_id");
  103 +// }
  104 +// ?>
  105 + <div class="row">
  106 + <div class="col-sm-5">
  107 + <?= $form->field($video, "[{$i}]url")
  108 + ->textInput([ 'maxlength' => true ]) ?>
  109 + </div>
  110 + <div class="col-sm-2" style="margin-top: 30px">
  111 + <button type="button" class="remove-item btn btn-danger btn-xs">
  112 + <i class="glyphicon glyphicon-minus"></i></button>
  113 + </div>
  114 + </div><!-- .row -->
  115 + </div>
  116 + </div>
  117 + <?php } ?>
  118 + </div>
  119 + </div>
  120 + </div><!-- .panel -->
  121 + <?php DynamicFormWidget::end(); ?>
  122 +
42 123 <?= $form->field($model, 'brand_id')
43 124 ->dropDownList(
44 125 ArrayHelper::map(
... ...
views/manage/update.php
... ... @@ -2,20 +2,26 @@
2 2  
3 3 use artweb\artbox\ecommerce\models\Product;
4 4 use artweb\artbox\ecommerce\models\ProductLang;
  5 + use artweb\artbox\ecommerce\models\ProductVideo;
5 6 use yii\db\ActiveQuery;
6 7 use yii\helpers\Html;
7 8 use yii\web\View;
8 9  
9 10 /**
10   - * @var View $this
11   - * @var Product $model
12   - * @var ProductLang[] $modelLangs
13   - * @var ActiveQuery $groups
  11 + * @var View $this
  12 + * @var Product $model
  13 + * @var ProductLang[] $modelLangs
  14 + * @var ActiveQuery $groups
  15 + * @var ProductVideo[] $videos
14 16 */
15 17  
16   - $this->title = Yii::t('product', 'Update {modelClass}: ', [
17   - 'modelClass' => 'Product',
18   - ]) . ' ' . $model->lang->title;
  18 + $this->title = Yii::t(
  19 + 'product',
  20 + 'Update {modelClass}: ',
  21 + [
  22 + 'modelClass' => 'Product',
  23 + ]
  24 + ) . ' ' . $model->lang->title;
19 25 $this->params[ 'breadcrumbs' ][] = [
20 26 'label' => Yii::t('product', 'Products'),
21 27 'url' => [ 'index' ],
... ... @@ -33,10 +39,14 @@
33 39  
34 40 <h1><?= Html::encode($this->title) ?></h1>
35 41  
36   - <?= $this->render('_form', [
37   - 'model' => $model,
38   - 'modelLangs' => $modelLangs,
39   - 'groups' => $groups,
40   - ]) ?>
  42 + <?= $this->render(
  43 + '_form',
  44 + [
  45 + 'model' => $model,
  46 + 'modelLangs' => $modelLangs,
  47 + 'groups' => $groups,
  48 + 'videos' => $videos,
  49 + ]
  50 + ) ?>
41 51  
42 52 </div>
... ...
views/tax-group/_form.php
... ... @@ -3,6 +3,7 @@
3 3 use artweb\artbox\language\widgets\LanguageForm;
4 4 use artweb\artbox\ecommerce\models\TaxGroup;
5 5 use artweb\artbox\ecommerce\models\TaxGroupLang;
  6 + use kartik\select2\Select2;
6 7 use yii\helpers\Html;
7 8 use yii\web\View;
8 9 use yii\widgets\ActiveForm;
... ... @@ -22,11 +23,30 @@
22 23 <?php $form = ActiveForm::begin([ 'options' => [ 'enctype' => 'multipart/form-data' ] ]); ?>
23 24  
24 25 <?= $form->field($model, 'categories')
25   - ->dropDownList(ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'id', 'lang.title'), [
26   - 'multiple' => true,
27   - ])
  26 + ->dropDownList(
  27 + ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'id', 'lang.title'),
  28 + [
  29 + 'multiple' => true,
  30 + ]
  31 + )
28 32 ->label('Use in the following categories') ?>
29 33  
  34 + <?= $form->field($model, 'position')
  35 + ->widget(
  36 + Select2::className(),
  37 + [
  38 + 'data' => [
  39 + 0 => 'Не отображать',
  40 + 1 => 'Во вкладках',
  41 + 2 => 'В списке',
  42 + ],
  43 + 'options' => [ 'placeholder' => 'Положение в карточке товара' ],
  44 + 'pluginOptions' => [
  45 + 'allowClear' => true,
  46 + ],
  47 + ]
  48 + ) ?>
  49 +
30 50 <?= $form->field($model, 'is_filter')
31 51 ->checkbox() ?>
32 52  
... ... @@ -40,15 +60,20 @@
40 60 ->textInput() ?>
41 61  
42 62 <?php
43   - echo LanguageForm::widget([
44   - 'modelLangs' => $modelLangs,
45   - 'formView' => '@artweb/artbox/ecommerce/views/tax-group/_form_language',
46   - 'form' => $form,
47   - ]);
  63 + echo LanguageForm::widget(
  64 + [
  65 + 'modelLangs' => $modelLangs,
  66 + 'formView' => '@artweb/artbox/ecommerce/views/tax-group/_form_language',
  67 + 'form' => $form,
  68 + ]
  69 + );
48 70 ?>
49 71  
50 72 <div class="form-group">
51   - <?= Html::submitButton($model->isNewRecord ? Yii::t('rubrication', 'Create') : Yii::t('rubrication', 'Update'), [ 'class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary' ]) ?>
  73 + <?= Html::submitButton(
  74 + $model->isNewRecord ? Yii::t('rubrication', 'Create') : Yii::t('rubrication', 'Update'),
  75 + [ 'class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary' ]
  76 + ) ?>
52 77 </div>
53 78  
54 79 <?php ActiveForm::end(); ?>
... ...
widgets/BasketHead.php 100644 → 100755
widgets/BasketModal.php 100644 → 100755
widgets/views/basket_head.php 100644 → 100755
widgets/views/basket_modal.php 100644 → 100755