diff --git a/docs/source/uploader.rst b/docs/source/uploader.rst index 50b5f9d..6bff50a 100644 --- a/docs/source/uploader.rst +++ b/docs/source/uploader.rst @@ -123,6 +123,48 @@ You can override the most validation configuration values set in ``config/mediab ->upload(); +You can also validate the file without uploading it by calling the ``verifyFile`` method. +If the file does not pass validation, an instance of ``Plank\Mediable\MediaUploadException`` will be thrown + +:: + + file('image')) + + // model class to use + ->setModelClass(MediaSubclass::class) + + // maximum filesize in bytes + ->setMaximumSize(99999) + + // only allow files of specific MIME types + ->setAllowedMimeTypes(['image/jpeg']) + + ->verifyFile() + + +Alter Model before upload +------------------------- + +You can manipulate the model before it's saved by passing a callable to the ``beforeSave`` method. +The callback takes two params, ``$model`` an instance of ``Plank\Mediable\Media`` the current model and ``$source`` an instance of ``Plank\Mediable\SourceAdapters\SourceAdapterInterface`` the current source. + +:: + + file('image')) + + // model class to use + ->setModelClass(CustomMediaClass::class) + + // pass the callable + ->beforeSave(function (Media $model, SourceAdapterInterface $source) { + $model->setAttribute('customAttribute', 'value') + }) + + ->upload() + + Handling Exceptions -------------------- diff --git a/src/MediaUploader.php b/src/MediaUploader.php index 762f557..707ba0d 100644 --- a/src/MediaUploader.php +++ b/src/MediaUploader.php @@ -72,6 +72,12 @@ class MediaUploader */ private $hash_filename = false; + /** + * Callable allowing to alter the model before save. + * @var callable + */ + private $before_save; + /** * Constructor. * @param \Illuminate\Filesystem\FilesystemManager $filesystem @@ -423,13 +429,14 @@ public function possibleAggregateTypesForExtension($extension) */ public function upload() { - $this->verifySource(); + $this->verifyFile(); $model = $this->makeModel(); - $model->size = $this->verifyFileSize($this->source->size()); - $model->mime_type = $this->verifyMimeType($this->source->mimeType()); - $model->extension = $this->verifyExtension($this->source->extension()); + $model->size = $this->source->size(); + $model->mime_type = $this->source->mimeType(); + $model->extension = $this->source->extension(); + $model->aggregate_type = $this->inferAggregateType($model->mime_type, $model->extension); $model->disk = $this->disk ?: $this->config['default_disk']; @@ -438,12 +445,27 @@ public function upload() $this->verifyDestination($model); + if (is_callable($this->before_save)) { + call_user_func($this->before_save, $model, $this->source); + } + $this->filesystem->disk($model->disk)->put($model->getDiskPath(), $this->source->contents()); $model->save(); return $model; } + /** + * Set the before save callback + * @param callable $callable + * @return static + */ + public function beforeSave(callable $callable) + { + $this->before_save = $callable; + return $this; + } + /** * Create a `Media` record for a file already on a disk. * @param string $disk @@ -512,6 +534,23 @@ public function update(Media $media) return $dirty; } + /** + * Verify if file is valid + * @throws \Plank\Mediable\Exceptions\MediaUpload\ConfigurationException If no source is provided + * @throws \Plank\Mediable\Exceptions\MediaUpload\FileNotFoundException If the source is invalid + * @throws \Plank\Mediable\Exceptions\MediaUpload\FileSizeException If the file is too large + * @throws \Plank\Mediable\Exceptions\MediaUpload\FileNotSupportedException If the mime type is not allowed + * @throws \Plank\Mediable\Exceptions\MediaUpload\FileNotSupportedException If the file extension is not allowed + * @return void + */ + public function verifyFile() + { + $this->verifySource(); + $this->verifyFileSize($this->source->size()); + $this->verifyMimeType($this->source->mimeType()); + $this->verifyExtension($this->source->extension()); + } + /** * Generate an instance of the `Media` class. * @return \Plank\Mediable\Media diff --git a/tests/integration/MediaUploaderTest.php b/tests/integration/MediaUploaderTest.php index 29f759e..6c4529e 100644 --- a/tests/integration/MediaUploaderTest.php +++ b/tests/integration/MediaUploaderTest.php @@ -422,6 +422,29 @@ public function test_it_use_hash_for_filename() $this->assertEquals('3ef5e70366086147c2695325d79a25cc', $media->filename); } + public function test_it_uploads_files_with_altered_model() + { + $this->useDatabase(); + $this->useFilesystem('tmp'); + + $media = Facade::fromSource(__DIR__ . '/../_data/plank.png') + ->toDestination('tmp', 'foo') + ->useFilename('bar') + ->beforeSave(function ($model) { + $model->id = 9876; + }) + ->upload(); + + $this->assertInstanceOf(Media::class, $media); + $this->assertTrue($media->fileExists()); + $this->assertEquals('tmp', $media->disk); + $this->assertEquals('foo/bar.png', $media->getDiskPath()); + $this->assertEquals('image/png', $media->mime_type); + $this->assertEquals(7173, $media->size); + $this->assertEquals('image', $media->aggregate_type); + $this->assertEquals(9876, $media->id); + } + protected function mockUploader($filesystem = null, $factory = null) { return new MediaUploader(