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