Compare commits

..

6 Commits

Author SHA1 Message Date
philipp lang 79cb5a8f58 update validation 2024-01-03 00:48:50 +01:00
philipp lang 2e90fde134 Add MediaFile Helper 2024-01-03 00:47:05 +01:00
philipp lang 38c40c48ac Fix Readme 2024-01-03 00:09:55 +01:00
philipp lang 1aeb520b06 Update validation 2024-01-03 00:09:48 +01:00
philipp lang 78143ec0b3 Set protected 2024-01-02 23:48:41 +01:00
philipp lang 194f1f9c14 Move CollectionExtension 2024-01-02 23:47:48 +01:00
6 changed files with 200 additions and 102 deletions

View File

@ -6,7 +6,7 @@ This package creates routes for the popular Medialibrary Package from Spatie ().
In RegisterMediaCollections, you have the following methods available: In RegisterMediaCollections, you have the following methods available:
You can set a filename by default for the file. This accepts the associated Model, as well as the original filename. You should return the new name of the file with the extension (e.g. disc.jpg). You can set a filename by default for the file. This accepts the associated Model, as well as the original basename (without extension). You should return the new name of the file without the extension (e.g. disc).
``` ```
forceFileName(fn ($model, $path) => Str::slug($path)) forceFileName(fn ($model, $path) => Str::slug($path))
@ -25,4 +25,3 @@ You can call whatever you want after an image has been added, modified or delete
.... ....
}) })
``` ```

View File

@ -2,13 +2,8 @@
namespace Zoomyboy\MedialibraryHelper; namespace Zoomyboy\MedialibraryHelper;
use Spatie\MediaLibrary\MediaCollections\MediaCollection;
class CollectionExtension class CollectionExtension
{ {
public function boot(): void
{
MediaCollection::mixin(new class() {
public function forceFileName() public function forceFileName()
{ {
return fn ($callback) => $this->registerCustomCallback('forceFileName', $callback); return fn ($callback) => $this->registerCustomCallback('forceFileName', $callback);
@ -73,7 +68,7 @@ class CollectionExtension
}; };
} }
public function setDefaultCustomCallbacks() protected function setDefaultCustomCallbacks()
{ {
return function () { return function () {
if (property_exists($this, 'customCallbacks')) { if (property_exists($this, 'customCallbacks')) {
@ -92,6 +87,4 @@ class CollectionExtension
]); ]);
}; };
} }
});
}
} }

View File

@ -14,6 +14,7 @@ use Spatie\MediaLibrary\MediaCollections\Exceptions\InvalidBase64Data;
use Spatie\MediaLibrary\MediaCollections\FileAdder; 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;
use Symfony\Component\HttpFoundation\File\File;
class MediaController class MediaController
{ {
@ -22,8 +23,8 @@ class MediaController
public function store(Request $request) public function store(Request $request)
{ {
$request->validate([ $request->validate([
'name' => 'string',
'model' => ['required', 'string', Rule::in(app('media-library-helpers')->keys())], 'model' => ['required', 'string', Rule::in(app('media-library-helpers')->keys())],
'id' => 'required',
]); ]);
$model = $this->validateModel($request); $model = $this->validateModel($request);
@ -33,30 +34,28 @@ class MediaController
$request->validate($isSingle ? [ $request->validate($isSingle ? [
'payload' => 'array', 'payload' => 'array',
'payload.*' => '', 'payload.name' => 'required|string|regex:/\..*$/|max:255',
'payload.name' => 'required|string|max:255',
'payload.content' => 'required|string', 'payload.content' => 'required|string',
] : [ ] : [
'payload' => 'required|array|min:1', 'payload' => 'required|array|min:1',
'payload.*' => 'array', 'payload.*' => 'array',
'payload.*.name' => 'string', 'payload.*.name' => 'required|string|regex:/\..*$/|max:255',
'payload.*.content' => 'string', 'payload.*.content' => 'required|string',
]); ]);
$content = $isSingle ? [$request->input('payload')] : $request->input('payload'); $content = $isSingle ? [$request->input('payload')] : $request->input('payload');
$medias = collect($content)->map(function ($c) use ($collection, $model) { $medias = collect($content)->map(function ($c) use ($collection, $model) {
$pathinfo = pathinfo($c['name']); $file = new MediaFile($c['name']);
$basename = $collection->runCallback('forceFileName', $model, $pathinfo['filename']); $file->setBasename($collection->runCallback('forceFileName', $model, $file->getBasename()));
$path = $basename . '.' . $pathinfo['extension'];
$adder = $this->fileAdderFromData($model, $c['content'], $collection) $adder = $this->fileAdderFromData($model, $c['content'], $collection)
->usingName($basename) ->usingName($file->getBasename())
->usingFileName($path) ->usingFileName($file->getFilename())
->withCustomProperties($collection->runCallback('withDefaultProperties', $path)); ->withCustomProperties($collection->runCallback('withDefaultProperties', $file->getFilename()));
return tap( return tap(
$collection->runCallback('storing', $adder, $path)->toMediaCollection($collection->name), $collection->runCallback('storing', $adder, $file->getFilename())->toMediaCollection($collection->name),
fn ($media) => $collection->runCallback('stored', $media) fn ($media) => $collection->runCallback('stored', $media)
); );
}); });

32
src/MediaFile.php Normal file
View File

@ -0,0 +1,32 @@
<?php
namespace Zoomyboy\MedialibraryHelper;
use Symfony\Component\HttpFoundation\File\File;
class MediaFile
{
public File $file;
public function __construct(string $path)
{
$this->file = new File($path, false);
}
public function getBasename(): string
{
return $this->file->getBasename('.' . $this->file->getExtension());
}
public function setBasename(string $basename): void
{
$newInstance = new self(($this->getPath() ? $this->getPath() . '/' : '') . $basename . '.' . $this->getExtension());
$this->file = $newInstance->file;
}
public function __call($method, $arguments)
{
return $this->file->{$method}(...$arguments);
}
}

View File

@ -4,6 +4,7 @@ namespace Zoomyboy\MedialibraryHelper;
use Illuminate\Routing\Router; use Illuminate\Routing\Router;
use Illuminate\Support\ServiceProvider as BaseServiceProvider; use Illuminate\Support\ServiceProvider as BaseServiceProvider;
use Spatie\MediaLibrary\MediaCollections\MediaCollection;
class ServiceProvider extends BaseServiceProvider class ServiceProvider extends BaseServiceProvider
{ {
@ -23,7 +24,8 @@ class ServiceProvider extends BaseServiceProvider
$router->patch('mediaupload/{media}', [MediaController::class, 'update'])->name('media.update'); $router->patch('mediaupload/{media}', [MediaController::class, 'update'])->name('media.update');
}); });
app(CollectionExtension::class)->boot(); MediaCollection::mixin(app(CollectionExtension::class));
// app(CollectionExtension::class)->boot();
} }
/** /**

View File

@ -35,6 +35,79 @@ test('it uploads a single file to a single file collection', function () {
$response->assertJsonMissingPath('model_id'); $response->assertJsonMissingPath('model_id');
}); });
test('test validation', function (array $attributes, string $messages) {
$this->auth()->registerModel();
$post = $this->newPost();
$content = base64_encode($this->pdfFile()->getContent());
$this->postJson('/mediaupload', [
'model' => 'post',
'id' => $post->id,
'collection' => 'defaultSingleFile',
'payload' => [
'content' => $content,
'name' => 'beispiel bild.jpg',
],
...$attributes
])->assertJsonValidationErrors($messages);
})->with([
'missing collection' => [
['collection' => ''],
'collection'
],
'missing id' => [
['id' => ''],
'id'
],
]);
test('test validation for payload', function () {
$this->auth()->registerModel();
$post = $this->newPost();
$this->postJson('/mediaupload', [
'model' => 'post',
'id' => $post->id,
'collection' => 'defaultSingleFile',
'payload' => [
'content' => '',
'name' => 'beispiel bild.jpg',
],
])->assertJsonValidationErrors('payload.content');
});
test('test validation for name', function () {
$this->auth()->registerModel();
$post = $this->newPost();
$content = base64_encode($this->pdfFile()->getContent());
$this->postJson('/mediaupload', [
'model' => 'post',
'id' => $post->id,
'collection' => 'defaultSingleFile',
'payload' => [
'content' => $content,
'name' => '',
],
])->assertJsonValidationErrors('payload.name');
});
test('test validation for extension', function () {
$this->auth()->registerModel();
$post = $this->newPost();
$content = base64_encode($this->pdfFile()->getContent());
$this->postJson('/mediaupload', [
'model' => 'post',
'id' => $post->id,
'collection' => 'defaultSingleFile',
'payload' => [
'content' => $content,
'name' => 'aaa',
],
])->assertJsonValidationErrors('payload.name');
});
test('it uploads a single image to a single file collection', function () { test('it uploads a single image to a single file collection', function () {
$this->auth()->registerModel(); $this->auth()->registerModel();
$post = $this->newPost(); $post = $this->newPost();