Commit af036678130d7605d53d59b12b79146c02a911cc
1 parent
b569ac34
Image behaviors
Showing
20 changed files
with
898 additions
and
833 deletions
Show diff stats
backend/controllers/ProjectController.php
@@ -92,16 +92,7 @@ | @@ -92,16 +92,7 @@ | ||
92 | $model->generateLangs(); | 92 | $model->generateLangs(); |
93 | if($model->load(Yii::$app->request->post())) { | 93 | if($model->load(Yii::$app->request->post())) { |
94 | $model->loadLangs(\Yii::$app->request); | 94 | $model->loadLangs(\Yii::$app->request); |
95 | - $model->imagesUpload = UploadedFile::getInstances($model, 'imagesUpload'); | ||
96 | if($model->save() && $model->transactionStatus) { | 95 | if($model->save() && $model->transactionStatus) { |
97 | - if($model->imagesUpload && ( ( $images = $model->imagesUpload() ) !== false )) { | ||
98 | - foreach($images as $image) { | ||
99 | - $imageModel = new ProjectImage(); | ||
100 | - $imageModel->project_id = $model->project_id; | ||
101 | - $imageModel->image = $image; | ||
102 | - $imageModel->save(); | ||
103 | - } | ||
104 | - } | ||
105 | return $this->redirect([ | 96 | return $this->redirect([ |
106 | 'view', | 97 | 'view', |
107 | 'id' => $model->project_id, | 98 | 'id' => $model->project_id, |
@@ -128,16 +119,7 @@ | @@ -128,16 +119,7 @@ | ||
128 | $model->generateLangs(); | 119 | $model->generateLangs(); |
129 | if($model->load(Yii::$app->request->post())) { | 120 | if($model->load(Yii::$app->request->post())) { |
130 | $model->loadLangs(\Yii::$app->request); | 121 | $model->loadLangs(\Yii::$app->request); |
131 | - $model->imagesUpload = UploadedFile::getInstances($model, 'imagesUpload'); | ||
132 | if($model->save() && $model->transactionStatus) { | 122 | if($model->save() && $model->transactionStatus) { |
133 | - if($model->imagesUpload && ( ( $images = $model->imagesUpload() ) !== false )) { | ||
134 | - foreach($images as $image) { | ||
135 | - $imageModel = new ProjectImage(); | ||
136 | - $imageModel->project_id = $model->project_id; | ||
137 | - $imageModel->image = $image; | ||
138 | - $imageModel->save(); | ||
139 | - } | ||
140 | - } | ||
141 | return $this->redirect([ | 123 | return $this->redirect([ |
142 | 'view', | 124 | 'view', |
143 | 'id' => $model->project_id, | 125 | 'id' => $model->project_id, |
1 | +<?php | ||
2 | + | ||
3 | + namespace common\behaviors; | ||
4 | + | ||
5 | + use yii\base\Behavior; | ||
6 | + use yii\base\Event; | ||
7 | + use yii\db\ActiveRecord; | ||
8 | + | ||
9 | + /** | ||
10 | + * Class ImageBehavior | ||
11 | + * @package common\behaviors | ||
12 | + */ | ||
13 | + class ImageBehavior extends Behavior | ||
14 | + { | ||
15 | + | ||
16 | + /** | ||
17 | + * @var string column where file name is stored | ||
18 | + */ | ||
19 | + public $link; | ||
20 | + | ||
21 | + /** | ||
22 | + * @var string directory name | ||
23 | + */ | ||
24 | + public $directory; | ||
25 | + | ||
26 | + /** | ||
27 | + * @inheritdoc | ||
28 | + */ | ||
29 | + public function events() | ||
30 | + { | ||
31 | + return [ | ||
32 | + ActiveRecord::EVENT_BEFORE_DELETE => 'beforeDelete', | ||
33 | + ]; | ||
34 | + } | ||
35 | + | ||
36 | + /** | ||
37 | + * @param Event $event | ||
38 | + */ | ||
39 | + public function beforeDelete($event) | ||
40 | + { | ||
41 | + $file = $this->getImageFile(); | ||
42 | + if(file_exists($file)) { | ||
43 | + unlink($file); | ||
44 | + } | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Get image file path | ||
49 | + * | ||
50 | + * @return null|string | ||
51 | + */ | ||
52 | + public function getImageFile() | ||
53 | + { | ||
54 | + $link = $this->link; | ||
55 | + return empty( $this->owner->$link ) ? NULL : \Yii::getAlias('@storage/' . $this->directory . '/' . $this->owner->$link); | ||
56 | + } | ||
57 | + | ||
58 | + /** | ||
59 | + * Get image file url | ||
60 | + * | ||
61 | + * @return null|string | ||
62 | + */ | ||
63 | + public function getImageUrl() | ||
64 | + { | ||
65 | + $link = $this->link; | ||
66 | + return empty( $this->owner->$link ) ? NULL : '/storage/' . $this->directory . '/' . $this->owner->$link; | ||
67 | + } | ||
68 | + } | ||
0 | \ No newline at end of file | 69 | \ No newline at end of file |
1 | +<?php | ||
2 | + | ||
3 | + namespace common\behaviors; | ||
4 | + | ||
5 | + use common\components\artboximage\ArtboxImageHelper; | ||
6 | + use yii\base\Behavior; | ||
7 | + use yii\db\ActiveRecord; | ||
8 | + use yii\helpers\Url; | ||
9 | + | ||
10 | + /** | ||
11 | + * Class MultipleImgBehavior | ||
12 | + * @todo Write validation | ||
13 | + * @property ActiveRecord $owner | ||
14 | + * @property ActiveRecord $image | ||
15 | + * @property ActiveRecord[] $images | ||
16 | + * @package common\behaviors | ||
17 | + */ | ||
18 | + class MultipleImgBehavior extends Behavior | ||
19 | + { | ||
20 | + | ||
21 | + /** | ||
22 | + * key - $model foreign key, value - $owner link key (usual ID) | ||
23 | + * @var array | ||
24 | + */ | ||
25 | + public $links = []; | ||
26 | + | ||
27 | + /** | ||
28 | + * Full namespaced image model | ||
29 | + * @var string | ||
30 | + */ | ||
31 | + public $model; | ||
32 | + | ||
33 | + /** | ||
34 | + * Image config array: | ||
35 | + * 'caption' - $model caption attribute | ||
36 | + * 'delete_action' - url to image delete action, will be passed as first argument to | ||
37 | + * Url::to(); | ||
38 | + * 'id' - $model primary key | ||
39 | + * @var array | ||
40 | + */ | ||
41 | + public $config = []; | ||
42 | + | ||
43 | + /** | ||
44 | + * One image query | ||
45 | + * | ||
46 | + * @return \yii\db\ActiveQuery | ||
47 | + */ | ||
48 | + public function getImage() | ||
49 | + { | ||
50 | + /** | ||
51 | + * @var ActiveRecord $owner | ||
52 | + */ | ||
53 | + $owner = $this->owner; | ||
54 | + return $owner->hasOne($this->model, $this->links); | ||
55 | + } | ||
56 | + | ||
57 | + /** | ||
58 | + * All images query | ||
59 | + * | ||
60 | + * @return \yii\db\ActiveQuery | ||
61 | + */ | ||
62 | + public function getImages() | ||
63 | + { | ||
64 | + /** | ||
65 | + * @var ActiveRecord $owner | ||
66 | + */ | ||
67 | + $owner = $this->owner; | ||
68 | + return $owner->hasMany($this->model, $this->links); | ||
69 | + } | ||
70 | + | ||
71 | + /** | ||
72 | + * Get images config array for FileInput | ||
73 | + * | ||
74 | + * @return array | ||
75 | + */ | ||
76 | + public function getImagesConfig() | ||
77 | + { | ||
78 | + $op = []; | ||
79 | + $images = $this->getImages()->all(); | ||
80 | + $config = $this->config; | ||
81 | + if(!isset( $config[ 'id' ] )) { | ||
82 | + return $op; | ||
83 | + } | ||
84 | + foreach($images as $image) { | ||
85 | + $op[] = [ | ||
86 | + 'caption' => ( isset( $config[ 'caption' ] ) ) ? $image->{$config[ 'caption' ]} : '', | ||
87 | + 'url' => ( isset( $config[ 'delete_action' ] ) ) ? Url::to([ | ||
88 | + $config[ 'delete_action' ], | ||
89 | + 'id' => $image->{$config[ 'id' ]}, | ||
90 | + ]) : '', | ||
91 | + 'key' => $image->{$config[ 'id' ]}, | ||
92 | + 'extra' => [ | ||
93 | + 'id' => $image->{$config[ 'id' ]}, | ||
94 | + ], | ||
95 | + ]; | ||
96 | + } | ||
97 | + return $op; | ||
98 | + } | ||
99 | + | ||
100 | + /** | ||
101 | + * Get images HTML | ||
102 | + * | ||
103 | + * @param string $preset | ||
104 | + * | ||
105 | + * @return array | ||
106 | + */ | ||
107 | + public function getImagesHTML($preset = 'admin_thumb') | ||
108 | + { | ||
109 | + $op = []; | ||
110 | + $images = $this->getImages()->all(); | ||
111 | + foreach($images as $image) { | ||
112 | + $op[] = ArtboxImageHelper::getImage($image->imageUrl, $preset); | ||
113 | + } | ||
114 | + return $op; | ||
115 | + } | ||
116 | + } | ||
0 | \ No newline at end of file | 117 | \ No newline at end of file |
common/behaviors/SaveImgBehavior.php
@@ -6,6 +6,7 @@ | @@ -6,6 +6,7 @@ | ||
6 | use yii\base\ModelEvent; | 6 | use yii\base\ModelEvent; |
7 | use yii\db\ActiveRecord; | 7 | use yii\db\ActiveRecord; |
8 | use yii\web\UploadedFile; | 8 | use yii\web\UploadedFile; |
9 | + | ||
9 | /** | 10 | /** |
10 | * Class Save Image Behavior | 11 | * Class Save Image Behavior |
11 | * @property ActiveRecord $owner | 12 | * @property ActiveRecord $owner |
@@ -15,6 +16,7 @@ | @@ -15,6 +16,7 @@ | ||
15 | { | 16 | { |
16 | 17 | ||
17 | public $fields; | 18 | public $fields; |
19 | + | ||
18 | public $is_language = false; | 20 | public $is_language = false; |
19 | 21 | ||
20 | public function events() | 22 | public function events() |
@@ -24,25 +26,26 @@ | @@ -24,25 +26,26 @@ | ||
24 | ActiveRecord::EVENT_BEFORE_INSERT => 'beforeSave', | 26 | ActiveRecord::EVENT_BEFORE_INSERT => 'beforeSave', |
25 | ]; | 27 | ]; |
26 | } | 28 | } |
27 | - | 29 | + |
28 | /** | 30 | /** |
29 | * @param ModelEvent $event | 31 | * @param ModelEvent $event |
30 | */ | 32 | */ |
31 | - public function beforeSave($event) { | ||
32 | - foreach($this->fields as $field){ | ||
33 | - $field_name = $field['name']; | 33 | + public function beforeSave($event) |
34 | + { | ||
35 | + foreach($this->fields as $field) { | ||
36 | + $field_name = $field[ 'name' ]; | ||
34 | $name = $field_name; | 37 | $name = $field_name; |
35 | if($this->is_language) { | 38 | if($this->is_language) { |
36 | - $name = '['.$this->owner->language_id.']'.$name; | 39 | + $name = '[' . $this->owner->language_id . ']' . $name; |
37 | } | 40 | } |
38 | - | 41 | + |
39 | $image = UploadedFile::getInstance($this->owner, $name); | 42 | $image = UploadedFile::getInstance($this->owner, $name); |
40 | 43 | ||
41 | - if(empty($image) && $event->name == ActiveRecord::EVENT_BEFORE_UPDATE) { | 44 | + if(empty( $image ) && $event->name == ActiveRecord::EVENT_BEFORE_UPDATE) { |
42 | $this->owner->$field_name = $this->owner->getOldAttribute($field_name); | 45 | $this->owner->$field_name = $this->owner->getOldAttribute($field_name); |
43 | - } elseif(!empty($image)) { | ||
44 | - $imgDir = \Yii::getAlias('@storage/'.$field['directory'].'/'); | ||
45 | - | 46 | + } elseif(!empty( $image )) { |
47 | + $imgDir = \Yii::getAlias('@storage/' . $field[ 'directory' ] . '/'); | ||
48 | + | ||
46 | if(!is_dir($imgDir)) { | 49 | if(!is_dir($imgDir)) { |
47 | mkdir($imgDir, 0755, true); | 50 | mkdir($imgDir, 0755, true); |
48 | } | 51 | } |
@@ -50,28 +53,43 @@ | @@ -50,28 +53,43 @@ | ||
50 | $baseName = $image->baseName; | 53 | $baseName = $image->baseName; |
51 | 54 | ||
52 | $iteration = 0; | 55 | $iteration = 0; |
53 | - $file_name = $imgDir.$baseName.'.'.$image->extension; | 56 | + $file_name = $imgDir . $baseName . '.' . $image->extension; |
54 | while(file_exists($file_name)) { | 57 | while(file_exists($file_name)) { |
55 | - $baseName = $image->baseName.'_'.++$iteration; | ||
56 | - $file_name = $imgDir.$baseName.'.'.$image->extension; | 58 | + $baseName = $image->baseName . '_' . ++$iteration; |
59 | + $file_name = $imgDir . $baseName . '.' . $image->extension; | ||
57 | } | 60 | } |
58 | - unset($iteration); | 61 | + unset( $iteration ); |
59 | 62 | ||
60 | - $this->owner->$field_name = $baseName.'.'.$image->extension; | 63 | + $this->owner->$field_name = $baseName . '.' . $image->extension; |
61 | 64 | ||
62 | $image->saveAs($file_name); | 65 | $image->saveAs($file_name); |
63 | } | 66 | } |
64 | } | 67 | } |
65 | } | 68 | } |
66 | - | ||
67 | - public function getImageFile($image = 'image') { | ||
68 | - return empty($this->owner->$image) ? null : '/storage/'.$this->fields[0]['directory'].'/'. $this->owner->$image; | ||
69 | - } | ||
70 | 69 | ||
71 | - public function getImageUrl($image = 'image') { | ||
72 | - return empty($this->owner->$image) ? null : '/storage/'.$this->fields[0]['directory'].'/'. $this->owner->$image; | 70 | + /** |
71 | + * @param int $field | ||
72 | + * | ||
73 | + * @return null|string | ||
74 | + */ | ||
75 | + public function getImageFile($field = 0) | ||
76 | + { | ||
77 | + $fieldset = $this->fields[ $field ]; | ||
78 | + $name = $fieldset[ 'name' ]; | ||
79 | + $directory = $fieldset[ 'directory' ]; | ||
80 | + return empty( $this->owner->$name ) ? NULL : '/storage/' . $directory . '/' . $this->owner->$name; | ||
73 | } | 81 | } |
74 | 82 | ||
75 | - | ||
76 | - | 83 | + /** |
84 | + * @param int $field | ||
85 | + * | ||
86 | + * @return null|string | ||
87 | + */ | ||
88 | + public function getImageUrl($field = 0) | ||
89 | + { | ||
90 | + $fieldset = $this->fields[ $field ]; | ||
91 | + $name = $fieldset[ 'name' ]; | ||
92 | + $directory = $fieldset[ 'directory' ]; | ||
93 | + return empty( $this->owner->$name ) ? NULL : '/storage/' . $directory . '/' . $this->owner->$name; | ||
94 | + } | ||
77 | } | 95 | } |
78 | \ No newline at end of file | 96 | \ No newline at end of file |
1 | +<?php | ||
2 | + | ||
3 | + namespace common\behaviors; | ||
4 | + | ||
5 | + use yii\base\Behavior; | ||
6 | + use yii\base\Event; | ||
7 | + use yii\db\ActiveRecord; | ||
8 | + use yii\web\UploadedFile; | ||
9 | + | ||
10 | + /** | ||
11 | + * Class SaveMultipleFileBehavior | ||
12 | + * | ||
13 | + * @todo Write validators | ||
14 | + * | ||
15 | + * @package common\behaviors | ||
16 | + */ | ||
17 | + class SaveMultipleFileBehavior extends Behavior | ||
18 | + { | ||
19 | + | ||
20 | + /** | ||
21 | + * $owner attribute to write files | ||
22 | + * @var string | ||
23 | + */ | ||
24 | + public $name; | ||
25 | + | ||
26 | + /** | ||
27 | + * Directory to store files | ||
28 | + * @var string | ||
29 | + */ | ||
30 | + public $directory; | ||
31 | + | ||
32 | + /** | ||
33 | + * Column in $model where to store filename | ||
34 | + * @var string | ||
35 | + */ | ||
36 | + public $column; | ||
37 | + | ||
38 | + /** | ||
39 | + * key - owner link attribute (usual ID), value - $model link attribute | ||
40 | + * @var array | ||
41 | + */ | ||
42 | + public $links = []; | ||
43 | + | ||
44 | + /** | ||
45 | + * Full namespaced classname of file table | ||
46 | + * @var string | ||
47 | + */ | ||
48 | + public $model; | ||
49 | + | ||
50 | + public function events() | ||
51 | + { | ||
52 | + return [ | ||
53 | + ActiveRecord::EVENT_AFTER_UPDATE => 'downloadFiles', | ||
54 | + ActiveRecord::EVENT_AFTER_INSERT => 'downloadFiles', | ||
55 | + ]; | ||
56 | + } | ||
57 | + | ||
58 | + /** | ||
59 | + * Save files to file table | ||
60 | + * | ||
61 | + * @param Event $event | ||
62 | + */ | ||
63 | + public function downloadFiles($event) | ||
64 | + { | ||
65 | + /** | ||
66 | + * @var ActiveRecord $owner | ||
67 | + */ | ||
68 | + $owner = $this->owner; | ||
69 | + $name = $this->name; | ||
70 | + $owner->$name = UploadedFile::getInstances($owner, $name); | ||
71 | + if(!empty( $files = $this->filesUpload() )) { | ||
72 | + $model = $this->model; | ||
73 | + $links = $this->links; | ||
74 | + $column = $this->column; | ||
75 | + foreach($files as $file) { | ||
76 | + /** | ||
77 | + * @var ActiveRecord $fileModel | ||
78 | + */ | ||
79 | + $fileModel = new $model(); | ||
80 | + foreach($links as $link_owner => $link) { | ||
81 | + $fileModel->$link = $owner->$link_owner; | ||
82 | + } | ||
83 | + $fileModel->$column = $file; | ||
84 | + $fileModel->save(); | ||
85 | + } | ||
86 | + } | ||
87 | + $this->detach(); | ||
88 | + } | ||
89 | + | ||
90 | + /** | ||
91 | + * Save files to file system | ||
92 | + * | ||
93 | + * @return array | ||
94 | + */ | ||
95 | + private function filesUpload() | ||
96 | + { | ||
97 | + $owner = $this->owner; | ||
98 | + $name = $this->name; | ||
99 | + $directory = $this->directory; | ||
100 | + $fileDir = \Yii::getAlias('@storage/' . $directory . '/'); | ||
101 | + if(!is_dir($fileDir)) { | ||
102 | + mkdir($fileDir, 0755, true); | ||
103 | + } | ||
104 | + $files = []; | ||
105 | + /** | ||
106 | + * @var UploadedFile $file | ||
107 | + */ | ||
108 | + foreach($owner->$name as $file) { | ||
109 | + $fileName = $file->baseName . '.' . $file->extension; | ||
110 | + $i = 0; | ||
111 | + while(file_exists(\Yii::getAlias($fileDir . $fileName))) { | ||
112 | + $fileName = $file->baseName . '_' . ++$i . '.' . $file->extension; | ||
113 | + } | ||
114 | + $file->saveAs($fileDir . $fileName); | ||
115 | + $files[] = $fileName; | ||
116 | + } | ||
117 | + return $files; | ||
118 | + } | ||
119 | + } | ||
0 | \ No newline at end of file | 120 | \ No newline at end of file |
common/models/Articles.php
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | namespace common\models; | 3 | namespace common\models; |
4 | - | ||
5 | - use common\modules\language\behaviors\TransactionBehavior; | 4 | + |
6 | use common\modules\language\behaviors\LanguageBehavior; | 5 | use common\modules\language\behaviors\LanguageBehavior; |
7 | use common\behaviors\SaveImgBehavior; | 6 | use common\behaviors\SaveImgBehavior; |
8 | use common\modules\comment\models\CommentModel; | 7 | use common\modules\comment\models\CommentModel; |
@@ -36,8 +35,14 @@ | @@ -36,8 +35,14 @@ | ||
36 | * @method bool saveLangs() | 35 | * @method bool saveLangs() |
37 | * @method bool getTransactionStatus() | 36 | * @method bool getTransactionStatus() |
38 | * * End language behavior * | 37 | * * End language behavior * |
38 | + * * From SaveImgBehavior | ||
39 | + * @property string|null imageFile | ||
40 | + * @property string|null imageUrl | ||
41 | + * @method string|null getImageFile( int $field ) | ||
42 | + * @method string|null getImageUrl( int $field ) | ||
43 | + * * End SaveImgBehavior | ||
39 | */ | 44 | */ |
40 | - class Articles extends \yii\db\ActiveRecord | 45 | + class Articles extends ActiveRecord |
41 | { | 46 | { |
42 | 47 | ||
43 | /** | 48 | /** |
common/models/Project.php
@@ -2,6 +2,8 @@ | @@ -2,6 +2,8 @@ | ||
2 | 2 | ||
3 | namespace common\models; | 3 | namespace common\models; |
4 | 4 | ||
5 | + use common\behaviors\MultipleImgBehavior; | ||
6 | + use common\behaviors\SaveMultipleFileBehavior; | ||
5 | use common\modules\language\behaviors\LanguageBehavior; | 7 | use common\modules\language\behaviors\LanguageBehavior; |
6 | use common\modules\product\models\ProductVariant; | 8 | use common\modules\product\models\ProductVariant; |
7 | use Yii; | 9 | use Yii; |
@@ -11,13 +13,9 @@ | @@ -11,13 +13,9 @@ | ||
11 | 13 | ||
12 | /** | 14 | /** |
13 | * This is the model class for table "project". | 15 | * This is the model class for table "project". |
14 | - * | ||
15 | * @todo Refactor | 16 | * @todo Refactor |
16 | - * | ||
17 | * @property integer $project_id | 17 | * @property integer $project_id |
18 | * @property integer $date_add | 18 | * @property integer $date_add |
19 | - * @property ProjectImage[] $images | ||
20 | - * @property ProjectImage $image | ||
21 | * @property array $imagesConfig | 19 | * @property array $imagesConfig |
22 | * @property ProductVariant[] $variants | 20 | * @property ProductVariant[] $variants |
23 | * @property ProductToProject[] $productToProject | 21 | * @property ProductToProject[] $productToProject |
@@ -41,6 +39,14 @@ | @@ -41,6 +39,14 @@ | ||
41 | * @method bool saveLangs() | 39 | * @method bool saveLangs() |
42 | * @method bool getTransactionStatus() | 40 | * @method bool getTransactionStatus() |
43 | * * End language behavior * | 41 | * * End language behavior * |
42 | + * * From multipleImage behavior | ||
43 | + * @property ProjectImage $image | ||
44 | + * @property ProjectImage[] $images | ||
45 | + * @method ActiveQuery getImage() | ||
46 | + * @method ActiveQuery getImages() | ||
47 | + * @method array getImagesConfig() | ||
48 | + * @method array getImagesHTML( string $preset ) | ||
49 | + * * End multipleImage behavior | ||
44 | */ | 50 | */ |
45 | class Project extends ActiveRecord | 51 | class Project extends ActiveRecord |
46 | { | 52 | { |
@@ -61,9 +67,31 @@ | @@ -61,9 +67,31 @@ | ||
61 | public function behaviors() | 67 | public function behaviors() |
62 | { | 68 | { |
63 | return [ | 69 | return [ |
64 | - 'language' => [ | 70 | + 'language' => [ |
65 | 'class' => LanguageBehavior::className(), | 71 | 'class' => LanguageBehavior::className(), |
66 | ], | 72 | ], |
73 | + 'images' => [ | ||
74 | + 'class' => SaveMultipleFileBehavior::className(), | ||
75 | + 'name' => 'imagesUpload', | ||
76 | + 'directory' => 'projects', | ||
77 | + 'column' => 'image', | ||
78 | + 'links' => [ | ||
79 | + 'project_id' => 'project_id', | ||
80 | + ], | ||
81 | + 'model' => ProjectImage::className(), | ||
82 | + ], | ||
83 | + 'multipleImage' => [ | ||
84 | + 'class' => MultipleImgBehavior::className(), | ||
85 | + 'links' => [ | ||
86 | + 'project_id' => 'project_id', | ||
87 | + ], | ||
88 | + 'model' => ProjectImage::className(), | ||
89 | + 'config' => [ | ||
90 | + 'caption' => 'image', | ||
91 | + 'delete_action' => '/project/delimg', | ||
92 | + 'id' => 'project_image_id', | ||
93 | + ], | ||
94 | + ], | ||
67 | ]; | 95 | ]; |
68 | } | 96 | } |
69 | 97 | ||
@@ -112,74 +140,6 @@ | @@ -112,74 +140,6 @@ | ||
112 | ]; | 140 | ]; |
113 | } | 141 | } |
114 | 142 | ||
115 | - public function getImages() | ||
116 | - { | ||
117 | - return $this->hasMany(ProjectImage::className(), [ 'project_id' => 'project_id' ]); | ||
118 | - } | ||
119 | - | ||
120 | - public function getImage() | ||
121 | - { | ||
122 | - return $this->hasOne(ProjectImage::className(), [ 'project_id' => 'project_id' ]); | ||
123 | - } | ||
124 | - | ||
125 | - public function getImagesHTML() | ||
126 | - { | ||
127 | - $op = []; | ||
128 | - if($this->images) { | ||
129 | - foreach($this->images as $image) { | ||
130 | - $op[] = \common\components\artboximage\ArtboxImageHelper::getImage($image->imageUrl, 'admin_thumb'); | ||
131 | - } | ||
132 | - } | ||
133 | - return $op; | ||
134 | - } | ||
135 | - | ||
136 | - public function getImagesConfig() | ||
137 | - { | ||
138 | - $op = []; | ||
139 | - if($this->images) { | ||
140 | - foreach($this->images as $image) { | ||
141 | - $op[] = [ | ||
142 | - 'caption' => $image->image, | ||
143 | - 'width' => '120px', | ||
144 | - 'url' => \yii\helpers\Url::to([ | ||
145 | - '/project/delimg', | ||
146 | - 'id' => $image->project_image_id, | ||
147 | - ]), | ||
148 | - 'key' => $image->project_image_id, | ||
149 | - 'extra' => [ | ||
150 | - 'id' => $image->project_image_id, | ||
151 | - ], | ||
152 | - ]; | ||
153 | - } | ||
154 | - } | ||
155 | - return $op; | ||
156 | - } | ||
157 | - | ||
158 | - public function imagesUpload() | ||
159 | - { | ||
160 | - if($this->validate()) { | ||
161 | - $images = []; | ||
162 | - foreach($this->imagesUpload as $image) { | ||
163 | - $imageName = $image->baseName . '.' . $image->extension; | ||
164 | - $i = 0; | ||
165 | - while(file_exists(\Yii::getAlias('@storage/projects/' . $imageName))) { | ||
166 | - $i++; | ||
167 | - $imageName = $image->baseName . '_' . $i . '.' . $image->extension; | ||
168 | - } | ||
169 | - $imgDir = \Yii::getAlias('@storage/projects/'); | ||
170 | - if(!is_dir($imgDir)) { | ||
171 | - mkdir($imgDir, 0755, true); | ||
172 | - } | ||
173 | - | ||
174 | - $image->saveAs($imgDir . $imageName); | ||
175 | - $images[] = $imageName; | ||
176 | - } | ||
177 | - return $images; | ||
178 | - } else { | ||
179 | - return false; | ||
180 | - } | ||
181 | - } | ||
182 | - | ||
183 | public function getProductToProject() | 143 | public function getProductToProject() |
184 | { | 144 | { |
185 | return $this->hasMany(ProductToProject::className(), [ | 145 | return $this->hasMany(ProductToProject::className(), [ |
common/modules/product/controllers/ManageController.php
@@ -8,7 +8,6 @@ | @@ -8,7 +8,6 @@ | ||
8 | use common\modules\product\models\Export; | 8 | use common\modules\product\models\Export; |
9 | use common\modules\product\models\Import; | 9 | use common\modules\product\models\Import; |
10 | use common\modules\product\models\ProductImage; | 10 | use common\modules\product\models\ProductImage; |
11 | - use common\modules\product\models\ProductVariant; | ||
12 | use Yii; | 11 | use Yii; |
13 | use common\modules\product\models\Product; | 12 | use common\modules\product\models\Product; |
14 | use common\modules\product\models\ProductSearch; | 13 | use common\modules\product\models\ProductSearch; |
@@ -38,22 +37,6 @@ | @@ -38,22 +37,6 @@ | ||
38 | ]; | 37 | ]; |
39 | } | 38 | } |
40 | 39 | ||
41 | - public function actionDev() | ||
42 | - { | ||
43 | - foreach(ProductVariant::find() | ||
44 | - ->where([ | ||
45 | - '>', | ||
46 | - 'price_old', | ||
47 | - 0, | ||
48 | - ]) | ||
49 | - ->all() as $item) { | ||
50 | - if($item->price >= $item->price_old || $item->price == 0) { | ||
51 | - print $item->price . ' | ' . $item->price_old . "<br>\n"; | ||
52 | - } | ||
53 | - } | ||
54 | - print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'; | ||
55 | - } | ||
56 | - | ||
57 | /** | 40 | /** |
58 | * Lists all Product models. | 41 | * Lists all Product models. |
59 | * @return mixed | 42 | * @return mixed |
@@ -92,36 +75,11 @@ | @@ -92,36 +75,11 @@ | ||
92 | { | 75 | { |
93 | $model = new Product(); | 76 | $model = new Product(); |
94 | $model->generateLangs(); | 77 | $model->generateLangs(); |
95 | - | ||
96 | $product_spec = new ProductSpec(); | 78 | $product_spec = new ProductSpec(); |
97 | $product_spec->generateLangs(); | 79 | $product_spec->generateLangs(); |
98 | - | ||
99 | if($model->load(Yii::$app->request->post())) { | 80 | if($model->load(Yii::$app->request->post())) { |
100 | $model->loadLangs(\Yii::$app->request); | 81 | $model->loadLangs(\Yii::$app->request); |
101 | - $model->imagesUpload = UploadedFile::getInstances($model, 'imagesUpload'); | ||
102 | - $model->certificateUpload = UploadedFile::getInstances($model, 'certificateUpload'); | ||
103 | - | ||
104 | if($model->save() && $model->transactionStatus) { | 82 | if($model->save() && $model->transactionStatus) { |
105 | - | ||
106 | - if(!empty( $model->imagesUpload ) && ( ( $images = $model->imagesUpload() ) !== false )) { | ||
107 | - foreach($images as $image) { | ||
108 | - $imageModel = new ProductImage(); | ||
109 | - $imageModel->product_id = $model->product_id; | ||
110 | - $imageModel->image = $image; | ||
111 | - $imageModel->save(); | ||
112 | - } | ||
113 | - } | ||
114 | - | ||
115 | - if(!empty( $model->certificateUpload ) && ( ( $certificates = $model->certificateUpload() ) !== false )) { | ||
116 | - foreach($certificates as $certificate) { | ||
117 | - $certificateModel = new ProductCertificate([ | ||
118 | - 'product_id' => $model->product_id, | ||
119 | - 'link' => $certificate, | ||
120 | - ]); | ||
121 | - $certificateModel->save(false); | ||
122 | - } | ||
123 | - } | ||
124 | - | ||
125 | if($product_spec->load(Yii::$app->request->post())) { | 83 | if($product_spec->load(Yii::$app->request->post())) { |
126 | $product_spec->loadLangs(\Yii::$app->request); | 84 | $product_spec->loadLangs(\Yii::$app->request); |
127 | $product_spec->product_id = $model->product_id; | 85 | $product_spec->product_id = $model->product_id; |
@@ -168,26 +126,7 @@ | @@ -168,26 +126,7 @@ | ||
168 | $product_spec->generateLangs(); | 126 | $product_spec->generateLangs(); |
169 | if($model->load(Yii::$app->request->post())) { | 127 | if($model->load(Yii::$app->request->post())) { |
170 | $model->loadLangs(\Yii::$app->request); | 128 | $model->loadLangs(\Yii::$app->request); |
171 | - $model->imagesUpload = UploadedFile::getInstances($model, 'imagesUpload'); | ||
172 | - $model->certificateUpload = UploadedFile::getInstances($model, 'certificateUpload'); | ||
173 | if($model->save() && $model->transactionStatus) { | 129 | if($model->save() && $model->transactionStatus) { |
174 | - if(!empty( $model->imagesUpload ) && ( ( $images = $model->imagesUpload() ) !== false )) { | ||
175 | - foreach($images as $image) { | ||
176 | - $imageModel = new ProductImage(); | ||
177 | - $imageModel->product_id = $model->product_id; | ||
178 | - $imageModel->image = $image; | ||
179 | - $imageModel->save(); | ||
180 | - } | ||
181 | - } | ||
182 | - if(!empty( $model->certificateUpload ) && ( ( $certificates = $model->certificateUpload() ) !== false )) { | ||
183 | - foreach($certificates as $certificate) { | ||
184 | - $certificateModel = new ProductCertificate([ | ||
185 | - 'product_id' => $model->product_id, | ||
186 | - 'link' => $certificate, | ||
187 | - ]); | ||
188 | - $certificateModel->save(false); | ||
189 | - } | ||
190 | - } | ||
191 | if($product_spec->load(Yii::$app->request->post())) { | 130 | if($product_spec->load(Yii::$app->request->post())) { |
192 | $product_spec->loadLangs(\Yii::$app->request); | 131 | $product_spec->loadLangs(\Yii::$app->request); |
193 | $product_spec->techSpecFile = UploadedFile::getInstance($product_spec, 'techSpecFile'); | 132 | $product_spec->techSpecFile = UploadedFile::getInstance($product_spec, 'techSpecFile'); |
@@ -225,7 +164,6 @@ | @@ -225,7 +164,6 @@ | ||
225 | { | 164 | { |
226 | $this->findModel($id) | 165 | $this->findModel($id) |
227 | ->delete(); | 166 | ->delete(); |
228 | - | ||
229 | return $this->redirect([ 'index' ]); | 167 | return $this->redirect([ 'index' ]); |
230 | } | 168 | } |
231 | 169 |
common/modules/product/controllers/VariantController.php
@@ -9,11 +9,9 @@ | @@ -9,11 +9,9 @@ | ||
9 | use common\modules\product\models\ProductVariantListSearch; | 9 | use common\modules\product\models\ProductVariantListSearch; |
10 | use common\modules\product\models\Stock; | 10 | use common\modules\product\models\Stock; |
11 | use Yii; | 11 | use Yii; |
12 | - use yii\helpers\ArrayHelper; | ||
13 | use yii\web\Controller; | 12 | use yii\web\Controller; |
14 | use yii\web\NotFoundHttpException; | 13 | use yii\web\NotFoundHttpException; |
15 | use yii\filters\VerbFilter; | 14 | use yii\filters\VerbFilter; |
16 | - use yii\web\UploadedFile; | ||
17 | 15 | ||
18 | /** | 16 | /** |
19 | * ManageController implements the CRUD actions for ProductVariant model. | 17 | * ManageController implements the CRUD actions for ProductVariant model. |
@@ -83,30 +81,7 @@ | @@ -83,30 +81,7 @@ | ||
83 | $model->generateLangs(); | 81 | $model->generateLangs(); |
84 | if($model->load(Yii::$app->request->post())) { | 82 | if($model->load(Yii::$app->request->post())) { |
85 | $model->loadLangs(\Yii::$app->request); | 83 | $model->loadLangs(\Yii::$app->request); |
86 | - $model->imagesUpload = UploadedFile::getInstances($model, 'imagesUpload'); | ||
87 | if($model->save() && $model->transactionStatus) { | 84 | if($model->save() && $model->transactionStatus) { |
88 | - if(( $image = UploadedFile::getInstance($model, 'image') )) { | ||
89 | - $imageModel = ProductImage::find() | ||
90 | - ->where([ 'product_variant_id' => $model->product_variant_id ]) | ||
91 | - ->one(); | ||
92 | - if($imageModel instanceof ProductImage) { | ||
93 | - $imageModel->product_id = $model->product_id; | ||
94 | - $imageModel->product_variant_id = $model->product_variant_id; | ||
95 | - $imageModel->image = $image->name; | ||
96 | - $imageModel->save(); | ||
97 | - } else { | ||
98 | - $imageModel = new ProductImage(); | ||
99 | - $imageModel->product_id = $model->product_id; | ||
100 | - $imageModel->product_variant_id = $model->product_variant_id; | ||
101 | - $imageModel->image = $image->name; | ||
102 | - $imageModel->save(); | ||
103 | - } | ||
104 | - $imgDir = Yii::getAlias('@storage/products/'); | ||
105 | - if(!is_dir($imgDir)) { | ||
106 | - mkdir($imgDir, 0755, true); | ||
107 | - } | ||
108 | - $image->saveAs(Yii::getAlias('@storage/products/' . $image->name)); | ||
109 | - } | ||
110 | $ProductStocks = Yii::$app->request->post('ProductStock'); | 85 | $ProductStocks = Yii::$app->request->post('ProductStock'); |
111 | $total_quantity = 0; | 86 | $total_quantity = 0; |
112 | if(!empty( $ProductStocks ) && is_array($ProductStocks)) { | 87 | if(!empty( $ProductStocks ) && is_array($ProductStocks)) { |
@@ -187,28 +162,6 @@ | @@ -187,28 +162,6 @@ | ||
187 | if($model->load(Yii::$app->request->post())) { | 162 | if($model->load(Yii::$app->request->post())) { |
188 | $model->loadLangs(\Yii::$app->request); | 163 | $model->loadLangs(\Yii::$app->request); |
189 | if($model->save() && $model->transactionStatus) { | 164 | if($model->save() && $model->transactionStatus) { |
190 | - if(( $image = UploadedFile::getInstance($model, 'image') )) { | ||
191 | - $imageModel = ProductImage::find() | ||
192 | - ->where([ 'product_variant_id' => $model->product_variant_id ]) | ||
193 | - ->one(); | ||
194 | - if($imageModel instanceof ProductImage) { | ||
195 | - $imageModel->product_id = $model->product_id; | ||
196 | - $imageModel->product_variant_id = $model->product_variant_id; | ||
197 | - $imageModel->image = $image->name; | ||
198 | - $imageModel->save(); | ||
199 | - } else { | ||
200 | - $imageModel = new ProductImage(); | ||
201 | - $imageModel->product_id = $model->product_id; | ||
202 | - $imageModel->product_variant_id = $model->product_variant_id; | ||
203 | - $imageModel->image = $image->name; | ||
204 | - $imageModel->save(); | ||
205 | - } | ||
206 | - $imgDir = Yii::getAlias('@storage/products/'); | ||
207 | - if(!is_dir($imgDir)) { | ||
208 | - mkdir($imgDir, 0755, true); | ||
209 | - } | ||
210 | - $image->saveAs(Yii::getAlias('@storage/products/' . $image->name)); | ||
211 | - } | ||
212 | $ProductStocks = Yii::$app->request->post('ProductStock'); | 165 | $ProductStocks = Yii::$app->request->post('ProductStock'); |
213 | $total_quantity = 0; | 166 | $total_quantity = 0; |
214 | if(!empty( $ProductStocks ) && is_array($ProductStocks)) { | 167 | if(!empty( $ProductStocks ) && is_array($ProductStocks)) { |
common/modules/product/models/Export.php
@@ -50,7 +50,7 @@ | @@ -50,7 +50,7 @@ | ||
50 | * @var Product[] $products | 50 | * @var Product[] $products |
51 | */ | 51 | */ |
52 | $products = Product::find() | 52 | $products = Product::find() |
53 | - ->with('variantsWithFilters', 'brand.lang', 'categories.lang', 'filters') | 53 | + ->with('variantsWithFilters', 'brand.lang', 'categories.lang', 'filters', 'images') |
54 | ->joinWith('lang', true, 'INNER JOIN') | 54 | ->joinWith('lang', true, 'INNER JOIN') |
55 | ->limit($limit) | 55 | ->limit($limit) |
56 | ->offset($from) | 56 | ->offset($from) |
@@ -71,6 +71,9 @@ | @@ -71,6 +71,9 @@ | ||
71 | } | 71 | } |
72 | 72 | ||
73 | $fotos = []; | 73 | $fotos = []; |
74 | + foreach($product->images as $image) { | ||
75 | + $fotos[] = $image->image; | ||
76 | + } | ||
74 | 77 | ||
75 | $categories = []; | 78 | $categories = []; |
76 | foreach($product->categories as $value) { | 79 | foreach($product->categories as $value) { |
@@ -80,20 +83,20 @@ | @@ -80,20 +83,20 @@ | ||
80 | $categories = implode(',', $categories); | 83 | $categories = implode(',', $categories); |
81 | 84 | ||
82 | $list = [ | 85 | $list = [ |
83 | - $categories, | ||
84 | - ( ( !empty( $product->brand ) ) ? $product->brand->lang->name.$this->generateID($product->brand->remote_id) : '' ), | ||
85 | - $product->lang->name.$this->generateID($product->remote_id), | ||
86 | - '', | ||
87 | - ( ( !empty( $product->lang->description ) ) ? $product->lang->description : '' ), | ||
88 | - $filterString, | ||
89 | - ( !empty( $product->variant ) ) ? $product->variant->price_old : '', | ||
90 | - ( !empty( $product->variant ) ) ? $product->variant->price : '', | ||
91 | - intval($product->akciya), | ||
92 | - '', | ||
93 | - intval($product->is_new), | ||
94 | - intval($product->is_top), | ||
95 | - $product->video, | ||
96 | - implode(',', $fotos), | 86 | + $categories, //A - категории через запятую Название(remote_id) |
87 | + ( ( !empty( $product->brand ) ) ? $product->brand->lang->name.$this->generateID($product->brand->remote_id) : '' ), //B - бренд Название(remote_id) | ||
88 | + $product->lang->name.$this->generateID($product->remote_id), //C - название товара Название(remote_id) | ||
89 | + ( ( !empty( $product->lang->description ) ) ? $product->lang->description : '' ), //D - описание товара Описание(remote_id) | ||
90 | + $filterString, //E - характеристики товара. Структура: [Группа1(remote_id):Характеристика11(remote_id),Характеристика12(remote_id)]*[Группа2(remote_id):Характеристика21(remote_id),Характеристика22(remote_id)] | ||
91 | + ( !empty( $product->variant ) ) ? $product->variant->price_old : '', //F - страрая цена | ||
92 | + ( !empty( $product->variant ) ) ? $product->variant->price : '', //G - новая цена | ||
93 | + intval($product->akciya), //H - товар акционный (1/0) | ||
94 | + '', //I - пустой | ||
95 | + intval($product->is_new), //J - товар новинка | ||
96 | + intval($product->is_top), //K - товар в топе | ||
97 | + $product->video, //L - ссылка на видео (iframe) | ||
98 | + implode(',', $fotos), //M - название файлов через запятую, картинки должны хранится в /storage/sync/product_images | ||
99 | + // Все последующие модификации: SKU(remote_id)=[Группа1(remote_id):Характеристика11(remote_id),Характеристика12(remote_id)]*[Группа2(remote_id):Характеристика21(remote_id),Характеристика22(remote_id)]=Название=Изображение=Остаток | ||
97 | ]; | 100 | ]; |
98 | $to_write = array_merge($list, $mods); | 101 | $to_write = array_merge($list, $mods); |
99 | fputcsv($handle, $to_write, ';'); | 102 | fputcsv($handle, $to_write, ';'); |
common/modules/product/models/Import.php
@@ -316,6 +316,10 @@ | @@ -316,6 +316,10 @@ | ||
316 | { | 316 | { |
317 | if(!empty( $fotos )) { | 317 | if(!empty( $fotos )) { |
318 | foreach($fotos as $foto) { | 318 | foreach($fotos as $foto) { |
319 | + | ||
320 | + if(empty($foto)){ | ||
321 | + continue; | ||
322 | + } | ||
319 | $source_image = Yii::getAlias('@uploadDir') . '/product_images/' . urlencode($foto); | 323 | $source_image = Yii::getAlias('@uploadDir') . '/product_images/' . urlencode($foto); |
320 | if(file_exists($source_image)) { | 324 | if(file_exists($source_image)) { |
321 | if(( $productImage = ProductImage::find() | 325 | if(( $productImage = ProductImage::find() |
@@ -410,7 +414,6 @@ | @@ -410,7 +414,6 @@ | ||
410 | $_productVariant->save(false); | 414 | $_productVariant->save(false); |
411 | 415 | ||
412 | $MOD_ARRAY[] = $_productVariant->product_variant_id; | 416 | $MOD_ARRAY[] = $_productVariant->product_variant_id; |
413 | - | ||
414 | $this->saveFotos([ $mod_image ], $product_id, $_productVariant->product_variant_id); | 417 | $this->saveFotos([ $mod_image ], $product_id, $_productVariant->product_variant_id); |
415 | } | 418 | } |
416 | } | 419 | } |
@@ -444,6 +447,8 @@ | @@ -444,6 +447,8 @@ | ||
444 | 447 | ||
445 | while(( empty( $limit ) || $j++ < $limit ) && ( $data = fgetcsv($handle, 10000, ";") ) !== false) { | 448 | while(( empty( $limit ) || $j++ < $limit ) && ( $data = fgetcsv($handle, 10000, ";") ) !== false) { |
446 | try { | 449 | try { |
450 | + | ||
451 | + | ||
447 | foreach($data as &$value) { | 452 | foreach($data as &$value) { |
448 | if(!$is_utf) { | 453 | if(!$is_utf) { |
449 | $value = iconv('windows-1251', "UTF-8//TRANSLIT//IGNORE", $value); | 454 | $value = iconv('windows-1251', "UTF-8//TRANSLIT//IGNORE", $value); |
@@ -528,7 +533,6 @@ | @@ -528,7 +533,6 @@ | ||
528 | 533 | ||
529 | $options = []; | 534 | $options = []; |
530 | if(!empty ( $filters )) { | 535 | if(!empty ( $filters )) { |
531 | - | ||
532 | $options = $this->saveFilters($filters, 0, $categories); | 536 | $options = $this->saveFilters($filters, 0, $categories); |
533 | } | 537 | } |
534 | $parsed_name = $this->parseName($product_name); | 538 | $parsed_name = $this->parseName($product_name); |
common/modules/product/models/Product.php
@@ -2,6 +2,8 @@ | @@ -2,6 +2,8 @@ | ||
2 | 2 | ||
3 | namespace common\modules\product\models; | 3 | namespace common\modules\product\models; |
4 | 4 | ||
5 | + use common\behaviors\MultipleImgBehavior; | ||
6 | + use common\behaviors\SaveMultipleFileBehavior; | ||
5 | use common\models\ProductCertificate; | 7 | use common\models\ProductCertificate; |
6 | use common\models\ProductSpec; | 8 | use common\models\ProductSpec; |
7 | use common\models\ProductToRating; | 9 | use common\models\ProductToRating; |
@@ -24,8 +26,6 @@ | @@ -24,8 +26,6 @@ | ||
24 | * @property Category[] $categories | 26 | * @property Category[] $categories |
25 | * @property ProductVariant[] $variants | 27 | * @property ProductVariant[] $variants |
26 | * @property ProductVariant $variant | 28 | * @property ProductVariant $variant |
27 | - * @property ProductImage $image | ||
28 | - * @property ProductImage[] $images | ||
29 | * @property boolean $is_top | 29 | * @property boolean $is_top |
30 | * @property boolean $is_new | 30 | * @property boolean $is_new |
31 | * @property boolean $akciya | 31 | * @property boolean $akciya |
@@ -39,25 +39,33 @@ | @@ -39,25 +39,33 @@ | ||
39 | * @property ProductSpec $productSpec | 39 | * @property ProductSpec $productSpec |
40 | * @property ProductCertificate[] $productCertificates | 40 | * @property ProductCertificate[] $productCertificates |
41 | * * From language behavior * | 41 | * * From language behavior * |
42 | - * @property ProductLang $lang | ||
43 | - * @property ProductLang[] $langs | ||
44 | - * @property ProductLang $object_lang | ||
45 | - * @property string $ownerKey | ||
46 | - * @property string $langKey | ||
47 | - * @property ProductLang[] $model_langs | ||
48 | - * @property bool $transactionStatus | 42 | + * @property ProductLang $lang |
43 | + * @property ProductLang[] $langs | ||
44 | + * @property ProductLang $object_lang | ||
45 | + * @property string $ownerKey | ||
46 | + * @property string $langKey | ||
47 | + * @property ProductLang[] $model_langs | ||
48 | + * @property bool $transactionStatus | ||
49 | * @method string getOwnerKey() | 49 | * @method string getOwnerKey() |
50 | - * @method void setOwnerKey(string $value) | 50 | + * @method void setOwnerKey( string $value ) |
51 | * @method string getLangKey() | 51 | * @method string getLangKey() |
52 | - * @method void setLangKey(string $value) | 52 | + * @method void setLangKey( string $value ) |
53 | * @method ActiveQuery getLangs() | 53 | * @method ActiveQuery getLangs() |
54 | * @method ActiveQuery getLang( integer $language_id ) | 54 | * @method ActiveQuery getLang( integer $language_id ) |
55 | * @method ProductLang[] generateLangs() | 55 | * @method ProductLang[] generateLangs() |
56 | - * @method void loadLangs(Request $request) | 56 | + * @method void loadLangs( Request $request ) |
57 | * @method bool linkLangs() | 57 | * @method bool linkLangs() |
58 | * @method bool saveLangs() | 58 | * @method bool saveLangs() |
59 | * @method bool getTransactionStatus() | 59 | * @method bool getTransactionStatus() |
60 | * * End language behavior * | 60 | * * End language behavior * |
61 | + * * From multipleImage behavior | ||
62 | + * @property ProductImage $image | ||
63 | + * @property ProductImage[] $images | ||
64 | + * @method ActiveQuery getImage() | ||
65 | + * @method ActiveQuery getImages() | ||
66 | + * @method array getImagesConfig() | ||
67 | + * @method array getImagesHTML( string $preset ) | ||
68 | + * * End multipleImage behavior | ||
61 | */ | 69 | */ |
62 | class Product extends \yii\db\ActiveRecord | 70 | class Product extends \yii\db\ActiveRecord |
63 | { | 71 | { |
@@ -65,8 +73,7 @@ | @@ -65,8 +73,7 @@ | ||
65 | /** @var array $_variants */ | 73 | /** @var array $_variants */ |
66 | public $_variants = []; | 74 | public $_variants = []; |
67 | 75 | ||
68 | - /** @var array $_images */ | ||
69 | - public $imagesUpload = ''; | 76 | + public $imagesUpload = []; |
70 | 77 | ||
71 | public $certificateUpload = []; | 78 | public $certificateUpload = []; |
72 | 79 | ||
@@ -76,10 +83,42 @@ | @@ -76,10 +83,42 @@ | ||
76 | public function behaviors() | 83 | public function behaviors() |
77 | { | 84 | { |
78 | return [ | 85 | return [ |
86 | + 'images' => [ | ||
87 | + 'class' => SaveMultipleFileBehavior::className(), | ||
88 | + 'name' => 'imagesUpload', | ||
89 | + 'directory' => 'products', | ||
90 | + 'column' => 'image', | ||
91 | + 'links' => [ | ||
92 | + 'product_id' => 'product_id', | ||
93 | + ], | ||
94 | + 'model' => ProductImage::className(), | ||
95 | + ], | ||
96 | + 'certificates' => [ | ||
97 | + 'class' => SaveMultipleFileBehavior::className(), | ||
98 | + 'name' => 'certificateUpload', | ||
99 | + 'directory' => 'certificates', | ||
100 | + 'column' => 'link', | ||
101 | + 'links' => [ | ||
102 | + 'product_id' => 'product_id', | ||
103 | + ], | ||
104 | + 'model' => ProductCertificate::className(), | ||
105 | + ], | ||
106 | + 'multipleImage' => [ | ||
107 | + 'class' => MultipleImgBehavior::className(), | ||
108 | + 'links' => [ | ||
109 | + 'product_id' => 'product_id', | ||
110 | + ], | ||
111 | + 'model' => ProductImage::className(), | ||
112 | + 'config' => [ | ||
113 | + 'caption' => 'image', | ||
114 | + 'delete_action' => '/product/manage/delimg', | ||
115 | + 'id' => 'product_image_id', | ||
116 | + ], | ||
117 | + ], | ||
79 | [ | 118 | [ |
80 | 'class' => FilterBehavior::className(), | 119 | 'class' => FilterBehavior::className(), |
81 | ], | 120 | ], |
82 | - 'language' => [ | 121 | + 'language' => [ |
83 | 'class' => LanguageBehavior::className(), | 122 | 'class' => LanguageBehavior::className(), |
84 | ], | 123 | ], |
85 | ]; | 124 | ]; |
@@ -159,33 +198,6 @@ | @@ -159,33 +198,6 @@ | ||
159 | { | 198 | { |
160 | return $this->hasOne(Brand::className(), [ 'brand_id' => 'brand_id' ]); | 199 | return $this->hasOne(Brand::className(), [ 'brand_id' => 'brand_id' ]); |
161 | } | 200 | } |
162 | - | ||
163 | - /** | ||
164 | - * @return \yii\db\ActiveQuery | ||
165 | - */ | ||
166 | - public function getImage() | ||
167 | - { | ||
168 | - return $this->hasOne(ProductImage::className(), [ 'product_id' => 'product_id' ]); | ||
169 | - } | ||
170 | - | ||
171 | - /** | ||
172 | - * fetch stored image url | ||
173 | - * @return string | ||
174 | - */ | ||
175 | - public function getImageUrl() | ||
176 | - { | ||
177 | - $image = empty( $this->variant ) ? NULL : $this->variant->image; | ||
178 | - return !empty( $image ) ? $image->imageUrl : '/images/no_photo.png'; | ||
179 | - } | ||
180 | - | ||
181 | - /** | ||
182 | - * @return \yii\db\ActiveQuery | ||
183 | - */ | ||
184 | - public function getImages() | ||
185 | - { | ||
186 | - return $this->hasMany(ProductImage::className(), [ 'product_id' => 'product_id' ]) | ||
187 | - ->where([ 'product_variant_id' => NULL ]); | ||
188 | - } | ||
189 | 201 | ||
190 | /** | 202 | /** |
191 | * @return \yii\db\ActiveQuery | 203 | * @return \yii\db\ActiveQuery |
@@ -247,18 +259,15 @@ | @@ -247,18 +259,15 @@ | ||
247 | return empty( $this->brand ) ? $this->lang->name : $this->brand->lang->name . ' ' . $this->lang->name; | 259 | return empty( $this->brand ) ? $this->lang->name : $this->brand->lang->name . ' ' . $this->lang->name; |
248 | } | 260 | } |
249 | 261 | ||
262 | + /** | ||
263 | + * @return ActiveQuery | ||
264 | + */ | ||
250 | public function getCategories() | 265 | public function getCategories() |
251 | { | 266 | { |
252 | return $this->hasMany(Category::className(), [ 'category_id' => 'category_id' ]) | 267 | return $this->hasMany(Category::className(), [ 'category_id' => 'category_id' ]) |
253 | ->viaTable('product_category', [ 'product_id' => 'product_id' ]); | 268 | ->viaTable('product_category', [ 'product_id' => 'product_id' ]); |
254 | } | 269 | } |
255 | 270 | ||
256 | - public function getCategoriesWithName() | ||
257 | - { | ||
258 | - return $this->hasMany(Category::className(), [ 'category_id' => 'category_id' ]) | ||
259 | - ->viaTable('product_category', [ 'product_id' => 'product_id' ]); | ||
260 | - } | ||
261 | - | ||
262 | public function getCategoriesNames() | 271 | public function getCategoriesNames() |
263 | { | 272 | { |
264 | $result = []; | 273 | $result = []; |
@@ -347,135 +356,51 @@ | @@ -347,135 +356,51 @@ | ||
347 | ->where([ 'product_id' => $this->product_id ]) | 356 | ->where([ 'product_id' => $this->product_id ]) |
348 | ->sum('quantity'); | 357 | ->sum('quantity'); |
349 | } | 358 | } |
350 | - | 359 | + |
351 | public function afterSave($insert, $changedAttributes) | 360 | public function afterSave($insert, $changedAttributes) |
352 | { | 361 | { |
353 | parent::afterSave($insert, $changedAttributes); | 362 | parent::afterSave($insert, $changedAttributes); |
354 | - | ||
355 | - if(!empty($this->categories)){ | 363 | + |
364 | + if(!empty( $this->categories )) { | ||
356 | $categories = Category::findAll($this->categories); | 365 | $categories = Category::findAll($this->categories); |
357 | $this->unlinkAll('categories', true); | 366 | $this->unlinkAll('categories', true); |
358 | - foreach($categories as $category){ | 367 | + foreach($categories as $category) { |
359 | $this->link('categories', $category); | 368 | $this->link('categories', $category); |
360 | } | 369 | } |
361 | } | 370 | } |
362 | - | ||
363 | - if(!empty($this->options)){ | 371 | + |
372 | + if(!empty( $this->options )) { | ||
364 | $options = TaxOption::findAll($this->options); | 373 | $options = TaxOption::findAll($this->options); |
365 | - $this->unlinkAll('options',true); | ||
366 | - foreach($options as $option){ | 374 | + $this->unlinkAll('options', true); |
375 | + foreach($options as $option) { | ||
367 | $this->link('options', $option); | 376 | $this->link('options', $option); |
368 | } | 377 | } |
369 | } | 378 | } |
370 | - | ||
371 | - | ||
372 | - if (!empty($this->_variants)) { | 379 | + |
380 | + if(!empty( $this->_variants )) { | ||
373 | $todel = []; | 381 | $todel = []; |
374 | - foreach ($this->variants ?: [] as $_variant) { | ||
375 | - $todel[$_variant->product_variant_id] = $_variant->product_variant_id; | 382 | + foreach($this->variants ? : [] as $_variant) { |
383 | + $todel[ $_variant->product_variant_id ] = $_variant->product_variant_id; | ||
376 | } | 384 | } |
377 | - foreach ($this->_variants as $_variant) { | ||
378 | - if (!is_array($_variant)) { | 385 | + foreach($this->_variants as $_variant) { |
386 | + if(!is_array($_variant)) { | ||
379 | return; | 387 | return; |
380 | } | 388 | } |
381 | - if (!empty($_variant['product_variant_id'])) { | ||
382 | - unset($todel[$_variant['product_variant_id']]); | ||
383 | - $model = ProductVariant::findOne($_variant['product_variant_id']); | 389 | + if(!empty( $_variant[ 'product_variant_id' ] )) { |
390 | + unset( $todel[ $_variant[ 'product_variant_id' ] ] ); | ||
391 | + $model = ProductVariant::findOne($_variant[ 'product_variant_id' ]); | ||
384 | } else { | 392 | } else { |
385 | $model = new ProductVariant(); | 393 | $model = new ProductVariant(); |
386 | } | 394 | } |
387 | - $_variant['product_id'] = $this->product_id; | ||
388 | - $model->load(['ProductVariant' => $_variant]); | 395 | + $_variant[ 'product_id' ] = $this->product_id; |
396 | + $model->load([ 'ProductVariant' => $_variant ]); | ||
389 | $model->product_id = $this->product_id; | 397 | $model->product_id = $this->product_id; |
390 | $model->save(); | 398 | $model->save(); |
391 | } | 399 | } |
392 | - if (!empty($todel)) { | ||
393 | - ProductVariant::deleteAll(['product_variant_id' => $todel]); | ||
394 | - } | ||
395 | - } | ||
396 | - } | ||
397 | - | ||
398 | - public function imagesUpload() | ||
399 | - { | ||
400 | - if($this->validate()) { | ||
401 | - $images = []; | ||
402 | - foreach($this->imagesUpload as $image) { | ||
403 | - $imageName = $image->baseName . '.' . $image->extension; | ||
404 | - $i = 0; | ||
405 | - while(file_exists(Yii::getAlias('@imagesDir/products/' . $imageName))) { | ||
406 | - $i++; | ||
407 | - $imageName = $image->baseName . '_' . $i . '.' . $image->extension; | ||
408 | - } | ||
409 | - $imgDir = Yii::getAlias('@imagesDir/products/'); | ||
410 | - if(!is_dir($imgDir)) { | ||
411 | - mkdir($imgDir, 0755, true); | ||
412 | - } | ||
413 | - | ||
414 | - $image->saveAs($imgDir . $imageName); | ||
415 | - $images[] = $imageName; | ||
416 | - } | ||
417 | - return $images; | ||
418 | - } else { | ||
419 | - return false; | ||
420 | - } | ||
421 | - } | ||
422 | - | ||
423 | - public function certificateUpload() | ||
424 | - { | ||
425 | - if($this->validate()) { | ||
426 | - $certificates = []; | ||
427 | - foreach($this->certificateUpload as $certificate) { | ||
428 | - $certificateName = $certificate->baseName . '.' . $certificate->extension; | ||
429 | - $i = 0; | ||
430 | - while(file_exists(Yii::getAlias('@storage/certificates/' . $this->product_id . '/' . $certificateName))) { | ||
431 | - $i++; | ||
432 | - $certificateName = $certificate->baseName . '_' . $i . '.' . $certificate->extension; | ||
433 | - } | ||
434 | - $certificateDir = Yii::getAlias('@storage/certificates/' . $this->product_id . '/'); | ||
435 | - if(!is_dir($certificateDir)) { | ||
436 | - mkdir($certificateDir, 0755, true); | ||
437 | - } | ||
438 | - | ||
439 | - $certificate->saveAs($certificateDir . $certificateName); | ||
440 | - $certificates[] = $certificateName; | ||
441 | - } | ||
442 | - return $certificates; | ||
443 | - } else { | ||
444 | - return false; | ||
445 | - } | ||
446 | - } | ||
447 | - | ||
448 | - public function getImagesHTML() | ||
449 | - { | ||
450 | - $op = []; | ||
451 | - if($this->images) { | ||
452 | - foreach($this->images as $image) { | ||
453 | - $op[] = \common\components\artboximage\ArtboxImageHelper::getImage($image->imageUrl, 'admin_thumb'); | ||
454 | - } | ||
455 | - } | ||
456 | - return $op; | ||
457 | - } | ||
458 | - | ||
459 | - public function getImagesConfig() | ||
460 | - { | ||
461 | - $op = []; | ||
462 | - if($this->images) { | ||
463 | - foreach($this->images as $image) { | ||
464 | - $op[] = [ | ||
465 | - 'caption' => $image->image, | ||
466 | - 'width' => '120px', | ||
467 | - 'url' => \yii\helpers\Url::to([ | ||
468 | - '/product/manage/delimg', | ||
469 | - 'id' => $image->product_image_id, | ||
470 | - ]), | ||
471 | - 'key' => $image->product_image_id, | ||
472 | - 'extra' => [ | ||
473 | - 'id' => $image->product_image_id, | ||
474 | - ], | ||
475 | - ]; | 400 | + if(!empty( $todel )) { |
401 | + ProductVariant::deleteAll([ 'product_variant_id' => $todel ]); | ||
476 | } | 402 | } |
477 | } | 403 | } |
478 | - return $op; | ||
479 | } | 404 | } |
480 | 405 | ||
481 | public function recalculateRating() | 406 | public function recalculateRating() |
common/modules/product/models/ProductImage.php
1 | <?php | 1 | <?php |
2 | - | ||
3 | -namespace common\modules\product\models; | ||
4 | - | ||
5 | -use Yii; | ||
6 | -use yii\web\UploadedFile; | ||
7 | - | ||
8 | -/** | ||
9 | - * This is the model class for table "product_image". | ||
10 | - * | ||
11 | - * @property integer $product_image_id | ||
12 | - * @property integer $product_id | ||
13 | - * @property integer $product_variant_id | ||
14 | - * @property string $image | ||
15 | - * @property string $alt | ||
16 | - * @property string $title | ||
17 | - * @property Product $product | ||
18 | - * @property ProductVariant $productVariant | ||
19 | - */ | ||
20 | -class ProductImage extends \yii\db\ActiveRecord | ||
21 | -{ | ||
22 | - public $imageUpload; | 2 | + |
3 | + namespace common\modules\product\models; | ||
4 | + | ||
5 | + use common\behaviors\ImageBehavior; | ||
6 | + use Yii; | ||
7 | + | ||
23 | /** | 8 | /** |
24 | - * @inheritdoc | 9 | + * This is the model class for table "product_image". |
10 | + * @property integer $product_image_id | ||
11 | + * @property integer $product_id | ||
12 | + * @property integer $product_variant_id | ||
13 | + * @property string $image | ||
14 | + * @property string $alt | ||
15 | + * @property string $title | ||
16 | + * @property Product $product | ||
17 | + * @property ProductVariant $productVariant | ||
25 | */ | 18 | */ |
26 | - public static function tableName() | 19 | + class ProductImage extends \yii\db\ActiveRecord |
27 | { | 20 | { |
28 | - return 'product_image'; | ||
29 | - } | ||
30 | - | ||
31 | - /** | ||
32 | - * @inheritdoc | ||
33 | - */ | ||
34 | - public function rules() | ||
35 | - { | ||
36 | - return [ | ||
37 | - [['product_id'], 'required'], | ||
38 | - [['product_image_id', 'product_id', 'product_variant_id'], 'integer'], | ||
39 | - [['alt', 'title', 'image'], 'string', 'max' => 255], | ||
40 | - [['product_id'], 'exist', 'skipOnError' => true, 'targetClass' => Product::className(), 'targetAttribute' => ['product_id' => 'product_id']], | ||
41 | - [['product_variant_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductVariant::className(), 'targetAttribute' => ['product_variant_id' => 'product_variant_id']], | ||
42 | - [['imageUpload'], 'safe'], | ||
43 | - [['imageUpload'], 'file', 'extensions' => 'jpg, gif, png'], | ||
44 | - ]; | ||
45 | - } | ||
46 | - | ||
47 | - /** | ||
48 | - * @inheritdoc | ||
49 | - */ | ||
50 | - public function attributeLabels() | ||
51 | - { | ||
52 | - return [ | ||
53 | - 'product_image_id' => Yii::t('product', 'Product Image ID'), | ||
54 | - 'product_id' => Yii::t('product', 'Product ID'), | ||
55 | - 'product_variant_id' => Yii::t('product', 'Product Variant ID'), | ||
56 | - 'product' => Yii::t('product', 'Product'), | ||
57 | - 'product_variant' => Yii::t('product', 'Product Variant'), | ||
58 | - 'image' => Yii::t('product', 'Image'), | ||
59 | - 'alt' => Yii::t('product', 'Alt'), | ||
60 | - 'title' => Yii::t('product', 'Title'), | ||
61 | - ]; | ||
62 | - } | ||
63 | - | ||
64 | - /** | ||
65 | - * @return \yii\db\ActiveQuery | ||
66 | - */ | ||
67 | - public function getProduct() | ||
68 | - { | ||
69 | - $return = $this->hasOne(Product::className(), ['product_id' => 'product_id']); | ||
70 | - if (empty($return)) { | ||
71 | - $return = $this->productVariant->product_id; | 21 | + |
22 | + /** | ||
23 | + * @inheritdoc | ||
24 | + */ | ||
25 | + public static function tableName() | ||
26 | + { | ||
27 | + return 'product_image'; | ||
72 | } | 28 | } |
73 | - return $return; | ||
74 | - } | ||
75 | - | ||
76 | - /** | ||
77 | - * @return \yii\db\ActiveQuery | ||
78 | - */ | ||
79 | - public function getProductVariant() | ||
80 | - { | ||
81 | - return $this->hasOne(Product::className(), ['product_variant_id' => 'product_variant_id']); | ||
82 | - } | ||
83 | - | ||
84 | - /** | ||
85 | - * fetch stored image file name with complete path | ||
86 | - * @return string | ||
87 | - */ | ||
88 | - public function getImageFile() | ||
89 | - { | ||
90 | - return isset($this->image) ? '/storage/products/' . $this->image : null; | ||
91 | - } | ||
92 | - | ||
93 | - /** | ||
94 | - * fetch stored image url | ||
95 | - * @return string | ||
96 | - */ | ||
97 | - public function getImageUrl() | ||
98 | - { | ||
99 | - // return a default image placeholder if your source image is not found | ||
100 | - return isset($this->image) ? '/storage/products/'. $this->image : '/storage/no_photo.png'; | ||
101 | - } | ||
102 | - | ||
103 | - /** | ||
104 | - * Process upload of image | ||
105 | - * | ||
106 | - * @return mixed the uploaded image instance | ||
107 | - */ | ||
108 | - public function uploadImage() { | ||
109 | - // get the uploaded file instance. for multiple file uploads | ||
110 | - // the following data will return an array (you may need to use | ||
111 | - // getInstances method) | ||
112 | - $image = UploadedFile::getInstance($this, 'imageUpload'); | ||
113 | - | ||
114 | - // if no image was uploaded abort the upload | ||
115 | - if (empty($image)) { | ||
116 | - return false; | 29 | + |
30 | + public function behaviors() | ||
31 | + { | ||
32 | + return [ | ||
33 | + [ | ||
34 | + 'class' => ImageBehavior::className(), | ||
35 | + 'link' => 'image', | ||
36 | + 'directory' => 'products', | ||
37 | + ], | ||
38 | + ]; | ||
117 | } | 39 | } |
118 | - | ||
119 | - // store the source file name | ||
120 | - $this->filename = $image->name; | ||
121 | - $ext = end((explode(".", $image->name))); | ||
122 | - | ||
123 | - // generate a unique file name | ||
124 | - $this->image = Yii::$app->security->generateRandomString().".{$ext}"; | ||
125 | - | ||
126 | - // the uploaded image instance | ||
127 | - return $image; | ||
128 | - } | ||
129 | - | ||
130 | - /** | ||
131 | - * Process deletion of image | ||
132 | - * | ||
133 | - * @return boolean the status of deletion | ||
134 | - */ | ||
135 | - public function deleteImage() { | ||
136 | - $file = $this->getImageFile(); | ||
137 | - | ||
138 | - // check if file exists on server | ||
139 | - if (empty($file) || !file_exists($file)) { | ||
140 | - return false; | 40 | + |
41 | + /** | ||
42 | + * @inheritdoc | ||
43 | + */ | ||
44 | + public function rules() | ||
45 | + { | ||
46 | + return [ | ||
47 | + [ | ||
48 | + [ 'product_id' ], | ||
49 | + 'required', | ||
50 | + ], | ||
51 | + [ | ||
52 | + [ | ||
53 | + 'product_image_id', | ||
54 | + 'product_id', | ||
55 | + 'product_variant_id', | ||
56 | + ], | ||
57 | + 'integer', | ||
58 | + ], | ||
59 | + [ | ||
60 | + [ | ||
61 | + 'alt', | ||
62 | + 'title', | ||
63 | + 'image', | ||
64 | + ], | ||
65 | + 'string', | ||
66 | + 'max' => 255, | ||
67 | + ], | ||
68 | + [ | ||
69 | + [ 'product_id' ], | ||
70 | + 'exist', | ||
71 | + 'skipOnError' => true, | ||
72 | + 'targetClass' => Product::className(), | ||
73 | + 'targetAttribute' => [ 'product_id' => 'product_id' ], | ||
74 | + ], | ||
75 | + [ | ||
76 | + [ 'product_variant_id' ], | ||
77 | + 'exist', | ||
78 | + 'skipOnError' => true, | ||
79 | + 'targetClass' => ProductVariant::className(), | ||
80 | + 'targetAttribute' => [ 'product_variant_id' => 'product_variant_id' ], | ||
81 | + ], | ||
82 | + ]; | ||
83 | + } | ||
84 | + | ||
85 | + /** | ||
86 | + * @inheritdoc | ||
87 | + */ | ||
88 | + public function attributeLabels() | ||
89 | + { | ||
90 | + return [ | ||
91 | + 'product_image_id' => Yii::t('product', 'Product Image ID'), | ||
92 | + 'product_id' => Yii::t('product', 'Product ID'), | ||
93 | + 'product_variant_id' => Yii::t('product', 'Product Variant ID'), | ||
94 | + 'product' => Yii::t('product', 'Product'), | ||
95 | + 'product_variant' => Yii::t('product', 'Product Variant'), | ||
96 | + 'image' => Yii::t('product', 'Image'), | ||
97 | + 'alt' => Yii::t('product', 'Alt'), | ||
98 | + 'title' => Yii::t('product', 'Title'), | ||
99 | + ]; | ||
100 | + } | ||
101 | + | ||
102 | + /** | ||
103 | + * @return \yii\db\ActiveQuery | ||
104 | + */ | ||
105 | + public function getProduct() | ||
106 | + { | ||
107 | + $return = $this->hasOne(Product::className(), [ 'product_id' => 'product_id' ]); | ||
108 | + if(empty( $return )) { | ||
109 | + $return = $this->productVariant->product_id; | ||
110 | + } | ||
111 | + return $return; | ||
141 | } | 112 | } |
142 | - | ||
143 | - // check if uploaded file can be deleted on server | ||
144 | - if (!unlink($file)) { | ||
145 | - return false; | 113 | + |
114 | + /** | ||
115 | + * @return \yii\db\ActiveQuery | ||
116 | + */ | ||
117 | + public function getProductVariant() | ||
118 | + { | ||
119 | + return $this->hasOne(Product::className(), [ 'product_variant_id' => 'product_variant_id' ]); | ||
146 | } | 120 | } |
147 | - | ||
148 | - // if deletion successful, reset your file attributes | ||
149 | - $this->image = null; | ||
150 | - $this->filename = null; | ||
151 | - | ||
152 | - return true; | ||
153 | } | 121 | } |
154 | -} |
common/modules/product/models/ProductSearch.php
1 | <?php | 1 | <?php |
2 | - | ||
3 | -namespace common\modules\product\models; | ||
4 | - | ||
5 | -use yii\base\Model; | ||
6 | -use yii\data\ActiveDataProvider; | ||
7 | - | ||
8 | -/** | ||
9 | - * ProductSearch represents the model behind the search form about `common\modules\product\models\Product`. | ||
10 | - */ | ||
11 | -class ProductSearch extends Product | ||
12 | -{ | ||
13 | - public $brand_name; | ||
14 | - public $brand_id; | ||
15 | - public $category_id; | ||
16 | - public $category_name; | ||
17 | - public $variant_sku; | ||
18 | - | ||
19 | - public function behaviors() | ||
20 | - { | ||
21 | - $behaviors = parent::behaviors(); | ||
22 | - if(isset($behaviors['language'])) { | ||
23 | - unset($behaviors['language']); | ||
24 | - } | ||
25 | - return $behaviors; | ||
26 | - } | ||
27 | 2 | ||
28 | - /** | ||
29 | - * @inheritdoc | ||
30 | - */ | ||
31 | - public function rules() | ||
32 | - { | ||
33 | - return [ | ||
34 | - [['brand_name', 'brand_id', 'category_id', 'category_name', 'variant_sku'], 'safe'], | ||
35 | - [['brand_id', 'product_id'], 'integer'], | ||
36 | - [['is_top', 'is_new', 'akciya'], 'boolean'], | ||
37 | - ]; | ||
38 | - } | 3 | + namespace common\modules\product\models; |
4 | + | ||
5 | + use yii\base\Model; | ||
6 | + use yii\data\ActiveDataProvider; | ||
7 | + use yii\db\ActiveQuery; | ||
39 | 8 | ||
40 | /** | 9 | /** |
41 | - * @inheritdoc | ||
42 | - */ | ||
43 | - public function scenarios() | ||
44 | - { | ||
45 | - // bypass scenarios() implementation in the parent class | ||
46 | - return Model::scenarios(); | ||
47 | - } | ||
48 | - | ||
49 | - /** | ||
50 | - * Creates data provider instance with search query applied | ||
51 | - * | ||
52 | - * @param array $params | ||
53 | - * | ||
54 | - * @return ActiveDataProvider | 10 | + * ProductSearch represents the model behind the search form about |
11 | + * `common\modules\product\models\Product`. | ||
55 | */ | 12 | */ |
56 | - public function search($params) | 13 | + class ProductSearch extends Product |
57 | { | 14 | { |
58 | - | ||
59 | - $query = Product::find(); | ||
60 | - | ||
61 | -// $query->joinWith(['brand', 'categories', 'variant']); | ||
62 | - | ||
63 | - $query->groupBy(['product.product_id']); | ||
64 | - | ||
65 | - $dataProvider = new ActiveDataProvider([ | ||
66 | - 'query' => $query, | ||
67 | - ]); | ||
68 | - | ||
69 | - if ( !($this->load($params) && $this->validate()) ) { | ||
70 | - return $dataProvider; | 15 | + |
16 | + public $brand_id; | ||
17 | + | ||
18 | + public $category_id; | ||
19 | + | ||
20 | + public $variant_sku; | ||
21 | + | ||
22 | + public function behaviors() | ||
23 | + { | ||
24 | + $behaviors = parent::behaviors(); | ||
25 | + if(isset( $behaviors[ 'language' ] )) { | ||
26 | + unset( $behaviors[ 'language' ] ); | ||
27 | + } | ||
28 | + return $behaviors; | ||
71 | } | 29 | } |
72 | - | ||
73 | -// $dataProvider->setSort([ | ||
74 | -// 'attributes' => [ | ||
75 | -// 'brand_name' => [ | ||
76 | -// 'asc' => ['brand.name' => SORT_ASC], | ||
77 | -// 'desc' => ['brand.name' => SORT_DESC], | ||
78 | -// 'default' => SORT_DESC, | ||
79 | -// 'label' => 'Brand name', | ||
80 | -// ], | ||
81 | -// 'category_name', | ||
82 | -// 'variant_sku', | ||
83 | -// ] | ||
84 | -// ]); | ||
85 | - | ||
86 | - if (isset($this->is_top)) { | ||
87 | - $query->andFilterWhere([ | ||
88 | - 'is_top' => (bool)$this->is_top, | ||
89 | - ]); | 30 | + |
31 | + /** | ||
32 | + * @inheritdoc | ||
33 | + */ | ||
34 | + public function rules() | ||
35 | + { | ||
36 | + return [ | ||
37 | + [ | ||
38 | + [ 'variant_sku' ], | ||
39 | + 'safe', | ||
40 | + ], | ||
41 | + [ | ||
42 | + [ | ||
43 | + 'brand_id', | ||
44 | + 'product_id', | ||
45 | + 'category_id', | ||
46 | + 'brand_id', | ||
47 | + ], | ||
48 | + 'integer', | ||
49 | + ], | ||
50 | + [ | ||
51 | + [ | ||
52 | + 'is_top', | ||
53 | + 'is_new', | ||
54 | + 'akciya', | ||
55 | + ], | ||
56 | + 'boolean', | ||
57 | + ], | ||
58 | + ]; | ||
90 | } | 59 | } |
91 | - if (isset($this->is_new)) { | ||
92 | - $query->andFilterWhere([ | ||
93 | - 'is_new' => (bool)$this->is_new, | ||
94 | - ]); | 60 | + |
61 | + /** | ||
62 | + * @inheritdoc | ||
63 | + */ | ||
64 | + public function scenarios() | ||
65 | + { | ||
66 | + // bypass scenarios() implementation in the parent class | ||
67 | + return Model::scenarios(); | ||
95 | } | 68 | } |
96 | - if (isset($this->akciya)) { | 69 | + |
70 | + /** | ||
71 | + * Creates data provider instance with search query applied | ||
72 | + * | ||
73 | + * @param array $params | ||
74 | + * | ||
75 | + * @return ActiveDataProvider | ||
76 | + */ | ||
77 | + public function search($params) | ||
78 | + { | ||
79 | + | ||
80 | + $query = Product::find(); | ||
81 | + | ||
82 | + $query->joinWith([ | ||
83 | + 'categories', | ||
84 | + /*'variant'*/ | ||
85 | + ]) | ||
86 | + ->joinWith([ | ||
87 | + 'brand' => function($query) { | ||
88 | + /** | ||
89 | + * @var ActiveQuery $query | ||
90 | + */ | ||
91 | + $query->joinWith('lang'); | ||
92 | + }, | ||
93 | + ]); | ||
94 | + | ||
95 | + $query->groupBy([ 'product.product_id' ]); | ||
96 | + | ||
97 | + $dataProvider = new ActiveDataProvider([ | ||
98 | + 'query' => $query, | ||
99 | + ]); | ||
100 | + | ||
101 | + if(!( $this->load($params) && $this->validate() )) { | ||
102 | + return $dataProvider; | ||
103 | + } | ||
104 | + | ||
105 | + $dataProvider->setSort([ | ||
106 | + 'attributes' => [ | ||
107 | + 'brand_id' => [ | ||
108 | + 'asc' => [ 'brand_lang.name' => SORT_ASC ], | ||
109 | + 'desc' => [ 'brand_lang.name' => SORT_DESC ], | ||
110 | + 'default' => SORT_DESC, | ||
111 | + 'label' => 'Brand name', | ||
112 | + ], | ||
113 | + ], | ||
114 | + ]); | ||
115 | + | ||
116 | + if(isset( $this->is_top )) { | ||
117 | + $query->andFilterWhere([ | ||
118 | + 'is_top' => (bool) $this->is_top, | ||
119 | + ]); | ||
120 | + } | ||
121 | + if(isset( $this->is_new )) { | ||
122 | + $query->andFilterWhere([ | ||
123 | + 'is_new' => (bool) $this->is_new, | ||
124 | + ]); | ||
125 | + } | ||
126 | + if(isset( $this->akciya )) { | ||
127 | + $query->andFilterWhere([ | ||
128 | + 'akciya' => (bool) $this->akciya, | ||
129 | + ]); | ||
130 | + } | ||
97 | $query->andFilterWhere([ | 131 | $query->andFilterWhere([ |
98 | - 'akciya' => (bool)$this->akciya, | 132 | + 'product.brand_id' => $this->brand_id, |
133 | + 'product.product_id' => $this->product_id, | ||
134 | + 'product_category.category_id' => $this->category_id, | ||
99 | ]); | 135 | ]); |
136 | + | ||
137 | + // $query->andFilterWhere(['ilike', 'brand.name', $this->brand_name]); | ||
138 | + // $query->andFilterWhere(['ilike', 'product_variant.sku', $this->variant_sku]); | ||
139 | + | ||
140 | + return $dataProvider; | ||
100 | } | 141 | } |
101 | - $query->andFilterWhere([ | ||
102 | - 'product.brand_id' => $this->brand_id, | ||
103 | - 'product.product_id' => $this->product_id, | ||
104 | -// 'product_category.category_id' => $this->category_id | ||
105 | - ]); | ||
106 | - | ||
107 | -// $query->andFilterWhere(['ilike', 'brand.name', $this->brand_name]); | ||
108 | -// $query->andFilterWhere(['ilike', 'category.name', $this->category_name]); | ||
109 | -// $query->andFilterWhere(['ilike', 'product_variant.sku', $this->variant_sku]); | ||
110 | - | ||
111 | - return $dataProvider; | ||
112 | } | 142 | } |
113 | -} |
common/modules/product/models/ProductVariant.php
@@ -2,6 +2,8 @@ | @@ -2,6 +2,8 @@ | ||
2 | 2 | ||
3 | namespace common\modules\product\models; | 3 | namespace common\modules\product\models; |
4 | 4 | ||
5 | + use common\behaviors\MultipleImgBehavior; | ||
6 | + use common\behaviors\SaveMultipleFileBehavior; | ||
5 | use common\modules\language\behaviors\LanguageBehavior; | 7 | use common\modules\language\behaviors\LanguageBehavior; |
6 | use common\modules\rubrication\models\TaxGroup; | 8 | use common\modules\rubrication\models\TaxGroup; |
7 | use common\modules\rubrication\models\TaxOption; | 9 | use common\modules\rubrication\models\TaxOption; |
@@ -22,8 +24,6 @@ | @@ -22,8 +24,6 @@ | ||
22 | * @property double $price_old | 24 | * @property double $price_old |
23 | * @property double $stock | 25 | * @property double $stock |
24 | * @property integer $product_unit_id | 26 | * @property integer $product_unit_id |
25 | - * @property ProductImage $image | ||
26 | - * @property array $images | ||
27 | * @property TaxOption[] $options | 27 | * @property TaxOption[] $options |
28 | * @property ProductUnit $productUnit | 28 | * @property ProductUnit $productUnit |
29 | * @property Product $product | 29 | * @property Product $product |
@@ -47,6 +47,14 @@ | @@ -47,6 +47,14 @@ | ||
47 | * @method bool saveLangs() | 47 | * @method bool saveLangs() |
48 | * @method bool getTransactionStatus() | 48 | * @method bool getTransactionStatus() |
49 | * * End language behavior * | 49 | * * End language behavior * |
50 | + * * From multipleImage behavior | ||
51 | + * @property ProductImage $image | ||
52 | + * @property ProductImage[] $images | ||
53 | + * @method ActiveQuery getImage() | ||
54 | + * @method ActiveQuery getImages() | ||
55 | + * @method array getImagesConfig() | ||
56 | + * @method array getImagesHTML( string $preset ) | ||
57 | + * * End multipleImage behavior | ||
50 | */ | 58 | */ |
51 | class ProductVariant extends ActiveRecord | 59 | class ProductVariant extends ActiveRecord |
52 | { | 60 | { |
@@ -58,7 +66,7 @@ | @@ -58,7 +66,7 @@ | ||
58 | private $_options; | 66 | private $_options; |
59 | 67 | ||
60 | /** @var array $_images */ | 68 | /** @var array $_images */ |
61 | - public $imagesUpload = ''; | 69 | + public $imagesUpload = []; |
62 | 70 | ||
63 | /** | 71 | /** |
64 | * @inheritdoc | 72 | * @inheritdoc |
@@ -71,9 +79,32 @@ | @@ -71,9 +79,32 @@ | ||
71 | public function behaviors() | 79 | public function behaviors() |
72 | { | 80 | { |
73 | return [ | 81 | return [ |
74 | - 'language' => [ | 82 | + 'language' => [ |
75 | 'class' => LanguageBehavior::className(), | 83 | 'class' => LanguageBehavior::className(), |
76 | ], | 84 | ], |
85 | + 'images' => [ | ||
86 | + 'class' => SaveMultipleFileBehavior::className(), | ||
87 | + 'name' => 'imagesUpload', | ||
88 | + 'directory' => 'products', | ||
89 | + 'column' => 'image', | ||
90 | + 'links' => [ | ||
91 | + 'product_id' => 'product_id', | ||
92 | + 'product_variant_id' => 'product_variant_id', | ||
93 | + ], | ||
94 | + 'model' => ProductImage::className(), | ||
95 | + ], | ||
96 | + 'multipleImage' => [ | ||
97 | + 'class' => MultipleImgBehavior::className(), | ||
98 | + 'links' => [ | ||
99 | + 'product_variant_id' => 'product_variant_id', | ||
100 | + ], | ||
101 | + 'model' => ProductImage::className(), | ||
102 | + 'config' => [ | ||
103 | + 'caption' => 'image', | ||
104 | + 'delete_action' => '/product/variant/delimg', | ||
105 | + 'id' => 'product_image_id', | ||
106 | + ], | ||
107 | + ], | ||
77 | ]; | 108 | ]; |
78 | } | 109 | } |
79 | 110 | ||
@@ -115,7 +146,6 @@ | @@ -115,7 +146,6 @@ | ||
115 | [ | 146 | [ |
116 | [ | 147 | [ |
117 | 'options', | 148 | 'options', |
118 | - 'imagesUpload', | ||
119 | ], | 149 | ], |
120 | 'safe', | 150 | 'safe', |
121 | ], | 151 | ], |
@@ -204,70 +234,11 @@ | @@ -204,70 +234,11 @@ | ||
204 | ->joinWith('lang', true, 'INNER JOIN'); | 234 | ->joinWith('lang', true, 'INNER JOIN'); |
205 | } | 235 | } |
206 | 236 | ||
207 | - /** | ||
208 | - * @return \yii\db\ActiveQuery | ||
209 | - */ | ||
210 | - public function getImage() | ||
211 | - { | ||
212 | - return $this->hasOne(ProductImage::className(), [ 'product_variant_id' => 'product_variant_id' ]); | ||
213 | - } | ||
214 | - | ||
215 | - /** | ||
216 | - * fetch stored image url | ||
217 | - * @return string | ||
218 | - */ | ||
219 | - public function getImageUrl() | ||
220 | - { | ||
221 | - // return a default image placeholder if your source image is not found | ||
222 | - return !empty( $this->image ) ? $this->image->imageUrl : '/images/no_photo.png'; | ||
223 | - } | ||
224 | - | ||
225 | public function getFullname() | 237 | public function getFullname() |
226 | { | 238 | { |
227 | return empty( $this->product ) ? NULL : ( $this->product->lang->name . ( empty( $this->lang->name ) ? '' : ' ' . $this->lang->name ) ); | 239 | return empty( $this->product ) ? NULL : ( $this->product->lang->name . ( empty( $this->lang->name ) ? '' : ' ' . $this->lang->name ) ); |
228 | } | 240 | } |
229 | 241 | ||
230 | - public function getImagesHTML() | ||
231 | - { | ||
232 | - $op = []; | ||
233 | - if($this->images) { | ||
234 | - foreach($this->images as $image) { | ||
235 | - $op[] = \common\components\artboximage\ArtboxImageHelper::getImage($image->imageUrl, 'admin_thumb'); | ||
236 | - } | ||
237 | - } | ||
238 | - return $op; | ||
239 | - } | ||
240 | - | ||
241 | - public function getImagesConfig() | ||
242 | - { | ||
243 | - $op = []; | ||
244 | - if($this->images) { | ||
245 | - foreach($this->images as $image) { | ||
246 | - $op[] = [ | ||
247 | - 'caption' => $image->image, | ||
248 | - 'width' => '120px', | ||
249 | - 'url' => \yii\helpers\Url::to([ | ||
250 | - '/product/manage/delimg', | ||
251 | - 'id' => $image->product_image_id, | ||
252 | - ]), | ||
253 | - 'key' => $image->product_image_id, | ||
254 | - 'extra' => [ | ||
255 | - 'id' => $image->product_image_id, | ||
256 | - ], | ||
257 | - ]; | ||
258 | - } | ||
259 | - } | ||
260 | - return $op; | ||
261 | - } | ||
262 | - | ||
263 | - /** | ||
264 | - * @return \yii\db\ActiveQuery | ||
265 | - */ | ||
266 | - public function getImages() | ||
267 | - { | ||
268 | - return $this->hasMany(ProductImage::className(), [ 'product_variant_id' => 'product_variant_id' ]); | ||
269 | - } | ||
270 | - | ||
271 | public function setOptions($values) | 242 | public function setOptions($values) |
272 | { | 243 | { |
273 | $this->_options = $values; | 244 | $this->_options = $values; |
@@ -348,7 +319,6 @@ | @@ -348,7 +319,6 @@ | ||
348 | 319 | ||
349 | if(!empty( $this->stocks )) { | 320 | if(!empty( $this->stocks )) { |
350 | ProductStock::deleteAll([ 'product_variant_id' => $this->product_variant_id ]); | 321 | ProductStock::deleteAll([ 'product_variant_id' => $this->product_variant_id ]); |
351 | - $values = []; | ||
352 | foreach($this->stocks as $id => $quantity) { | 322 | foreach($this->stocks as $id => $quantity) { |
353 | $productStock = ProductStock::find() | 323 | $productStock = ProductStock::find() |
354 | ->where([ | 324 | ->where([ |
@@ -362,24 +332,4 @@ | @@ -362,24 +332,4 @@ | ||
362 | } | 332 | } |
363 | } | 333 | } |
364 | 334 | ||
365 | - public function imagesUpload() | ||
366 | - { | ||
367 | - if($this->validate()) { | ||
368 | - $images = []; | ||
369 | - foreach($this->imagesUpload as $image) { | ||
370 | - $imageName = $image->baseName . '.' . $image->extension; | ||
371 | - $i = 0; | ||
372 | - while(file_exists(Yii::getAlias('@imagesDir/products/' . $imageName))) { | ||
373 | - $i++; | ||
374 | - $imageName = $image->baseName . '_' . $i . '.' . $image->extension; | ||
375 | - } | ||
376 | - | ||
377 | - $image->saveAs(Yii::getAlias('@imagesDir/products/' . $imageName)); | ||
378 | - $images[] = $imageName; | ||
379 | - } | ||
380 | - return $images; | ||
381 | - } else { | ||
382 | - return false; | ||
383 | - } | ||
384 | - } | ||
385 | } | 335 | } |
common/modules/product/views/manage/export-process.php
100644 → 100755
common/modules/product/views/manage/export.php
100644 → 100755
common/modules/product/views/manage/index.php
1 | <?php | 1 | <?php |
2 | - | ||
3 | -use yii\helpers\Html; | ||
4 | -use yii\grid\GridView; | ||
5 | -use yii\helpers\ArrayHelper; | ||
6 | -use kartik\select2\Select2; | ||
7 | -use common\components\artboxtree\ArtboxTreeHelper; | ||
8 | -use common\modules\product\helpers\ProductHelper; | ||
9 | - | ||
10 | -/* @var $this yii\web\View */ | ||
11 | -/* @var $searchModel common\modules\product\models\ProductSearch */ | ||
12 | -/* @var $dataProvider yii\data\ActiveDataProvider */ | ||
13 | - | ||
14 | -$this->title = Yii::t('product', 'Products'); | ||
15 | -$this->params['breadcrumbs'][] = $this->title; | 2 | + |
3 | + use common\modules\product\models\Brand; | ||
4 | + use common\modules\product\models\Category; | ||
5 | + use common\modules\product\models\Product; | ||
6 | + use yii\helpers\Html; | ||
7 | + use yii\grid\GridView; | ||
8 | + use kartik\select2\Select2; | ||
9 | + use common\components\artboxtree\ArtboxTreeHelper; | ||
10 | + use common\modules\product\helpers\ProductHelper; | ||
11 | + | ||
12 | + /* @var $this yii\web\View */ | ||
13 | + /* @var $searchModel common\modules\product\models\ProductSearch */ | ||
14 | + /* @var $dataProvider yii\data\ActiveDataProvider */ | ||
15 | + | ||
16 | + $this->title = Yii::t('product', 'Products'); | ||
17 | + $this->params[ 'breadcrumbs' ][] = $this->title; | ||
16 | ?> | 18 | ?> |
17 | <div class="product-index"> | 19 | <div class="product-index"> |
18 | - | 20 | + |
19 | <h1><?= Html::encode($this->title) ?></h1> | 21 | <h1><?= Html::encode($this->title) ?></h1> |
20 | - | 22 | + |
21 | <p> | 23 | <p> |
22 | - <?= Html::a(Yii::t('product', 'Create Product'), ['create'], ['class' => 'btn btn-success']) ?> | 24 | + <?= Html::a(Yii::t('product', 'Create Product'), [ 'create' ], [ 'class' => 'btn btn-success' ]) ?> |
23 | </p> | 25 | </p> |
24 | <?= GridView::widget([ | 26 | <?= GridView::widget([ |
25 | 'dataProvider' => $dataProvider, | 27 | 'dataProvider' => $dataProvider, |
26 | - 'filterModel' => $searchModel, | ||
27 | - 'columns' => [ | ||
28 | - ['class' => 'yii\grid\SerialColumn'], | 28 | + 'filterModel' => $searchModel, |
29 | + 'columns' => [ | ||
29 | 'product_id', | 30 | 'product_id', |
30 | -// [ | ||
31 | -// 'label' => Yii::t('product', 'Brand'), | ||
32 | -// 'attribute' => 'brand_name', | ||
33 | -// 'value' => 'brand.name', | ||
34 | -// 'format' => 'raw', | ||
35 | -// 'filter' => Select2::widget([ | ||
36 | -// 'model' => $searchModel, | ||
37 | -// 'attribute' => 'brand_id', | ||
38 | -// 'data' => ArrayHelper::map(ProductHelper::getBrands()->all(), 'brand_id', 'name'), | ||
39 | -// 'language' => 'ru', | ||
40 | -// 'options' => [ | ||
41 | -// 'placeholder' => Yii::t('product', 'Select brand'), | ||
42 | -// 'multiple' => false, | ||
43 | -// ], | ||
44 | -// 'pluginOptions' => [ | ||
45 | -// 'allowClear' => true | ||
46 | -// ], | ||
47 | -// ]) | ||
48 | -// ], | ||
49 | -// [ | ||
50 | -// 'label' => Yii::t('product', 'Category'), | ||
51 | -// 'attribute' => 'category_name', | ||
52 | -// 'value' => function($model) { | ||
53 | -// $categories = []; | ||
54 | -// foreach ($model->categories as $category) { | ||
55 | -// $categories[] = $category->name; | ||
56 | -// } | ||
57 | -// return implode(", ", $categories); | ||
58 | -// }, | ||
59 | -// 'format' => 'raw', | ||
60 | -// 'filter' => Select2::widget([ | ||
61 | -// 'model' => $searchModel, | ||
62 | -// 'attribute' => 'category_id', | ||
63 | -// 'data' => ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'category_id', 'name'), | ||
64 | -// 'language' => 'ru', | ||
65 | -// 'options' => [ | ||
66 | -// 'placeholder' => Yii::t('product', 'Select category'), | ||
67 | -// 'multiple' => false, | ||
68 | -// ], | ||
69 | -// 'pluginOptions' => [ | ||
70 | -// 'allowClear' => true | ||
71 | -// ], | ||
72 | -// ]) | ||
73 | -// ], | ||
74 | -// [ | ||
75 | -// 'label' => Yii::t('product', 'SKU'), | ||
76 | -// 'attribute' => 'variant_sku', | ||
77 | -// 'value' => 'variant.sku', | ||
78 | -// ], | ||
79 | -// 'variant.price', | ||
80 | -// 'variant.price_old', | ||
81 | -// [ | ||
82 | -// 'label' => Yii::t('product', 'Stock'), | ||
83 | -// 'attribute' => 'variant_stock', | ||
84 | -// 'value' => 'variant.stock_caption', | ||
85 | -// ], | ||
86 | [ | 31 | [ |
87 | - 'class' => 'yii\grid\ActionColumn', | ||
88 | - 'template' => '{items} {view} |{is_top} {is_new} {akciya} | {update} {delete}', | ||
89 | - 'buttons' => [ | ||
90 | - 'is_top' => function ($url, $model) { | ||
91 | - return Html::a('<span class="glyphicon glyphicon-star' . ($model->is_top ? '' : '-empty') . '"></span>', $url, [ | ||
92 | - 'title' => Yii::t('product', ($model->is_top ? 'Set not is top' : 'Set is top')), | 32 | + 'label' => Yii::t('product', 'Brand'), |
33 | + 'attribute' => 'brand_id', | ||
34 | + 'value' => 'brand.lang.name', | ||
35 | + 'filter' => Select2::widget([ | ||
36 | + 'model' => $searchModel, | ||
37 | + 'attribute' => 'brand_id', | ||
38 | + 'data' => Brand::find()->joinWith('lang')->select(['brand_lang.name', 'brand.brand_id'])->asArray()->indexBy('brand_id')->column(), | ||
39 | + 'language' => 'ru', | ||
40 | + 'options' => [ | ||
41 | + 'placeholder' => Yii::t('product', 'Select brand'), | ||
42 | + 'multiple' => false, | ||
43 | + ], | ||
44 | + 'pluginOptions' => [ | ||
45 | + 'allowClear' => true, | ||
46 | + ], | ||
47 | + ]), | ||
48 | + ], | ||
49 | + [ | ||
50 | + 'label' => Yii::t('product', 'Category'), | ||
51 | + 'attribute' => 'category_id', | ||
52 | + 'value' => function($model) { | ||
53 | + /** | ||
54 | + * @var Product $model | ||
55 | + */ | ||
56 | + $categories = []; | ||
57 | + foreach($model->getCategories()->with('lang')->all() as $category) { | ||
58 | + /** | ||
59 | + * @var Category $category | ||
60 | + */ | ||
61 | + $categories[] = $category->lang->name; | ||
62 | + } | ||
63 | + return implode(", ", $categories); | ||
64 | + }, | ||
65 | + 'filter' => Select2::widget([ | ||
66 | + 'model' => $searchModel, | ||
67 | + 'attribute' => 'category_id', | ||
68 | + 'data' => ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'category_id', 'lang.name'), | ||
69 | + 'language' => 'ru', | ||
70 | + 'options' => [ | ||
71 | + 'placeholder' => Yii::t('product', 'Select category'), | ||
72 | + 'multiple' => false, | ||
73 | + ], | ||
74 | + 'pluginOptions' => [ | ||
75 | + 'allowClear' => true, | ||
76 | + ], | ||
77 | + ]), | ||
78 | + ], | ||
79 | + // [ | ||
80 | + // 'label' => Yii::t('product', 'SKU'), | ||
81 | + // 'attribute' => 'variant_sku', | ||
82 | + // 'value' => 'variant.sku', | ||
83 | + // ], | ||
84 | + // 'variant.price', | ||
85 | + // 'variant.price_old', | ||
86 | + // [ | ||
87 | + // 'label' => Yii::t('product', 'Stock'), | ||
88 | + // 'attribute' => 'variant_stock', | ||
89 | + // 'value' => 'variant.stock_caption', | ||
90 | + // ], | ||
91 | + [ | ||
92 | + 'class' => 'yii\grid\ActionColumn', | ||
93 | + 'template' => '{items} {view} |{is_top} {is_new} {akciya} | {update} {delete}', | ||
94 | + 'buttons' => [ | ||
95 | + 'is_top' => function($url, $model) { | ||
96 | + return Html::a('<span class="glyphicon glyphicon-star' . ( $model->is_top ? '' : '-empty' ) . '"></span>', $url, [ | ||
97 | + 'title' => Yii::t('product', ( $model->is_top ? 'Set not is top' : 'Set is top' )), | ||
93 | ]); | 98 | ]); |
94 | }, | 99 | }, |
95 | - 'is_new' => function ($url, $model) { | ||
96 | - return Html::a('<span class="glyphicon glyphicon-heart' . ($model->is_new ? '' : '-empty') . '"></span>', $url, [ | ||
97 | - 'title' => Yii::t('product', ($model->is_new ? 'Set not is new' : 'Set is new')), | 100 | + 'is_new' => function($url, $model) { |
101 | + return Html::a('<span class="glyphicon glyphicon-heart' . ( $model->is_new ? '' : '-empty' ) . '"></span>', $url, [ | ||
102 | + 'title' => Yii::t('product', ( $model->is_new ? 'Set not is new' : 'Set is new' )), | ||
98 | ]); | 103 | ]); |
99 | }, | 104 | }, |
100 | - 'akciya' => function ($url, $model) { | ||
101 | - return Html::a('<span class="glyphicon glyphicon-tag' . ($model->akciya ? 's' : '') . '"></span>', $url, [ | ||
102 | - 'title' => Yii::t('product', ($model->akciya ? 'Set not is promotion' : 'Set is promotion')), | 105 | + 'akciya' => function($url, $model) { |
106 | + return Html::a('<span class="glyphicon glyphicon-tag' . ( $model->akciya ? 's' : '' ) . '"></span>', $url, [ | ||
107 | + 'title' => Yii::t('product', ( $model->akciya ? 'Set not is promotion' : 'Set is promotion' )), | ||
103 | ]); | 108 | ]); |
104 | }, | 109 | }, |
105 | - 'items' => function ($url, $model) { | 110 | + 'items' => function($url, $model) { |
106 | return Html::a('<span class="glyphicon glyphicon-th-list"></span>', $url, [ | 111 | return Html::a('<span class="glyphicon glyphicon-th-list"></span>', $url, [ |
107 | 'title' => Yii::t('product', 'Variants'), | 112 | 'title' => Yii::t('product', 'Variants'), |
108 | ]); | 113 | ]); |
109 | }, | 114 | }, |
110 | - | 115 | + |
111 | ], | 116 | ], |
112 | - 'urlCreator' => function ($action, $model, $key, $index) { | ||
113 | - switch ($action) { | 117 | + 'urlCreator' => function($action, $model, $key, $index) { |
118 | + switch($action) { | ||
114 | case 'items': | 119 | case 'items': |
115 | - return \yii\helpers\Url::to(['/product/variant', 'product_id' => $model->product_id]); | 120 | + return \yii\helpers\Url::to([ |
121 | + '/product/variant', | ||
122 | + 'product_id' => $model->product_id, | ||
123 | + ]); | ||
116 | break; | 124 | break; |
117 | case 'is_top': | 125 | case 'is_top': |
118 | - return \yii\helpers\Url::to(['manage/is_top', 'id' => $model->product_id]); | 126 | + return \yii\helpers\Url::to([ |
127 | + 'manage/is_top', | ||
128 | + 'id' => $model->product_id, | ||
129 | + ]); | ||
119 | break; | 130 | break; |
120 | case 'is_new': | 131 | case 'is_new': |
121 | - return \yii\helpers\Url::to(['manage/is_new', 'id' => $model->product_id]); | 132 | + return \yii\helpers\Url::to([ |
133 | + 'manage/is_new', | ||
134 | + 'id' => $model->product_id, | ||
135 | + ]); | ||
122 | break; | 136 | break; |
123 | case 'akciya': | 137 | case 'akciya': |
124 | - return \yii\helpers\Url::to(['manage/akciya', 'id' => $model->product_id]); | 138 | + return \yii\helpers\Url::to([ |
139 | + 'manage/akciya', | ||
140 | + 'id' => $model->product_id, | ||
141 | + ]); | ||
125 | break; | 142 | break; |
126 | case 'view': | 143 | case 'view': |
127 | - return \yii\helpers\Url::to(['manage/view', 'id' => $model->product_id]); | 144 | + return \yii\helpers\Url::to([ |
145 | + 'manage/view', | ||
146 | + 'id' => $model->product_id, | ||
147 | + ]); | ||
128 | break; | 148 | break; |
129 | case 'update': | 149 | case 'update': |
130 | - return \yii\helpers\Url::to(['manage/update', 'id' => $model->product_id]); | 150 | + return \yii\helpers\Url::to([ |
151 | + 'manage/update', | ||
152 | + 'id' => $model->product_id, | ||
153 | + ]); | ||
131 | break; | 154 | break; |
132 | case 'delete': | 155 | case 'delete': |
133 | - return \yii\helpers\Url::to(['manage/delete', 'id' => $model->product_id]); | 156 | + return \yii\helpers\Url::to([ |
157 | + 'manage/delete', | ||
158 | + 'id' => $model->product_id, | ||
159 | + ]); | ||
134 | break; | 160 | break; |
135 | } | 161 | } |
136 | - } | 162 | + }, |
137 | ], | 163 | ], |
138 | ], | 164 | ], |
139 | ]); ?> | 165 | ]); ?> |
common/modules/product/views/variant/_form.php
@@ -53,13 +53,12 @@ $(".dynamicform_wrapper").on("limitReached", function(e, item) { | @@ -53,13 +53,12 @@ $(".dynamicform_wrapper").on("limitReached", function(e, item) { | ||
53 | ->textarea(); ?> | 53 | ->textarea(); ?> |
54 | <?= $form->field($model, 'price_old') | 54 | <?= $form->field($model, 'price_old') |
55 | ->textarea(); ?> | 55 | ->textarea(); ?> |
56 | - <?= $form->field($model, 'image') | 56 | + <?= $form->field($model, 'imagesUpload[]') |
57 | ->widget(\kartik\file\FileInput::className(), [ | 57 | ->widget(\kartik\file\FileInput::className(), [ |
58 | - 'model' => $model, | ||
59 | - 'attribute' => 'image', | 58 | + 'language' => 'ru', |
60 | 'options' => [ | 59 | 'options' => [ |
61 | 'accept' => 'image/*', | 60 | 'accept' => 'image/*', |
62 | - 'multiple' => false, | 61 | + 'multiple' => true, |
63 | ], | 62 | ], |
64 | 'pluginOptions' => [ | 63 | 'pluginOptions' => [ |
65 | 'allowedFileExtensions' => [ | 64 | 'allowedFileExtensions' => [ |
@@ -67,10 +66,13 @@ $(".dynamicform_wrapper").on("limitReached", function(e, item) { | @@ -67,10 +66,13 @@ $(".dynamicform_wrapper").on("limitReached", function(e, item) { | ||
67 | 'gif', | 66 | 'gif', |
68 | 'png', | 67 | 'png', |
69 | ], | 68 | ], |
70 | - 'initialPreview' => $model->imageUrl ? \common\components\artboximage\ArtboxImageHelper::getImage($model->imageUrl, 'products') : '', | ||
71 | - 'overwriteInitial' => true, | ||
72 | - 'showRemove' => true, | 69 | + 'initialPreview' => !empty( $model->imagesHTML ) ? $model->imagesHTML : [], |
70 | + 'initialPreviewConfig' => $model->imagesConfig, | ||
71 | + 'overwriteInitial' => false, | ||
72 | + 'showRemove' => false, | ||
73 | 'showUpload' => false, | 73 | 'showUpload' => false, |
74 | + 'uploadAsync' => !empty( $model->product_variant_id ), | ||
75 | + 'previewFileType' => 'image', | ||
74 | ], | 76 | ], |
75 | ]); ?> | 77 | ]); ?> |
76 | 78 |
console/migrations/m161011_104931_create_stock_lang_table.php
100644 → 100755