cms/app/Http/Controllers/MediaController.php

63 lines
1.9 KiB
PHP
Raw Normal View History

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use League\Glide\ServerFactory;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\StreamedResponse;
use App\Models\Media;
class MediaController extends Controller
{
/**
* Handle JIT image requests.
*/
public function __invoke(Request $request, string $path)
{
// Check if the file exists in the source directory
if (! Storage::disk('public')->exists("media/{$path}")) {
abort(404);
}
// Try to find focal point in DB
$media = Media::where('filename', basename($path))->first();
$params = $request->all();
if ($media && !isset($params['fit'])) {
// If we have a focal point, default to crop with that focal point if fit is not specified
// Glide uses 'crop-x-y-zoom' or similar, but simpler is just 'fit=crop-center'
// Actually Glide supports 'fit=crop-x-y-zoom'
$params['fit'] = 'crop-' . $media->focal_x . '-' . $media->focal_y . '-1';
}
$server = ServerFactory::create([
'source' => storage_path('app/public/media'),
'cache' => storage_path('app/public/media/cache'),
'driver' => 'gd',
'defaults' => [
'q' => 90,
'fm' => 'webp',
],
]);
$response = new StreamedResponse(function () use ($server, $path, $params) {
$server->outputImage($path, $params);
});
// Set correct content type
$extension = $request->get('fm') ?: pathinfo($path, PATHINFO_EXTENSION);
$mimeType = match ($extension) {
'webp' => 'image/webp',
'avif' => 'image/avif',
'png' => 'image/png',
'gif' => 'image/gif',
default => 'image/jpeg',
};
$response->headers->set('Content-Type', $mimeType);
return $response;
}
}