- Added standard Laravel directory structure and configuration. - Included Svelte and Tailwind configuration for the admin interface. - Added core PHPUnit and testing scripts.
63 lines
1.9 KiB
PHP
63 lines
1.9 KiB
PHP
<?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;
|
|
}
|
|
}
|