ldc-ovoteam/app/Http/Controllers/MediaController.php

78 lines
2.4 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Config;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Uwil\Storage\Contracts\StorageService;
use Uwil\Storage\Exceptions\UnexpectedStorageException;
use Uwil\Storage\Lib\ValueObjects\StorageFilePath;
class MediaController extends Controller
{
public function __invoke(string $path, StorageService $storage): StreamedResponse
{
$prefix = Config::string('storage-service.prefix', 'media');
$fullPath = $prefix !== ''
? trim($prefix, '/') . '/' . ltrim($path, '/')
: ltrim($path, '/');
try {
$filePath = new StorageFilePath($fullPath);
} catch (UnexpectedStorageException) {
abort(404, 'Fichier introuvable ou chemin invalide.');
}
$fileStream = $storage->getFile($filePath);
if ($fileStream === null) {
abort(404, 'Fichier introuvable.');
}
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$mimeType = $this->getMimeType($extension);
$headers = [
'Content-Type' => $mimeType,
'Content-Disposition' => 'inline; filename="' . basename($path) . '"',
'Cache-Control' => 'public, max-age=31536000, immutable',
];
$size = $fileStream->getSize();
if ($size !== null) {
$headers['Content-Length'] = (string) $size;
}
return response()->stream(
function () use ($fileStream): void {
$resource = $fileStream->stream();
if (is_resource($resource)) {
fpassthru($resource);
}
},
200,
$headers
);
}
/**
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
*/
private function getMimeType(string $extension): string
{
return match ($extension) {
'png' => 'image/png',
'jpg', 'jpeg' => 'image/jpeg',
'gif' => 'image/gif',
'webp' => 'image/webp',
'pdf' => 'application/pdf',
'svg' => 'image/svg+xml',
'mp4' => 'video/mp4',
'webm' => 'video/webm',
'txt' => 'text/plain',
'csv' => 'text/csv',
default => 'application/octet-stream',
};
}
}