DownloadRequestProvider.php 2.7 KB

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