DownloadProvider.php 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\State\Provider\Core;
  4. use ApiPlatform\Metadata\GetCollection;
  5. use ApiPlatform\Metadata\Operation;
  6. use ApiPlatform\State\ProviderInterface;
  7. use App\Enum\Core\FileStatusEnum;
  8. use App\Repository\Core\FileRepository;
  9. use App\Service\File\Exception\FileNotFoundException;
  10. use App\Service\File\FileManager;
  11. use Symfony\Component\HttpFoundation\HeaderUtils;
  12. use Symfony\Component\HttpFoundation\RedirectResponse;
  13. use Symfony\Component\HttpFoundation\Response;
  14. /**
  15. * Custom provider pour le téléchargement des fichiers du LocalStorage.
  16. */
  17. final class DownloadProvider implements ProviderInterface
  18. {
  19. public function __construct(
  20. private readonly FileRepository $fileRepository,
  21. private readonly FileManager $fileManager,
  22. ) {
  23. }
  24. /**
  25. * @param array<mixed> $uriVariables
  26. * @param array<mixed> $context
  27. *
  28. * @throws FileNotFoundException
  29. */
  30. public function provide(Operation $operation, array $uriVariables = [], array $context = []): Response|RedirectResponse
  31. {
  32. if ($operation instanceof GetCollection) {
  33. throw new \RuntimeException('not supported', Response::HTTP_METHOD_NOT_ALLOWED);
  34. }
  35. return $this->serveFile($uriVariables['fileId']);
  36. }
  37. /**
  38. * @throws FileNotFoundException
  39. */
  40. protected function serveFile(int $fileId): Response
  41. {
  42. $file = $this->fileRepository->find($fileId);
  43. if (empty($file)) {
  44. throw new \RuntimeException('File '.$fileId.' does not exist; abort.');
  45. }
  46. if ($file->getStatus() !== FileStatusEnum::READY) {
  47. throw new \RuntimeException('File '.$fileId.' has '.$file->getStatus().' status; abort.');
  48. }
  49. $content = $this->fileManager->read($file);
  50. // Build the response and attach the file to it
  51. // @see https://symfony.com/doc/current/components/http_foundation.html#serving-files
  52. $response = new Response($content);
  53. $response->headers->set('Charset', 'UTF-8');
  54. $response->headers->set('Access-Control-Expose-Headers', 'Content-Disposition');
  55. if (!empty($file->getMimeType())) {
  56. $response->headers->set('Content-Type', $file->getMimeType());
  57. }
  58. $response->headers->set(
  59. 'Content-Disposition',
  60. HeaderUtils::makeDisposition(HeaderUtils::DISPOSITION_ATTACHMENT, $file->getName())
  61. );
  62. return $response;
  63. }
  64. }