maxodrom / yii2-upload-behavior
Upload behavior for Yii 2
Installs: 87
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 56
Open Issues: 0
Type:yii2-extension
Requires
- php: >=5.6.0
- yiisoft/yii2: ~2.0.0
Requires (Dev)
- phpunit/dbunit: ~1.0
- phpunit/phpunit: ~4.0
- yiisoft/yii2-imagine: ^2.1
Suggests
- yiisoft/yii2-imagine: Required to use thumbnails processing with UploadImageBehavior
This package is not auto-updated.
Last update: 2024-11-10 06:07:18 UTC
README
This behavior automatically uploads file and fills the specified attribute with a value of the name of the uploaded file. This code is inspired by, but not derived from, https://github.com/yii-dream-team/yii2-upload-behavior.
Installation
The preferred way to install this extension via composer.
Either run
php composer.phar require --prefer-dist maxodrom/yii2-upload-behavior "*"
or add this code line to the require
section of your composer.json
file:
"maxodrom/yii2-upload-behavior": "*"
Usage
Upload file
Attach the behavior in your model:
class Document extends ActiveRecord { /** * @inheritdoc */ public function rules() { return [ ['file', 'file', 'extensions' => 'doc, docx, pdf', 'on' => ['insert', 'update']], ]; } /** * @return \yii\db\ActiveQuery */ public function getCategory() { return $this->hasOne(Category::class, [ 'id' => 'id_category' ]); } /** * @inheritdoc */ function behaviors() { return [ [ 'class' => UploadBehavior::class, 'attribute' => 'file', 'scenarios' => ['insert', 'update'], 'path' => '@webroot/upload/docs/{category.id}', 'url' => '@web/upload/docs/{category.id}', ], ]; } }
Set model scenario in controller action:
class Controller extends Controller { public function actionCreate($id) { $model = $this->findModel($id); $model->setScenario('insert'); // Note! Set upload behavior scenario. ... ... } }
Example view file:
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?> <?= $form->field($model, 'image')->fileInput() ?> <div class="form-group"> <?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?> </div> <?php ActiveForm::end(); ?>
Upload image and create thumbnails
Thumbnails processing requires yiisoft/yii2-imagine to be installed.
Attach the behavior in your model:
class User extends ActiveRecord { /** * @inheritdoc */ public function rules() { return [ ['image', 'image', 'extensions' => 'jpg, jpeg, gif, png', 'on' => ['insert', 'update']], ]; } /** * @inheritdoc */ public function behaviors() { return [ [ 'class' => \mohorev\file\UploadImageBehavior::class, 'attribute' => 'image', 'scenarios' => ['insert', 'update'], 'placeholder' => '@app/modules/user/assets/images/userpic.jpg', 'path' => '@webroot/upload/user/{id}', 'url' => '@web/upload/user/{id}', 'thumbs' => [ 'thumb' => ['width' => 400, 'quality' => 90], 'preview' => ['width' => 200, 'height' => 200], 'news_thumb' => ['width' => 200, 'height' => 200, 'bg_color' => '000'], ], ], ]; } }
Flexible configuration for path and URL generation
More flexible configuration for path
and/or url
behavior properties is that to use
callbacks or array for defining path
or url
generation logic.
I. Via callbacks
/** * @inheritdoc */ public function behaviors() { return [ [ 'class' => \mohorev\file\UploadImageBehavior::class, 'attribute' => 'image', 'scenarios' => ['insert', 'update'], 'placeholder' => '@app/modules/user/assets/images/userpic.jpg', 'path' => function ($model) { /** @var \app\models\UserProfile $model */ $basePath = '@webroot/upload/profiles/'; $path = implode('/', array_slice(str_split(md5($model->id), 2), 0, 2)); return $basePath . $path; }, 'url' => function ($model) { /** @var \app\models\UserProfile $model */ $baseUrl = '@web/upload/profiles/'; $path = implode('/', array_slice(str_split(md5($model->id), 2), 0, 2)); return $baseUrl . $path; }, 'thumbs' => [ 'thumb' => ['width' => 400, 'quality' => 90], 'preview' => ['width' => 200, 'height' => 200], 'news_thumb' => ['width' => 200, 'height' => 200, 'bg_color' => '000'], ], ], ]; }
II. Via array configuration by defining class and its static methods for path/URL generation
/** * @inheritdoc */ public function behaviors() { return [ [ 'class' => \mohorev\file\UploadImageBehavior::class, 'attribute' => 'image', 'scenarios' => ['insert', 'update'], 'placeholder' => '@app/modules/user/assets/images/userpic.jpg', 'path' => [UserProfile::class, 'buildAvatarPath'], 'url' => [UserProfile::class, 'buildAvatarUrl'], 'thumbs' => [ 'thumb' => ['width' => 400, 'quality' => 90], 'preview' => ['width' => 200, 'height' => 200], 'news_thumb' => ['width' => 200, 'height' => 200, 'bg_color' => '000'], ], ], ]; } /** * Define two static methos in your model for path and URL generation */ /** * @param \app\models\UserProfile|\yii\db\ActiveRecord $profile * @return string */ public static function buildAvatarPath(UserProfile $model) { $basePath = '@webroot/upload/profiles/'; $path = implode('/', array_slice(str_split(md5($model->id), 2), 0, 2)); return $basePath . $path; } /** * @param \app\models\UserProfile|\yii\db\ActiveRecord $profile * @return string */ public static function buildAvatarUrl(UserProfile $model) { $baseUrl = '@web/upload/profiles/'; $path = implode('/', array_slice(str_split(md5($model->id), 2), 0, 2)); return $baseUrl . $path; }
Usage in views
Example:
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?> <div class="form-group"> <div class="row"> <div class="col-lg-6"> <!-- Original image --> <?= Html::img($model->getUploadUrl('image'), ['class' => 'img-thumbnail']) ?> </div> <div class="col-lg-4"> <!-- Thumb 1 (thumb profile) --> <?= Html::img($model->getThumbUploadUrl('image'), ['class' => 'img-thumbnail']) ?> </div> <div class="col-lg-2"> <!-- Thumb 2 (preview profile) --> <?= Html::img($model->getThumbUploadUrl('image', 'preview'), ['class' => 'img-thumbnail']) ?> </div> </div> </div> <?= $form->field($model, 'image')->fileInput(['accept' => 'image/*']) ?> <div class="form-group"> <?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?> </div> <?php ActiveForm::end(); ?>
Behavior Options
- attribute - The attribute which holds the attachment
- scenarios - The scenarios in which the behavior will be triggered
- instanceByName - Getting file instance by name, If you use UploadBehavior in
RESTfull
application and you do not need a prefix of the model name, set the propertyinstanceByName = false
, default value isfalse
- path - the base path or path alias to the directory in which to save files.
- url - the base URL or path alias for this file
- generateNewName - Set true or anonymous function takes the old filename and returns a new name, default value is
true
- unlinkOnSave - If
true
current attribute file will be deleted, default value istrue
- unlinkOnDelete - If
true
current attribute file will be deleted after model deletion. - deleteOriginalFile - Only for UploadImageBehavior. If
true
original image file will be deleted after thumbs generating, default value isfalse
.
Attention!
It is prefered to use immutable placeholder in url
and path
options, other words try don't use related attributes that can be changed. There's bad practice. For example:
class Track extends ActiveRecord { public function getArtist() { return $this->hasOne(Artist::class, [ 'id' => 'id_artist' ]); } public function behaviors() { return [ [ 'class' => UploadBehavior::class, 'attribute' => 'image', 'scenarios' => ['default'], 'path' => '@webroot/uploads/{artist.slug}', 'url' => '@web/uploads/{artist.slug}', ], ]; } }
If related model attribute slug
will change, you must change folders' names too, otherwise behavior will works not correctly.