118 lines
4.1 KiB
PHP
118 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace Zoomyboy\MedialibraryHelper;
|
|
|
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Validation\Rule;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Spatie\MediaLibrary\HasMedia;
|
|
use Spatie\MediaLibrary\MediaCollections\MediaCollection;
|
|
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
|
|
|
class MediaController
|
|
{
|
|
use AuthorizesRequests;
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$request->validate([
|
|
'name' => 'string',
|
|
'model' => ['required', 'string', Rule::in(app('media-library-helpers')->keys())],
|
|
]);
|
|
|
|
$model = $this->validateModel($request);
|
|
$this->authorize('storeMedia', $model);
|
|
$collection = $model->getMediaCollection($request->input('collection'));
|
|
$isSingle = 1 === $collection->collectionSizeLimit;
|
|
|
|
$request->validate($isSingle ? [
|
|
'payload' => 'array',
|
|
'payload.*' => '',
|
|
'payload.name' => 'required|string|max:255',
|
|
'payload.content' => 'required|string',
|
|
] : [
|
|
'payload' => 'required|array|min:1',
|
|
'payload.*' => 'array',
|
|
'payload.*.name' => 'string',
|
|
'payload.*.content' => 'string',
|
|
]);
|
|
|
|
$content = $isSingle ? [$request->input('payload')] : $request->input('payload');
|
|
|
|
$medias = collect($content)->map(function ($c) use ($collection, $model) {
|
|
$pathinfo = pathinfo($c['name']);
|
|
$path = $collection->runCallback('forceFileName', $pathinfo['filename']).'.'.$pathinfo['extension'];
|
|
Storage::disk('public')->put($path, base64_decode($c['content']));
|
|
$adder = $model
|
|
->addMedia(Storage::disk('public')->path($path))
|
|
->withCustomProperties($collection->runCallback('withDefaultProperties', $path));
|
|
|
|
return tap(
|
|
$collection->runCallback('storing', $adder, $path)->toMediaCollection($collection->name),
|
|
fn ($media) => $collection->runCallback('stored', $media)
|
|
);
|
|
});
|
|
|
|
return $isSingle ? MediaData::from($medias->first()) : MediaData::collection($medias);
|
|
}
|
|
|
|
public function update(Request $request, Media $media): MediaData
|
|
{
|
|
$rules = collect($media->model->getMediaCollection($media->collection_name)->runCallback('withPropertyValidation', $media->file_name))
|
|
->mapWithKeys(fn ($rule, $key) => ["properties.{$key}" => $rule])->toArray();
|
|
|
|
$request->validate($rules);
|
|
|
|
$media->update(['custom_properties' => $request->properties]);
|
|
|
|
return MediaData::from($media);
|
|
}
|
|
|
|
public function index(Request $request, $parentModel, int $parentId, string $collection): JsonResponse
|
|
{
|
|
$model = app('media-library-helpers')->get($parentModel);
|
|
$model = $model::find($parentId);
|
|
$isSingle = $model->getMediaCollection($collection)->collectionSizeLimit;
|
|
|
|
return response()->json([
|
|
'data' => $isSingle ? $model->getFirstMedia($collection) : $model->getMedia($collection)->map(fn ($c) => $c->toArray()),
|
|
]);
|
|
}
|
|
|
|
public function destroy(Media $media, Request $request): JsonResponse
|
|
{
|
|
$this->authorize('destroyMedia', $media->model);
|
|
$media->delete();
|
|
|
|
return response()->json([]);
|
|
}
|
|
|
|
protected function hasCallback(MediaCollection $collection, string $callback): bool
|
|
{
|
|
return property_exists($collection, $callback);
|
|
}
|
|
|
|
protected function validateModel(Request $request): HasMedia
|
|
{
|
|
$model = app('media-library-helpers')->get($request->input('model'));
|
|
|
|
$request->validate([
|
|
'collection' => [
|
|
'required',
|
|
'string',
|
|
Rule::in((new $model())->getRegisteredMediaCollections()->pluck('name')),
|
|
],
|
|
]);
|
|
|
|
$model = $model::find($request->input('id'));
|
|
if (!$model) {
|
|
throw ValidationException::withMessages(['model' => 'nicht gefunden']);
|
|
}
|
|
|
|
return $model;
|
|
}
|
|
}
|