diff --git a/README.md b/README.md index ca6aa83..601031e 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,152 @@ -# Upload plugin for CakePHP -## Installation +**Upload plugin for CakePHP 3.x** +============================= +By [Allan Carvalho](https://www.facebook.com/Allan.Mariucci.Carvalho) +--------------------------------------------------------------------- -You can install this plugin into your CakePHP application using [composer](http://getcomposer.org). +# **Installation** +### 1. Installing dependency +You can install this plugin into your CakePHP application using [`composer`](http://getcomposer.org). The recommended way to install composer packages is: +```bacth +composer require allanmcarvalho/upload +``` + +### 2. Loading plugin +In `App\config\bootstrap.php` +```php +Plugin::load('Upload', ['bootstrap' => true]); ``` -composer allanmcarvalho/upload + +# **Basic usage** + +#### **1** - You should open the table and then add the `behavior` of the plugin **Upload**. + + +```php +// in App\Model\Table\ExamplesTable.php +class ExamplesTable extends Table +{ +... + public function initialize(array $config) + { + parent::initialize($config); + + $this->addBehavior('Upload.Upload', [ + 'file1' => [], + 'file2' => [] + ]); + } +... +``` +> **Note:** +> Just adding the `Upload.Upload` **Behavior** does not mean it's ready, in fact, if you just add, nothing will happen. You must define which table columns are going to be responsible for storing the file name as shown above (`file1` and `file2`). + +####**2** - Now should open the view from the form and configure the `form` and `input` to be of the file type. + +```php +// in App\Template\Controller\add.ctp +... + Form->create($example, ['type' => 'file']) ?> + Form->control('title') ?> + Form->control('file1', ['type' => 'file']) ?> + Form->control('file2', ['type' => 'file']) ?> + Form->button(__('Submit')) ?> + Form->end() ?> +... +``` + +### Available **Behavior** settings + + - **path:** + +```php +// in App\Model\Table\ExamplesTable.php + + $this->addBehavior('Upload.Upload', [ + 'file1' => [ + 'path' => WWW_ROOT . 'img' . DS, + 'prefix' => 'example_' + ] + ]); ``` +> **Options** +> +> - **path:** The path where that file will be saved. + +>> **Note:** +>> When `path` is not provided, the default is `WWW_ROOT . 'files' . DS . $this->table->getAlias() . DS` or `WWW_ROOT . 'img' . DS . $this->table->getAlias() . DS` when the `image` setting is set. +> +> - **prefix:** A prefix to be added to the image file name. Default: **Does not have**; + + +---------- + + + - **image:** Set of settings for image uploads; + +```php +// in App\Model\Table\ExamplesTable.php + + $this->addBehavior('Upload.Upload', [ + 'file1' => [ + 'image' => [ + 'format' => 'jpg', + 'quality' => 75, + 'watermark' => WWW_ROOT . 'img' . DS . 'watermark.png', + 'watermark_position' => 'bottom-right' + 'thumbnails' => [ // Optional + [ + 'width' => 450, + 'height' => 400, + ], + [ + 'width' => 225, + 'height' => 200, + 'watermark' => false; + ] + ], + ], + 'prefix' => 'cover_' + ] + ]); +``` +> **Image options:** +> +> - **crop:** (optional) Crop the image. Default: **Does not have**; + - **width:** (required) The crop image width. Default: **Does not have**; + - **height:** (required) The crop image height. Default: **Does not have**; + - **format:** Image format. It can be (jpg, png, gif). Default: `jpg`; + - **quality:** Image quality from 1 to 100. Default: `100`; + - **resize:** (optional) Changes the image size. Default: **Does not have**; + - **width:** (optional) New image width. Default: **If height is set is automatic**; + - **height:** (optional) New image height. Default: **If width is set is automatic**; + - **crop:** (optional) Crop the new image. Default: **Does not have**; + - **width:** (required) New image crop width. Default:**Does not have**; + - **height:** (required) New image height. Default: **Does not have**; + - **thumbnails:** (optional) Setting to set thumbnails to be created. Default: **Does not have**; + - **width:** (required) Thumbnail width. Default: **Does not have**; + - **height:** (required) Thumbnail height. Default: **Does not have**; + - **watermark:** (optional) Sets whether the thumbnail will have the same watermark as the original image (if the original has). Default: `true`; + - **watermark:** (optional) Watermak full file path. Default: **Does not have**; + - **watermark_position:** (optional) Watermak orientation. Default: `bottom-right`. It can be: + - **top-left** + - **top** + - **top-right** + - **left** + - **center** + - **right** + - **bottom-left** + - **bottom** + - **bottom-right** + + +License + + +---------- + + +MIT \ No newline at end of file diff --git a/src/File/Writer/DefaultWriter.php b/src/File/Writer/DefaultWriter.php index 51bf4a4..53d2488 100644 --- a/src/File/Writer/DefaultWriter.php +++ b/src/File/Writer/DefaultWriter.php @@ -13,14 +13,13 @@ use Cake\Filesystem\File; use Cake\Filesystem\Folder; use Cake\Utility\Hash; -use Intervention\Image\ImageManager; /** * Description of DefaultWriter * * @author allancarvalho */ -class DefaultWriter implements WriterInterface +abstract class DefaultWriter implements WriterInterface { /** @@ -59,11 +58,17 @@ class DefaultWriter implements WriterInterface */ protected $defaultPath = ''; + /** + * Destination file path + * @var string + */ + protected $path = null; + /** * Final file name * @var string */ - protected $fileName = null; + protected $filename = null; /** * Construct Method @@ -78,62 +83,134 @@ public function __construct(Table $table, Entity $entity, $field, $settings) $this->entity = $entity; $this->field = $field; $this->settings = $settings; - $this->fileInfo = $this->entity->get($this->field); + $this->fileInfo = (array) $this->entity->get($this->field); $this->defaultPath = WWW_ROOT . 'files' . DS . $this->table->getAlias() . DS; } - public function write() + /** + * Delete a file from path + * @param string $PathAndFilename + * @return boolean + */ + protected function _delete($path, $filename) { - + $file = new File($path . $filename); + if ($file->exists()) + { + if (!$file->delete()) + { + \Cake\Log\Log::error(__d('upload', 'Unable to delete file "{0}" in entity id "{1}" from table "{2}" and path "{3}"', $filename, $this->entity->get($this->table->getPrimaryKey()), $this->table->getTable(), $path)); + return false; + } + } else + { + \Cake\Log\Log::error(__d('upload', 'Unable to delete file "{0}" in entity id "{1}" from table "{2}" and path "{3}" because it does not exist', $filename, $this->entity->get($this->table->getPrimaryKey()), $this->table->getTable(), $path)); + return false; + } + return true; } - public function delete() + /** + * Get a path to save file + * @return string + */ + protected function getPath($subDirectory = null) { - + if ($this->path === null) + { + $path = Hash::get($this->settings, 'path', $this->defaultPath); + $this->path = empty($path) ? $this->defaultPath : (substr($path, -1) === DS ? $path : $path . DS); + + if (!is_dir($this->path)) + { + $this->createFolderIfItNotExists($this->path); + } + } + + if ($subDirectory !== null) + { + $subDirectory = substr($subDirectory, -1) === DS ? $subDirectory : $subDirectory . DS; + $this->createFolderIfItNotExists($this->path . $subDirectory); + return $this->path . $subDirectory; + } else + { + return $this->path; + } } /** - * Get a path to save file - * @return string + * Create a folder if it not exist + * @param string $path */ - protected function getPath() + protected function createFolderIfItNotExists($path) { - $path = Hash::get($this->settings, 'path', $this->defaultPath); + if (!new Folder($path, true)) + { + \Cake\Log\Log::error(__d('upload', 'Unable to create directory: {0}', $path)); + } + } - return empty($path) ? $this->defaultPath : (substr($path, -1) === DS ? $path : $path . DS); + /** + * get a image save format from behavior config + * @return type + */ + protected function getConfigFileFormat() + { + if (Hash::get($this->settings, 'image', false)) + { + $fileExtension = Hash::get($this->settings, 'image.format', 'jpg'); + return substr($fileExtension, 0, 1) === '.' ? $fileExtension : '.' . $fileExtension; + } else + { + $fileExtension = pathinfo(Hash::get($this->fileInfo, 'name', 'err'), PATHINFO_EXTENSION); + return substr($fileExtension, 0, 1) === '.' ? $fileExtension : '.' . $fileExtension; + } } /** - * Check if path exist - * @param bool $create Create a path if not exist + * Create a new filename + * @param bool $ifExistCreateNew if true force to create a new filename + * @return string */ - protected function checkPath($create = true) - { - if (!new Folder($this->getPath(), $create)) + protected function createFilename($ifExistCreateNew = false) + { + if ($this->filename === null) + { + $filePrefix = Hash::get($this->settings, 'prefix', ''); + $fileUniqidMoreEntropy = Hash::get($this->settings, 'more_entropy', true); + $this->filename = Hash::get($this->settings, 'filename', uniqid($filePrefix, $fileUniqidMoreEntropy)) . $this->getConfigFileFormat(); + } elseif ($ifExistCreateNew === true) { - \Cake\Log\Log::error(__d('upload', 'Unable to create directory: {0}', $this->getPath())); + $filePrefix = Hash::get($this->settings, 'prefix', ''); + $fileUniqidMoreEntropy = Hash::get($this->settings, 'more_entropy', true); + $this->filename = Hash::get($this->settings, 'filename', uniqid($filePrefix, $fileUniqidMoreEntropy)) . $this->getConfigFileFormat(); } + + return $this->filename; } /** * Return a file name * @return string */ - protected function getFileName() + protected function getFilename() { - if (debug_backtrace()[1]['function'] == 'write') + if ($this->filename === null) { - if ($this->fileName === null) + if ($this->entity->isNew()) + { + $this->createFilename(); + } elseif (is_array($this->entity->get($this->field))) + { + $entity = $this->table->get($this->entity->get($this->table->getPrimaryKey())); + $this->filename = $entity->get($this->field); + } else { - $filePrefix = Hash::get($this->settings, 'prefix', ''); - $fileUniqidMoreEntropy = Hash::get($this->settings, 'more_entropy', true); - $this->fileName = Hash::get($this->settings, 'filename', uniqid($filePrefix, $fileUniqidMoreEntropy)); + $this->filename = $this->entity->get($this->field); } - }elseif(debug_backtrace()[1]['function'] == 'delete') - { - $this->fileName = $this->entity->get($this->field); } - return $this->fileName; + + return $this->filename; } } diff --git a/src/File/Writer/FileWriter.php b/src/File/Writer/FileWriter.php index 8a16ed4..4e7d83b 100644 --- a/src/File/Writer/FileWriter.php +++ b/src/File/Writer/FileWriter.php @@ -8,9 +8,9 @@ namespace Upload\File\Writer; +use Cake\ORM\Table; +use Cake\ORM\Entity; use Cake\Filesystem\File; -use Cake\Utility\Hash; -use Cake\Log\Log; /** * Description of DefaultWriter @@ -20,41 +20,52 @@ class FileWriter extends DefaultWriter { - public function write() + + + public function __construct(Table $table, Entity $entity, $field, $settings) { - $this->checkPath(); - $file = new File($this->fileInfo['tmp_name']); + parent::__construct($table, $entity, $field, $settings); + $this->defaultPath = WWW_ROOT . 'file' . DS . $this->table->getAlias() . DS; + } - if($file->copy("{$this->getPath()}{$this->getFileName()}{$this->getFileFormat()}")) - { - $this->entity->set($this->field, "{$this->getFileName()}{$this->getFileFormat()}"); - return true; - }else + public function write() + { + if (!$this->entity->isNew()) { - Log::error(__d('upload', 'Unable to save file "{0}" in path "{1}"', $this->getFileName(), $this->getPath())); - return false; + $this->delete(true); + $this->createFilename(true); } - } + $file = new File($this->fileInfo['tmp_name'], true); - public function delete() - { - $file = new File("{$this->getPath()}{$this->getFileName()}"); - if ($file->exists()) + if ($file->copy("{$this->getPath()}{$this->getFilename()}")) { - if (!$file->delete()) - { - Log::error(__d('upload', 'Unable to delete file "{0}" in path "{1}"', $this->getFileName(), $this->getPath())); - } + return $this->entity->set($this->field, "{$this->getFileName()}"); } else { - Log::error(__d('upload', 'Unable to delete file "{0}" in path "{1}" because it does not exist', $this->getFileName(), $this->getPath())); + \Cake\Log\Log::error(__d('upload', 'Unable to salve file "{0}" in entity id "{1}" from table "{2}" and path "{3}" because it does not exist', $this->getFileName(), $this->entity->get($this->table->getPrimaryKey()), $this->table->getTable(), $this->getPath())); + return false; } } - private function getFileFormat() + /** + * Delete method that delete primary and thumbnails images + */ + public function delete($isUptade = false) { - return '.' . pathinfo($this->fileInfo['name'], PATHINFO_EXTENSION); + if($isUptade === false) + { + $entity = &$this->entity; + }else + { + $entity = $this->table->get($this->entity->get($this->table->getPrimaryKey())); + } + + if (!empty($entity->get($this->field))) + { + $filename = $entity->get($this->field); + return $this->_delete($this->getPath(), $filename); + } } } diff --git a/src/File/Writer/ImageWriter.php b/src/File/Writer/ImageWriter.php index 64895cf..2f0ea70 100644 --- a/src/File/Writer/ImageWriter.php +++ b/src/File/Writer/ImageWriter.php @@ -10,9 +10,10 @@ use Cake\ORM\Table; use Cake\ORM\Entity; +use Cake\Filesystem\Folder; use Cake\Filesystem\File; use Cake\Utility\Hash; -use Intervention\Image\ImageManager; +use Upload\File\Writer\Traits\ImageTrait; /** * Description of DefaultWriter @@ -22,50 +23,92 @@ class ImageWriter extends DefaultWriter { - private $maxHeigth = false; - private $maxWidth = false; + use ImageTrait; + + private $resize_heigth = false; + private $resize_width = false; + private $crop_heigth = false; + private $crop_width = false; + private $crop_x = false; + private $crop_y = false; private $watermark = false; private $watermarkPosition = false; + private $thumbnails = []; public function __construct(Table $table, Entity $entity, $field, $settings) { parent::__construct($table, $entity, $field, $settings); $this->defaultPath = WWW_ROOT . 'img' . DS . $this->table->getAlias() . DS; + + $this->resize_heigth = Hash::get($this->settings, 'image.resize.height', false); + $this->resize_width = Hash::get($this->settings, 'image.resize.width', false); + $this->crop_heigth = Hash::get($this->settings, 'image.crop.height', false); + $this->crop_width = Hash::get($this->settings, 'image.crop.width', false); + $this->crop_x = Hash::get($this->settings, 'image.crop.x', null); + $this->crop_y = Hash::get($this->settings, 'image.crop.y', null); + $this->watermark = Hash::get($this->settings, 'image.watermark', false); + $this->watermarkPosition = Hash::get($this->settings, 'image.watermark_position', 'bottom-right'); + $this->thumbnails = Hash::get($this->settings, 'image.thumbnails', []); } public function write() { - $this->checkPath(); - $image = $this->getImage($this->fileInfo['tmp_name']); + if (!$this->entity->isNew()) + { + $this->delete(true); + $this->createFilename(true); + } - $this->maxHeigth = Hash::get($this->settings, 'image.max_height', false); - $this->maxWidth = Hash::get($this->settings, 'image.max_width', false); - $this->watermark = Hash::get($this->settings, 'image.watermark', false); - $this->watermarkPosition = Hash::get($this->settings, 'image.watermark_position', 'bottom-right'); - $image = $this->modifyImage($image); - if ($image->save("{$this->getPath()}{$this->getFileName()}{$this->getImageFormat()}", $this->getImageQuality())) + $image = $this->getImage($this->fileInfo['tmp_name']); + + $this->modifyImage($image); + + if ($image->save("{$this->getPath()}{$this->getFilename()}", $this->getConfigImageQuality())) { - return $this->entity->set($this->field, "{$this->getFileName()}{$this->getImageFormat()}"); + return $this->entity->set($this->field, "{$this->getFileName()}"); } else { + \Cake\Log\Log::error(__d('upload', 'Unable to salve image "{0}" in entity id "{1}" from table "{2}" and path "{3}" because it does not exist', $this->getFileName(), $this->entity->get($this->table->getPrimaryKey()), $this->table->getTable(), $this->getPath())); return false; } } - public function delete() + /** + * Delete method that delete primary and thumbnails images + */ + public function delete($isUptade = false) { - $file = new File("{$this->getPath()}{$this->getFileName()}"); - if ($file->exists()) + if ($isUptade === false) { - if (!$file->delete()) - { - \Cake\Log\Log::error(__d('upload', 'Unable to delete file "{0}" in path "{1}"', $this->getFileName(), $this->getPath())); - } + $entity = &$this->entity; } else { - \Cake\Log\Log::error(__d('upload', 'Unable to delete file "{0}" in path "{1}" because it does not exist', $this->getFileName(), $this->getPath())); + $entity = $this->table->get($this->entity->get($this->table->getPrimaryKey())); + } + + if (!empty($entity->get($this->field))) + { + $filename = $entity->get($this->field); + $this->_delete($this->getPath(), $filename); + $result = false; + foreach ($this->thumbnails as $thumbnail) + { + $width = Hash::get($thumbnail, 'width'); + $height = Hash::get($thumbnail, 'height'); + $cropWidth = Hash::get($thumbnail, 'crop.width', false); + $cropHeight = Hash::get($thumbnail, 'crop.height', false); + + if ($cropWidth !== false and $cropHeight !== false) + { + $result = $this->_delete($this->getPath("{$cropWidth}x{$cropHeight}"), $filename); + } else + { + $result = $this->_delete($this->getPath("{$width}x{$height}"), $filename); + } + } + return $result; } } @@ -76,100 +119,32 @@ public function delete() */ private function modifyImage($image) { - if ($this->maxHeigth !== false) + if ($this->resize_width !== false or $this->resize_heigth !== false) { - if ($this->maxHeigth < $image->height()) - { - $image = $this->maxHeight($image, $this->maxHeigth); - } + $this->resize($image, $this->resize_width, $this->resize_heigth); } - if ($this->maxWidth !== false) + if ($this->crop_width !== false and $this->crop_heigth !== false) { - if ($this->maxWidth < $image->width()) - { - $image = $this->maxWidth($image, $this->maxWidth); - } + $this->crop($image, $this->crop_width, $this->crop_heigth, $this->crop_x, $this->crop_y); } - if ($this->watermark !== false) + if ($this->thumbnails !== false) { - $image = $this->insertWatermark($image, $this->watermark, $this->watermarkPosition); + $this->createThumbnails(clone $image); } - - return $image; - } - - /** - * Get a Intervention image object - * @param string $path - * @return \Intervention\Image\Image - */ - private function getImage($path) - { - $manager = new ImageManager(); - return $manager->make($path); - } - - /** - * Set a max width of image if it is smaller than original - * @param \Intervention\Image\Image $image - * @return \Intervention\Image\Image - */ - private function maxWidth($image, $width) - { - $image->resize($width, null, function ($constraint) - { - $constraint->aspectRatio(); - }); - - return $image; - } - - /** - * Set a max height of image if it is smaller than original - * @param \Intervention\Image\Image $image - * @return \Intervention\Image\Image - */ - private function maxHeight($image, $heigt) - { - - $image->resize(null, $heigt, function ($constraint) + + if ($this->watermark !== false) { - $constraint->aspectRatio(); - }); - - return $image; + $this->insertWatermark($image, $this->watermark, $this->watermarkPosition); + } } /** - * Insert a watermark in image - * @param \Intervention\Image\Image $image - * @param string $path - * @param string $position - * @return \Intervention\Image\Image + * get a image quality from behavior config + * @return type */ - public function insertWatermark($image, $path, $position) - { - $watermark = $this->getImage($path); - - if($watermark->height() > intval($image->height() * 0.07)) - { - $watermark = $this->maxHeight($watermark, intval($image->height() * 0.07)); - } - - $image->insert($watermark, $position, $image->width() * 0.05, $image->height() * 0.05); - - return $image; - } - - private function getImageFormat() - { - $imageFormat = Hash::get($this->settings, 'image.format', 'jpg'); - return substr($imageFormat, 0, 1) === '.' ? $imageFormat : '.' . $imageFormat; - } - - private function getImageQuality() + private function getConfigImageQuality() { return Hash::get($this->settings, 'image.quality', 100); } diff --git a/src/File/Writer/Traits/ImageTrait.php b/src/File/Writer/Traits/ImageTrait.php new file mode 100644 index 0000000..394c896 --- /dev/null +++ b/src/File/Writer/Traits/ImageTrait.php @@ -0,0 +1,151 @@ +getManager()->make($path); + } + + /** + * Resize a imagem based in + * @param Image $image + * @param mixed $width must by smaller than the original + * @param mixed $height must by smaller than the original + * @return Image + */ + protected function resize($image, $width, $height) + { + if ($width != false and $height != false) + { + if ($width < $image->width() and $height < $image->height()) + { + $image->resize($width, $height); + } + } elseif ($width != false) + { + if ($width < $image->width()) + { + $image->resize($width, null, function ($constraint) + { + $constraint->aspectRatio(); + }); + } + } elseif ($height != false) + { + if ($height < $image->height()) + { + $image->resize(null, $height, function ($constraint) + { + $constraint->aspectRatio(); + }); + } + } + return $image; + } + + /** + * Crop a image + * @param Image $image + * @param mixed $width + * @param mixed $height + * @return Image + */ + protected function crop($image, $width, $height, $x, $y) + { + $image->crop($width, $height, $x, $y); + } + + /** + * Insert a watermark in image + * @param \Intervention\Image\Image $image + * @param string $path + * @param string $position + * @return \Intervention\Image\Image + */ + protected function insertWatermark($image, $path, $position) + { + $watermark = $this->getImage($path); + $targetWarthermarkSize = intval($image->height() * 0.07); + if ($watermark->height() > $targetWarthermarkSize) + { + $watermark = $this->resize($watermark, null, $targetWarthermarkSize); + } + + $image->insert($watermark, $position, intval($image->width() * 0.05), intval($image->height() * 0.05)); + } + + /** + * + * @param \Intervention\Image\Image $thumbnailImage + * @return boolean + */ + protected function createThumbnails($thumbnailImage) + { + foreach ($this->thumbnails as $thumbnail) + { + $width = Hash::get($thumbnail, 'width'); + $height = Hash::get($thumbnail, 'height'); + $cropWidth = Hash::get($thumbnail, 'crop.width', false); + $cropHeight = Hash::get($thumbnail, 'crop.height', false); + $cropX = Hash::get($thumbnail, 'crop.x', null); + $cropY = Hash::get($thumbnail, 'crop.y', null); + + $this->resize($thumbnailImage, $width, $height); + + if ($cropWidth !== false and $cropHeight !== false) + { + $this->crop($thumbnailImage, $cropWidth, $cropHeight, $cropX, $cropY); + $thumbnailPath = $this->getPath("{$cropWidth}x{$cropHeight}"); + } else + { + $thumbnailPath = $this->getPath("{$width}x{$height}"); + } + + if (Hash::get($thumbnail, 'watermark', true)) + { + if ($this->watermark !== false) + { + $this->insertWatermark($thumbnailImage, $this->watermark, $this->watermarkPosition); + } + } + if (!$thumbnailImage->save($thumbnailPath . $this->getFilename(), $this->getConfigImageQuality())) + { + \Cake\Log\Log::error(__d('upload', 'Unable to salve thumbnail "{0}" in entity id "{1}" from table "{2}" and path "{3}" because it does not exist', $this->getFileName(), $this->entity->get($this->table->getPrimaryKey()), $this->table->getTable(), $this->getPath())); + } + } + } + +} diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 3d365cc..0825b94 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -71,11 +71,9 @@ public function beforeMarshal(Event $event, \ArrayObject $data, \ArrayObject $op public function beforeSave(Event $event, EntityInterface $entity, \ArrayObject $options) { - foreach ($this->getConfig() as $field => $settings) { - - if ($entity->has($field)) + if ($entity->has($field) and $entity->dirty($field)) { if (Hash::get((array) $entity->get($field), 'error') !== UPLOAD_ERR_OK) { @@ -84,7 +82,7 @@ public function beforeSave(Event $event, EntityInterface $entity, \ArrayObject $ } $writer = $this->getWriter($entity, $field, $settings); - if(!$writer->write()) + if (!$writer->write()) { return false; } @@ -94,14 +92,74 @@ public function beforeSave(Event $event, EntityInterface $entity, \ArrayObject $ public function afterDelete(Event $event, Entity $entity, \ArrayObject $options) { - foreach ($this->config() as $field => $settings) + foreach ($this->getConfig() as $field => $settings) { if ($entity->has($field)) { $writer = $this->getWriter($entity, $field, $settings); - $writer->delete(); + if (!$writer->delete()) + { + $result = false; + } } } + if (isset($result)) + { + return $result; + } + } + + /** + * Delete file(s) without delete entity + * @param EntityInterface $entity + * @param array $fields + * @return boolean + */ + public function deleteFiles($entity, $fields = []) + { + if (empty($fields)) + { + $configs = $this->getConfig(); + } else + { + foreach ($fields as $field => $settings) + { + if (is_int($field)) + { + $configs[$settings] = []; + } else + { + $configs[$field] = $settings; + } + } + $configs = array_intersect_key($this->getConfig(), $configs); + } + + if (empty($configs)) + { + return false; + } + + $result = true; + foreach ($configs as $field => $settings) + { + if (!empty($entity->get($field))) + { + $writer = $this->getWriter($entity, $field, $settings); + if (!$writer->delete()) + { + $result = false; + } + $entity->set($field, null); + } + } + + if (!$this->_table->save($entity)) + { + return false; + } + + return $result; } /**