diff --git a/src/CollectionExtension.php b/src/CollectionExtension.php index 4585a8e..92e0807 100644 --- a/src/CollectionExtension.php +++ b/src/CollectionExtension.php @@ -19,6 +19,11 @@ class CollectionExtension return fn ($callback) => $this->registerCustomCallback('destroyed', $callback); } + public function convert() + { + return fn ($callback) => $this->registerCustomCallback('convert', $callback); + } + public function after() { return fn ($callback) => $this->registerCustomCallback('after', $callback); @@ -74,8 +79,10 @@ class CollectionExtension if (property_exists($this, 'customCallbacks')) { return; } + $this->convertTo = null; $this->customCallbacks = collect([ 'forceFileName' => fn ($model, $name) => $name, + 'convert' => fn () => null, 'maxWidth' => fn ($size) => null, 'stored' => fn ($event) => true, 'after' => fn ($event) => true, diff --git a/src/MediaController.php b/src/MediaController.php index 7fc891b..761b97b 100644 --- a/src/MediaController.php +++ b/src/MediaController.php @@ -85,10 +85,13 @@ class MediaController $content = $isSingle ? [$request->input('payload')] : $request->input('payload'); - $tempPaths = collect($content)->map(function ($c) use ($collection, $modelName) { + $tempPaths = collect($content)->map(function ($c) use ($collection) { $file = new MediaFile($c['name']); $tmpFile = $this->storeTemporaryFile($c['content'], $collection); + if ($collection->runCallback('convert') !== null) { + $file->setExtension($collection->runCallback('convert')); + } Storage::disk(config('media-library.temp_disk'))->move($tmpFile, 'media-library/' . $file->getFilename()); return 'media-library/' . $file->getFilename(); }); @@ -171,10 +174,16 @@ class MediaController $tmpFile = 'media-library/' . str()->uuid()->toString(); Storage::disk(config('media-library.temp_disk'))->put($tmpFile, $binaryData); + $image = Image::load(Storage::disk(config('media-library.temp_disk'))->path($tmpFile)); if (null !== $maxWidth && 'image/jpeg' === Storage::disk(config('media-library.temp_disk'))->mimeType($tmpFile)) { - Image::load(Storage::disk(config('media-library.temp_disk'))->path($tmpFile))->width($maxWidth)->save(); + $image->width($maxWidth); } + if ($collection->runCallback('convert') !== null) { + $image->format($collection->runCallback('convert')); + } + $image->save(); + return $tmpFile; } diff --git a/src/MediaFile.php b/src/MediaFile.php index 784ff2a..6d04a14 100644 --- a/src/MediaFile.php +++ b/src/MediaFile.php @@ -25,6 +25,12 @@ class MediaFile $this->file = $newInstance->file; } + public function setExtension(string $extension): void + { + $newInstance = new self(($this->getPath() ? $this->getPath() . '/' : '') . $this->getBasename() . '.' . $extension); + $this->file = $newInstance->file; + } + public function __call($method, $arguments) { return $this->file->{$method}(...$arguments); diff --git a/tests/Feature/DeferredUploadTest.php b/tests/Feature/DeferredUploadTest.php index 03948df..002d3a3 100644 --- a/tests/Feature/DeferredUploadTest.php +++ b/tests/Feature/DeferredUploadTest.php @@ -26,6 +26,28 @@ test('it uploads a deferred file to a collection', function () { Storage::disk('temp')->assertExists('media-library/beispiel.pdf'); }); +test('it forces filename when uploading', function () { + $this->auth()->registerModel()->withoutExceptionHandling(); + + $this->postJson('/mediaupload', [ + 'parent' => ['model' => 'post', 'collection_name' => 'singleJpegFile', 'id' => null], + 'payload' => ['content' => base64_encode($this->pngFile()->getContent()), 'name' => 'beispiel.png'], + ]) + ->assertStatus(201) + ->assertExactJson([ + 'is_deferred' => true, + 'original_url' => Storage::disk('temp')->url('media-library/beispiel.jpg'), + 'name' => 'beispiel', + 'collection_name' => 'singleJpegFile', + 'size' => 366471, + 'file_name' => 'beispiel.jpg', + 'mime_type' => 'image/jpeg', + 'icon' => url('storage/filetypes/imagejpeg.svg'), + ]); + Storage::disk('temp')->assertExists('media-library/beispiel.jpg'); + Storage::disk('temp')->assertMissing('media-library/beispiel.png'); +}); + test('it stores a file to media library after deferred upload', function () { Carbon::setTestNow(Carbon::parse('2023-05-06 06:00:00')); $this->auth()->registerModel()->withoutExceptionHandling(); diff --git a/tests/TestCase.php b/tests/TestCase.php index 7211518..bb1e66c 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -27,6 +27,11 @@ class TestCase extends BaseTestCase return $this->getFile('jpg.jpg', $filename ?: 'jpg.jpg'); } + protected function pngFile(?string $filename = null): File + { + return $this->getFile('png.png', $filename ?: 'png.png'); + } + protected function getFile(string $location, string $as): File { $path = __DIR__ . '/stubs/' . $location; diff --git a/tests/stubs/png.png b/tests/stubs/png.png new file mode 100644 index 0000000..3ec45e5 Binary files /dev/null and b/tests/stubs/png.png differ diff --git a/tests/workbench/app/Models/Post.php b/tests/workbench/app/Models/Post.php index be93974..5764a48 100644 --- a/tests/workbench/app/Models/Post.php +++ b/tests/workbench/app/Models/Post.php @@ -23,6 +23,7 @@ class Post extends Model implements HasMedia public function registerMediaCollections(): void { $this->addMediaCollection('defaultSingleFile')->maxWidth(fn () => 250)->singleFile(); + $this->addMediaCollection('singleJpegFile')->convert(fn () => 'jpg')->singleFile(); $this->addMediaCollection('conversionsWithDefault') ->singleFile()