medialibrary-helper/src/MediaController.php

131 lines
4.7 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\LaravelData\DataCollection;
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);
$collection = $model->getMediaCollection($request->input('collection'));
$isSingle = 1 === $collection->collectionSizeLimit;
$this->authorize('storeMedia', [$model, $collection->name]);
$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']);
$basename = $collection->runCallback('forceFileName', $model, $pathinfo['filename']);
$path = $basename.'.'.$pathinfo['extension'];
$adder = $model
->addMediaFromBase64($c['content'])
->usingName($basename)
->usingFileName($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
{
$this->authorize('updateMedia', [$media->model, $media->collection_name]);
$rules = collect($media->model->getMediaCollection($media->collection_name)->runCallback('withPropertyValidation', $media->file_name))
->mapWithKeys(fn ($rule, $key) => ["properties.{$key}" => $rule])->toArray();
$validated = $request->validate($rules);
$media->update(['custom_properties' => data_get($validated, 'properties', [])]);
return MediaData::from($media);
}
public function index(Request $request, $parentModel, int $parentId, string $collectionName): MediaData|DataCollection
{
$model = app('media-library-helpers')->get($parentModel);
$model = $model::find($parentId);
$this->authorize('listMedia', [$model, $collectionName]);
$collection = $model->getMediaCollection($collectionName);
$isSingle = 1 === $collection->collectionSizeLimit;
abort_if($isSingle && !$model->getFirstMedia($collectionName) && !MediaData::defaultFromCollection($model, $collection), 404);
if ($isSingle && !$model->getFirstMedia($collectionName)) {
return MediaData::defaultFromCollection($model, $collection);
}
return $isSingle
? MediaData::from($model->getFirstMedia($collectionName))
: MediaData::collection($model->getMedia($collectionName));
}
public function destroy(Media $media, Request $request): JsonResponse
{
$this->authorize('destroyMedia', [$media->model, $media->collection_name]);
$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;
}
}