bscheshirwork / yii2-file-upload-behavior
Tool set for upload file and store to the model-depend folder
Installs: 33
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
Type:yii2-extension
Requires
- yiisoft/yii2: >=2.0.15
This package is auto-updated.
Last update: 2024-11-06 21:21:02 UTC
README
Installation
The preferred way to install this extension is through composer.
add
"bscheshirwork/yii2-file-upload-behavior": "@dev"
to the require section of your composer.json
file.
The namespace of module is a
bscheshirwork\fub
Usage
We can add of this elements in some places for complex solution:
In form (also can be combine with model. In this case add fileUpload
and fileSave
to model. See example below)
TagForm.php
use bscheshirwork\fub\FileUploadBehavior; ... public function behaviors() { return [ 'fileUpload' => [ // name is important 'class' => FileUploadBehavior::class, 'attribute' => 'image', 'tempDirectory' => '@storageWeb/images/temp', 'tempDirectoryUrl' => '@storageUrl/images/temp', ], ]; } public function form2Models(): ActiveRecordInterface { $this->getBehavior('fileUpload')->uploadFile(); $this->_model->getBehavior('fileSave')->uploader = $this->getBehavior('fileUpload'); return $this->_model; }
In model
Tag.php
use bscheshirwork\fub\FileSaveBehavior; ... public function behaviors() { return [ 'fileSave' => [ // name is important 'class' => FileSaveBehavior::class, 'directory' => '@storageWeb/images/single', 'directoryUrl' => '@storageUrl/images/single', 'type' => 'tag', 'fileVersions' => [ 'default' => [ 'fileName' => [ /** @see FileSaveBehavior::defaultFileName() */ [FileSaveBehavior::class, 'defaultFileName'], 'extension' => 'svg', ], 'fileUrl' => [ /** @see FileSaveBehavior::defaultFileUrl() */ [FileSaveBehavior::class, 'defaultFileUrl'], 'extension' => 'svg', 'fileNameVersion' => 'default', ], 'postProcessing' => [ /** @see FileSaveBehavior::defaultAttachFileToModel() */ [FileSaveBehavior::class, 'defaultAttachFileToModel'], 'fileNameVersion' => 'default', ], ], ], ], ]; }
In view
_form.php
use bscheshirwork\fub\FileInputWidget; ?> ... <?= $form->field($model, 'image')->widget(FileInputWidget::class, [ 'attributeLabel' => Yii::t('expand-tag', 'Image'), 'buttonLabel' => Yii::t('expand-tag', 'Select tag SVG icon...'), 'deleteButtonLabel' => Yii::t('expand-tag', 'Delete tag SVG icon'), 'template' => "{label}\n{image}\n{tempImage}\n{deleteImageButton}\n<span class='btn btn-primary btn-file'>\n{buttonLabel}\n{input}</span>\n{hint}\n{error}", 'uploader' => $model->getBehavior('fileUpload'), 'saver' => $model->model->getBehavior('fileSave'), 'deleteAction' => 'crud/delete-file', ]) ?>
In controller
CrudController.php
use bscheshirwork\fub\FileDeleteAction; ... public function actions() { return [ 'delete-file' => [ 'class' => FileDeleteAction::class, 'action' => 'delete-file', ], ]; }
Display image
index.php
[ 'label' => Yii::t('expand-tag', 'Image'), 'content' => function ($model) { return $model->fileUrl ? Html::img($model->fileUrl) : ''; }, ],
Advanced usage
In form
BlogForm.php
use bscheshirwork\fub\FileUploadBehavior; ... public function behaviors() { return [ 'fileUpload' => [ // name is important 'class' => FileUploadBehavior::class, 'attribute' => 'image', 'mimeTypeFilter' => 'image/jpeg', 'tempDirectory' => '@storageWeb/images/temp', 'tempDirectoryUrl' => '@storageUrl/images/temp', ], ]; } public function form2Models(): ActiveRecordInterface { $this->getBehavior('fileUpload')->uploadFile(); $this->_model->getBehavior('fileSave')->uploader = $this->getBehavior('fileUpload'); return $this->_model; }
In model
Blog.php
use bscheshirwork\fub\FileSaveBehavior; use bscheshirwork\fub\FileHelper; ... public function behaviors() { return [ 'fileSave' => [ // name is important 'class' => FileSaveBehavior::class, 'directory' => '@storageWeb/images/single', 'directoryUrl' => '@storageUrl/images/single', 'type' => 'blog', 'fileVersions' => [ 'default' => [ 'fileName' => [ /** @see FileSaveBehavior::defaultFileName() */ [FileSaveBehavior::class, 'defaultFileName'], 'extension' => 'jpg', ], 'fileUrl' => [ /** @see FileSaveBehavior::defaultFileUrl() */ [FileSaveBehavior::class, 'defaultFileUrl'], 'extension' => 'jpg', 'fileNameVersion' => 'default', ], 'postProcessing' => [ /** @see BlogArticle::fileUploadDefaultPostProcessing() */ [$this, 'fileUploadDefaultPostProcessing'], 'imaginary' => 'http://imaginary:9000', 'imaginaryDir' => '/images/single', 'format' => 'jpeg', 'extension' => 'jpg', 'fileNameVersion' => 'default', ], ], 'big' => [ 'fileName' => [ /** @see BlogArticle::fileNameForBehavior() */ [$this, 'fileNameForBehavior'], 'extension' => 'jpg', 'suffix' => 'big', ], 'fileUrl' => [ /** @see BlogArticle::fileUrlForBehavior() */ [$this, 'fileUrlForBehavior'], 'extension' => 'jpg', 'suffix' => 'big', 'fileNameVersion' => 'big', ], 'postProcessing' => [ /** @see BlogArticle::fileUploadPostProcessing() */ [$this, 'fileUploadPostProcessing'], 'imaginary' => 'http://imaginary:9000', 'imaginaryDir' => '/images/single', 'width' => 1110, 'height' => 340, 'extension' => 'jpg', 'fileNameVersion' => 'big', ], ], 'small' => [ 'fileName' => [ /** @see BlogArticle::fileNameForBehavior() */ [$this, 'fileNameForBehavior'], 'extension' => 'jpg', 'suffix' => 'small', ], 'fileUrl' => [ /** @see BlogArticle::fileUrlForBehavior() */ [$this, 'fileUrlForBehavior'], 'extension' => 'jpg', 'suffix' => 'small', 'fileNameVersion' => 'small', ], 'postProcessing' => [ /** @see BlogArticle::fileUploadPostProcessing() */ [$this, 'fileUploadPostProcessing'], 'imaginary' => 'http://imaginary:9000', 'imaginaryDir' => '/images/single', 'width' => 350, 'height' => 208, 'extension' => 'jpg', 'fileNameVersion' => 'small', ], ], ], ], ]; } ... public function fileNameForBehavior($extension, $suffix) { /** @var FileSaveBehavior $behavior */ $behavior = $this->getBehavior('fileSave'); if ($fileId = $behavior->getFileId()) { $filePath = Yii::getAlias($behavior->directory) . DIRECTORY_SEPARATOR . $behavior->type . DIRECTORY_SEPARATOR . $fileId . '_' . $suffix . '.' . $extension; return $filePath; } return false; } public function fileUrlForBehavior($extension, $suffix, $version = 'default') { /** @var FileSaveBehavior $behavior */ $behavior = $this->getBehavior('fileSave'); if (($fileId = $behavior->getFileId()) && $behavior->getFilePath($version, true)) { return Yii::getAlias($behavior->directoryUrl) . '/' . $behavior->type . '/' . $fileId . '_' . $suffix . '.' . $extension; } return false; } /** * @param $oldFileName * @param $imaginary * @param $imaginaryDir * @param string $format Specify the image format to output. Possible values are: jpeg, png, webp * @param string $extension * @param string $version */ public function fileUploadDefaultPostProcessing($oldFileName, $imaginary, $imaginaryDir, $format = 'jpeg', $extension = 'jpg', $version = 'default') { /** @var FileSaveBehavior $behavior */ $behavior = $this->getBehavior('fileSave'); $fileId = $behavior->getFileId(); if ($filePath = $behavior->getFilePath($version, false)) { try { FileHelper::unlink($filePath); } catch (ErrorException $exception) { } rename($oldFileName, $filePath); FileHelper::deleteEmptyDirectory($oldFileName); $originalImagePathForImagine = $imaginaryDir . DIRECTORY_SEPARATOR . $behavior->type . DIRECTORY_SEPARATOR . $fileId . '.' . $extension; $httpQuery = http_build_query([ 'file' => $originalImagePathForImagine, 'type' => $format, 'quality' => 100, ]); $url = $imaginary . '/convert?' . $httpQuery; file_put_contents($filePath, file_get_contents($url)); } } public function fileUploadPostProcessing($oldFileName, $imaginary, $imaginaryDir, $width, $height, $extension = 'jpg', $version = 'default') { /** @var FileSaveBehavior $behavior */ $behavior = $this->getBehavior('fileSave'); $fileId = $behavior->getFileId(); if ($filePath = $behavior->getFilePath($version, false)) { try { FileHelper::unlink($filePath); } catch (ErrorException $exception) { } $originalImagePathForImagine = $imaginaryDir . DIRECTORY_SEPARATOR . $behavior->type . DIRECTORY_SEPARATOR . $fileId . '.' . $extension; $httpQuery = http_build_query([ 'file' => $originalImagePathForImagine, 'width' => $width, 'height' => $height, ]); $url = $imaginary . '/crop?' . $httpQuery; file_put_contents($filePath, file_get_contents($url)); } }
Display image
_form.php
<img src="<?= $model->model->getBehavior('fileSave')->getFileUrl('big') ?>">
Single model
in model:
Reason.php
use bscheshirwork\fub\FileUploadBehavior; use bscheshirwork\fub\FileSaveBehavior; ... public function behaviors() { return [ 'fileUpload' => [ // name is important 'class' => FileUploadBehavior::class, 'attribute' => 'image', 'mimeTypeFilter' => ['image/jpeg', 'image/png',], 'tempDirectory' => '@storageWeb/images/temp', 'tempDirectoryUrl' => '@storageUrl/images/temp', ], 'fileSave' => [ // name is important 'class' => FileSaveBehavior::class, 'directory' => '@storageWeb/images/single', 'directoryUrl' => '@storageUrl/images/single', 'type' => 'reason', 'fileVersions' => [ 'default' => [ 'fileName' => [ /** @see FileSaveBehavior::defaultFileName() */ [FileSaveBehavior::class, 'defaultFileName'], 'extension' => 'jpg', ], 'fileUrl' => [ /** @see FileSaveBehavior::defaultFileUrl() */ [FileSaveBehavior::class, 'defaultFileUrl'], 'extension' => 'jpg', 'fileNameVersion' => 'default', ], 'postProcessing' => [ /** @see Reason::fileUploadDefaultPostProcessing() */ [$this, 'fileUploadDefaultPostProcessing'], 'imaginary' => 'http://imaginary:9000', 'imaginaryDir' => '/images/single', 'format' => 'jpeg', 'extension' => 'jpg', 'fileNameVersion' => 'default', ], ], 'small' => [ 'fileName' => [ /** @see Reason::fileNameForBehavior() */ [$this, 'fileNameForBehavior'], 'extension' => 'jpg', 'suffix' => 'small', ], 'fileUrl' => [ /** @see Reason::fileUrlForBehavior() */ [$this, 'fileUrlForBehavior'], 'extension' => 'jpg', 'suffix' => 'small', 'fileNameVersion' => 'small', ], 'postProcessing' => [ /** @see Reason::fileUploadPostProcessing() */ [$this, 'fileUploadPostProcessing'], 'imaginary' => 'http://imaginary:9000', 'imaginaryDir' => '/images/single', 'width' => 350, 'height' => 250, 'extension' => 'jpg', 'fileNameVersion' => 'small', ], ], ], ], ]; } ... /** * {@inheritDoc} */ public function beforeValidate() { $this->getBehavior('fileUpload')->uploadFile(); $this->getBehavior('fileSave')->uploader = $this->getBehavior('fileUpload'); return parent::beforeValidate(); } /** * Return file name for build specific version of file * @param $extension * @param $suffix * @return bool|string */ public function fileNameForBehavior($extension, $suffix) { /** @var FileSaveBehavior $behavior */ $behavior = $this->getBehavior('fileSave'); if ($fileId = $behavior->getFileId()) { $filePath = Yii::getAlias($behavior->directory) . DIRECTORY_SEPARATOR . $behavior->type . DIRECTORY_SEPARATOR . $fileId . '_' . $suffix . '.' . $extension; return $filePath; } return false; } /** * Return URL for specific version of file * @param $extension * @param $suffix * @param string $version * @return bool|string */ public function fileUrlForBehavior($extension, $suffix, $version = 'default') { /** @var FileSaveBehavior $behavior */ $behavior = $this->getBehavior('fileSave'); if (($fileId = $behavior->getFileId()) && $behavior->getFilePath($version, true)) { return Yii::getAlias($behavior->directoryUrl) . '/' . $behavior->type . '/' . $fileId . '_' . $suffix . '.' . $extension; } return false; } /** * First-time save file to model-depend directory and convert to single image form * @param $oldFileName * @param $imaginary * @param $imaginaryDir * @param string $format Specify the image format to output. Possible values are: jpeg, png, webp * @param string $extension * @param string $version */ public function fileUploadDefaultPostProcessing($oldFileName, $imaginary, $imaginaryDir, $format = 'jpeg', $extension = 'jpg', $version = 'default') { /** @var FileSaveBehavior $behavior */ $behavior = $this->getBehavior('fileSave'); $fileId = $behavior->getFileId(); if ($filePath = $behavior->getFilePath($version, false)) { try { FileHelper::unlink($filePath); } catch (ErrorException $exception) { } rename($oldFileName, $filePath); FileHelper::deleteEmptyDirectory($oldFileName); $originalImagePathForImagine = $imaginaryDir . DIRECTORY_SEPARATOR . $behavior->type . DIRECTORY_SEPARATOR . $fileId . '.' . $extension; $httpQuery = http_build_query([ 'file' => $originalImagePathForImagine, 'type' => $format, 'quality' => 100, ]); $url = $imaginary . '/convert?' . $httpQuery; file_put_contents($filePath, file_get_contents($url)); } } /** * Get another version of file. Crop to size. * @param $oldFileName * @param $imaginary * @param $imaginaryDir * @param $width * @param $height * @param string $extension * @param string $version */ public function fileUploadPostProcessing($oldFileName, $imaginary, $imaginaryDir, $width, $height, $extension = 'jpg', $version = 'default') { /** @var FileSaveBehavior $behavior */ $behavior = $this->getBehavior('fileSave'); $fileId = $behavior->getFileId(); if ($filePath = $behavior->getFilePath($version, false)) { try { FileHelper::unlink($filePath); } catch (ErrorException $exception) { } $originalImagePathForImagine = $imaginaryDir . DIRECTORY_SEPARATOR . $behavior->type . DIRECTORY_SEPARATOR . $fileId . '.' . $extension; $httpQuery = http_build_query([ 'file' => $originalImagePathForImagine, 'width' => $width, 'height' => $height, ]); $url = $imaginary . '/crop?' . $httpQuery; file_put_contents($filePath, file_get_contents($url)); } }
in controller:
CrudController.php
use bscheshirwork\fub\FileDeleteAction; ... public function actions() { return [ 'delete-file' => [ 'class' => FileDeleteAction::class, 'action' => 'delete-file', ], ]; }
in view:
_form.php
<?= $form->field($model, 'image')->widget(FileInputWidget::class, [ 'attributeLabel' => Yii::t('reason', 'Image'), 'buttonLabel' => Yii::t('reason', 'Select image...'), 'deleteButtonLabel' => Yii::t('reason', 'Delete images'), 'template' => "{label}\n{image}\n{tempImage}\n{deleteImageButton}\n<span class='btn btn-primary btn-file'>\n{buttonLabel}\n{input}</span>\n{hint}\n{error}", 'uploader' => $model->getBehavior('fileUpload'), 'saver' => $model->getBehavior('fileSave'), 'deleteAction' => 'crud/delete-file', ]) ?>
index.php
<?= GridView::widget([ 'dataProvider' => $dataProvider, 'filterModel' => $searchModel, 'columns' => [ 'id', 'name', [ // main image 'headerOptions' => ['class' => 'image-column'], 'content' => function ($model) { /** @var Reason $model */ return Html::img($model->getBehavior('fileSave')->getFileUrl('small'), ['class' => 'img-fit-to-column']); }, ], [ 'class' => yii\grid\ActionColumn::class, 'template' => '{update} {delete}', ], ], ]); ?>
view.php
<img src="<?= $model->getBehavior('fileSave')->getFileUrl('small') ?>">