Skip to content

Commit

Permalink
Feature/callback before upload (#105)
Browse files Browse the repository at this point in the history
* add callbacks

* add missing uses

* unit testing

* Delete unused namespace

* typehint callable

* delete callBefore and add callWithReturnTypeCheck

* remove before save exception test

* Delete before upload, add verifyFile and modifySource

* unit tests

* Remove unused exception file and namespaces

* Delete ModifySource

* Add VerifySource to VerifyFile and return true or throw exception

* Update wrong comment

* add documentation

* typehint the source adapter and add params types in description

* Change return type of verifyFile from true to void

* Update documentation of veirfyFile
  • Loading branch information
JulesPrimo authored and frasmage committed May 11, 2018
1 parent a5ae86b commit 6379ded
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 4 deletions.
42 changes: 42 additions & 0 deletions docs/source/uploader.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

::

<?php
$media = MediaUploader::fromSource($request->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.

::

<?php
$media = MediaUploader::fromSource($request->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
--------------------

Expand Down
47 changes: 43 additions & 4 deletions src/MediaUploader.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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'];
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions tests/integration/MediaUploaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down

0 comments on commit 6379ded

Please # to comment.