Add image conversion

This commit is contained in:
philipp lang 2024-07-13 19:38:51 +02:00
parent d2f7f16e88
commit a6c11cdc14
7 changed files with 52 additions and 2 deletions

View File

@ -19,6 +19,11 @@ class CollectionExtension
return fn ($callback) => $this->registerCustomCallback('destroyed', $callback); return fn ($callback) => $this->registerCustomCallback('destroyed', $callback);
} }
public function convert()
{
return fn ($callback) => $this->registerCustomCallback('convert', $callback);
}
public function after() public function after()
{ {
return fn ($callback) => $this->registerCustomCallback('after', $callback); return fn ($callback) => $this->registerCustomCallback('after', $callback);
@ -74,8 +79,10 @@ class CollectionExtension
if (property_exists($this, 'customCallbacks')) { if (property_exists($this, 'customCallbacks')) {
return; return;
} }
$this->convertTo = null;
$this->customCallbacks = collect([ $this->customCallbacks = collect([
'forceFileName' => fn ($model, $name) => $name, 'forceFileName' => fn ($model, $name) => $name,
'convert' => fn () => null,
'maxWidth' => fn ($size) => null, 'maxWidth' => fn ($size) => null,
'stored' => fn ($event) => true, 'stored' => fn ($event) => true,
'after' => fn ($event) => true, 'after' => fn ($event) => true,

View File

@ -85,10 +85,13 @@ class MediaController
$content = $isSingle ? [$request->input('payload')] : $request->input('payload'); $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']); $file = new MediaFile($c['name']);
$tmpFile = $this->storeTemporaryFile($c['content'], $collection); $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()); Storage::disk(config('media-library.temp_disk'))->move($tmpFile, 'media-library/' . $file->getFilename());
return 'media-library/' . $file->getFilename(); return 'media-library/' . $file->getFilename();
}); });
@ -171,10 +174,16 @@ class MediaController
$tmpFile = 'media-library/' . str()->uuid()->toString(); $tmpFile = 'media-library/' . str()->uuid()->toString();
Storage::disk(config('media-library.temp_disk'))->put($tmpFile, $binaryData); 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)) { 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; return $tmpFile;
} }

View File

@ -25,6 +25,12 @@ class MediaFile
$this->file = $newInstance->file; $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) public function __call($method, $arguments)
{ {
return $this->file->{$method}(...$arguments); return $this->file->{$method}(...$arguments);

View File

@ -26,6 +26,28 @@ test('it uploads a deferred file to a collection', function () {
Storage::disk('temp')->assertExists('media-library/beispiel.pdf'); 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 () { test('it stores a file to media library after deferred upload', function () {
Carbon::setTestNow(Carbon::parse('2023-05-06 06:00:00')); Carbon::setTestNow(Carbon::parse('2023-05-06 06:00:00'));
$this->auth()->registerModel()->withoutExceptionHandling(); $this->auth()->registerModel()->withoutExceptionHandling();

View File

@ -27,6 +27,11 @@ class TestCase extends BaseTestCase
return $this->getFile('jpg.jpg', $filename ?: 'jpg.jpg'); 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 protected function getFile(string $location, string $as): File
{ {
$path = __DIR__ . '/stubs/' . $location; $path = __DIR__ . '/stubs/' . $location;

BIN
tests/stubs/png.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

View File

@ -23,6 +23,7 @@ class Post extends Model implements HasMedia
public function registerMediaCollections(): void public function registerMediaCollections(): void
{ {
$this->addMediaCollection('defaultSingleFile')->maxWidth(fn () => 250)->singleFile(); $this->addMediaCollection('defaultSingleFile')->maxWidth(fn () => 250)->singleFile();
$this->addMediaCollection('singleJpegFile')->convert(fn () => 'jpg')->singleFile();
$this->addMediaCollection('conversionsWithDefault') $this->addMediaCollection('conversionsWithDefault')
->singleFile() ->singleFile()