Add max width to upload

This commit is contained in:
Philipp Lang 2023-05-02 14:23:25 +02:00
parent fb7f70fb12
commit 2473c7c55b
4 changed files with 61 additions and 3 deletions

View File

@ -49,6 +49,11 @@ class CollectionExtension
return fn ($callback) => $this->registerCustomCallback('withFallback', $callback); return fn ($callback) => $this->registerCustomCallback('withFallback', $callback);
} }
public function maxWidth()
{
return fn ($callback) => $this->registerCustomCallback('maxWidth', $callback);
}
public function runCallback() public function runCallback()
{ {
return function (string $callback, ...$parameters) { return function (string $callback, ...$parameters) {
@ -76,6 +81,7 @@ class CollectionExtension
} }
$this->customCallbacks = collect([ $this->customCallbacks = collect([
'forceFileName' => fn ($model, $name) => $name, 'forceFileName' => fn ($model, $name) => $name,
'maxWidth' => fn ($size) => null,
'stored' => fn ($event) => true, 'stored' => fn ($event) => true,
'after' => fn ($event) => true, 'after' => fn ($event) => true,
'destroyed' => fn ($event) => true, 'destroyed' => fn ($event) => true,

View File

@ -7,8 +7,11 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use Spatie\Image\Image;
use Spatie\LaravelData\DataCollection; use Spatie\LaravelData\DataCollection;
use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\MediaCollections\Exceptions\InvalidBase64Data;
use Spatie\MediaLibrary\MediaCollections\FileAdder;
use Spatie\MediaLibrary\MediaCollections\MediaCollection; use Spatie\MediaLibrary\MediaCollections\MediaCollection;
use Spatie\MediaLibrary\MediaCollections\Models\Media; use Spatie\MediaLibrary\MediaCollections\Models\Media;
@ -46,8 +49,8 @@ class MediaController
$pathinfo = pathinfo($c['name']); $pathinfo = pathinfo($c['name']);
$basename = $collection->runCallback('forceFileName', $model, $pathinfo['filename']); $basename = $collection->runCallback('forceFileName', $model, $pathinfo['filename']);
$path = $basename.'.'.$pathinfo['extension']; $path = $basename.'.'.$pathinfo['extension'];
$adder = $model
->addMediaFromBase64($c['content']) $adder = $this->fileAdderFromData($model, $c['content'], $collection)
->usingName($basename) ->usingName($basename)
->usingFileName($path) ->usingFileName($path)
->withCustomProperties($collection->runCallback('withDefaultProperties', $path)); ->withCustomProperties($collection->runCallback('withDefaultProperties', $path));
@ -133,4 +136,34 @@ class MediaController
return $model; return $model;
} }
protected function fileAdderFromData($model, $data, $collection): FileAdder
{
$maxWidth = $collection->runCallback('maxWidth', 9);
if (str_contains($data, ';base64')) {
[$_, $data] = explode(';', $data);
[$_, $data] = explode(',', $data);
}
// strict mode filters for non-base64 alphabet characters
$binaryData = base64_decode($data, true);
if (false === $binaryData) {
throw InvalidBase64Data::create();
}
// decoding and then reencoding should not change the data
if (base64_encode($binaryData) !== $data) {
throw InvalidBase64Data::create();
}
$tmpFile = tempnam(sys_get_temp_dir(), 'media-library');
file_put_contents($tmpFile, $binaryData);
if (null !== $maxWidth && 'image/jpeg' === mime_content_type($tmpFile)) {
Image::load($tmpFile)->width($maxWidth)->save();
}
return $model->addMedia($tmpFile);
}
} }

View File

@ -35,6 +35,25 @@ test('it uploads a single file to a single file collection', function () {
$response->assertJsonMissingPath('model_id'); $response->assertJsonMissingPath('model_id');
}); });
test('it uploads a single image to a single file collection', function () {
$this->auth()->registerModel();
$post = $this->newPost();
$content = base64_encode($this->jpgFile()->getContent());
$response = $this->postJson('/mediaupload', [
'model' => 'post',
'id' => $post->id,
'collection' => 'defaultSingleFile',
'payload' => [
'content' => $content,
'name' => 'beispiel bild.jpg',
],
]);
$response->assertStatus(201);
$this->assertCount(1, $post->getMedia('defaultSingleFile'));
});
test('it forces a filename for a single collection', function () { test('it forces a filename for a single collection', function () {
Carbon::setTestNow(Carbon::parse('2023-04-04 00:00:00')); Carbon::setTestNow(Carbon::parse('2023-04-04 00:00:00'));
$this->auth()->registerModel(); $this->auth()->registerModel();

View File

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