138 lines
4.7 KiB
PHP
138 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\StoreEventMediaRequest;
|
|
use App\Http\Resources\EventMediaResource;
|
|
use App\Models\EventMedia;
|
|
use App\Services\EventMediaImageProcessor;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Response;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class EventMediaController extends Controller
|
|
{
|
|
public function index(Request $request, string $clientId): JsonResponse
|
|
{
|
|
$event = $request->user()->events()
|
|
->where('client_id', $clientId)
|
|
->firstOrFail();
|
|
|
|
return response()->json([
|
|
'data' => EventMediaResource::collection(
|
|
$event->media()->orderBy('created_at')->get()
|
|
),
|
|
]);
|
|
}
|
|
|
|
public function store(
|
|
StoreEventMediaRequest $request,
|
|
EventMediaImageProcessor $processor,
|
|
string $clientId
|
|
): JsonResponse {
|
|
$event = $request->user()->events()
|
|
->where('client_id', $clientId)
|
|
->firstOrFail();
|
|
|
|
$collection = $request->validated('collection') ?? 'gallery';
|
|
$processed = $processor->process($request->file('file'));
|
|
$uuid = (string) str()->uuid();
|
|
$directory = "event-media/{$request->user()->id}/{$event->client_id}";
|
|
$path = "{$directory}/{$uuid}.jpg";
|
|
$previewPath = "{$directory}/{$uuid}_preview.jpg";
|
|
$thumbnailPath = "{$directory}/{$uuid}_thumb.jpg";
|
|
|
|
Storage::disk('local')->put($path, $processed['original']);
|
|
Storage::disk('local')->put($previewPath, $processed['preview']);
|
|
Storage::disk('local')->put($thumbnailPath, $processed['thumbnail']);
|
|
|
|
if ($collection === 'key_image') {
|
|
$this->deleteExistingKeyImages($event->media()->where('collection', 'key_image')->get());
|
|
}
|
|
|
|
$media = $event->media()->create([
|
|
'uuid' => $uuid,
|
|
'user_id' => $request->user()->id,
|
|
'collection' => $collection,
|
|
'name' => $request->file('file')->getClientOriginalName(),
|
|
'mime_type' => $processed['mime_type'],
|
|
'disk' => 'local',
|
|
'path' => $path,
|
|
'thumbnail_path' => $thumbnailPath,
|
|
'preview_path' => $previewPath,
|
|
'size' => $processed['size'],
|
|
'width' => $processed['width'],
|
|
'height' => $processed['height'],
|
|
'thumbnail_width' => $processed['thumbnail_width'],
|
|
'thumbnail_height' => $processed['thumbnail_height'],
|
|
'preview_width' => $processed['preview_width'],
|
|
'preview_height' => $processed['preview_height'],
|
|
]);
|
|
|
|
if ($collection === 'key_image') {
|
|
$event->update(['image' => "/event-media/{$media->id}/thumb"]);
|
|
}
|
|
|
|
return (new EventMediaResource($media))
|
|
->response()
|
|
->setStatusCode(201);
|
|
}
|
|
|
|
public function show(Request $request, EventMedia $media, string $variant): Response
|
|
{
|
|
abort_unless(in_array($variant, ['thumb', 'preview', 'original'], true), 404);
|
|
abort_unless((int) $media->user_id === (int) $request->user()->id, 404);
|
|
|
|
$path = match ($variant) {
|
|
'thumb' => $media->thumbnail_path,
|
|
'preview' => $media->preview_path ?: $media->thumbnail_path,
|
|
default => $media->path,
|
|
};
|
|
|
|
abort_unless(is_string($path) && $path !== '', 404);
|
|
abort_unless(Storage::disk($media->disk)->exists($path), 404);
|
|
|
|
return response(Storage::disk($media->disk)->get($path), 200, [
|
|
'Content-Type' => 'image/jpeg',
|
|
'Cache-Control' => 'private, max-age=604800',
|
|
]);
|
|
}
|
|
|
|
public function destroy(Request $request, string $clientId, EventMedia $media): JsonResponse
|
|
{
|
|
$event = $request->user()->events()
|
|
->where('client_id', $clientId)
|
|
->firstOrFail();
|
|
|
|
abort_unless((int) $media->event_id === (int) $event->id, 404);
|
|
|
|
$wasKeyImage = $media->collection === 'key_image';
|
|
$this->deleteMediaFiles($media);
|
|
$media->delete();
|
|
|
|
if ($wasKeyImage) {
|
|
$event->update(['image' => null]);
|
|
}
|
|
|
|
return response()->json(null, 204);
|
|
}
|
|
|
|
private function deleteExistingKeyImages(iterable $mediaItems): void
|
|
{
|
|
foreach ($mediaItems as $media) {
|
|
$this->deleteMediaFiles($media);
|
|
$media->delete();
|
|
}
|
|
}
|
|
|
|
private function deleteMediaFiles(EventMedia $media): void
|
|
{
|
|
Storage::disk($media->disk)->delete(array_filter([
|
|
$media->path,
|
|
$media->preview_path,
|
|
$media->thumbnail_path,
|
|
]));
|
|
}
|
|
}
|