DownloadRequestProvider.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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\DownloadRequest;
  8. use App\Enum\Core\FileStatusEnum;
  9. use App\Repository\Core\FileRepository;
  10. use App\Service\File\Exception\FileNotFoundException;
  11. use App\Service\File\FileManager;
  12. use RuntimeException;
  13. use Symfony\Component\HttpFoundation\HeaderUtils;
  14. use Symfony\Component\HttpFoundation\RedirectResponse;
  15. use Symfony\Component\HttpFoundation\Response;
  16. use Symfony\Bundle\SecurityBundle\Security;
  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 FileRepository $fileRepository,
  24. private FileManager $fileManager,
  25. private Security $security,
  26. )
  27. {}
  28. /**
  29. * @param string $resourceClass
  30. * @param string|null $operationName
  31. * @param mixed[] $context
  32. * @return bool
  33. */
  34. public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
  35. {
  36. return DownloadRequest::class === $resourceClass;
  37. }
  38. /**
  39. * @param Operation $operation
  40. * @param mixed[] $uriVariables
  41. * @param mixed[] $context
  42. * @return Response|RedirectResponse
  43. * @throws FileNotFoundException
  44. */
  45. public function provide(Operation $operation, array $uriVariables = [], array $context = []): Response | RedirectResponse
  46. {
  47. if($operation instanceof GetCollection) {
  48. throw new RuntimeException('not supported', 500);
  49. }
  50. $id = $uriVariables['id'];
  51. $file = $this->fileRepository->find($id);
  52. if (empty($file)) {
  53. throw new RuntimeException("File " . $id . " does not exist; abort.");
  54. }
  55. if ($file->getStatus() !== FileStatusEnum::READY()->getValue()) {
  56. throw new RuntimeException("File " . $id . " has " . $file->getStatus() . " status; abort.");
  57. }
  58. // Read the file
  59. $token = $this->security->getToken();
  60. $content = $this->fileManager->read($file, $token);
  61. // Build the response and attach the file to it
  62. // @see https://symfony.com/doc/current/components/http_foundation.html#serving-files
  63. $response = new Response($content);
  64. $response->headers->set('Charset', 'UTF-8');
  65. $response->headers->set('Access-Control-Expose-Headers', 'Content-Disposition');
  66. if (!empty($file->getMimeType())) {
  67. $response->headers->set('Content-Type', $file->getMimeType());
  68. }
  69. $response->headers->set(
  70. 'Content-Disposition',
  71. HeaderUtils::makeDisposition(HeaderUtils::DISPOSITION_ATTACHMENT, $file->getName())
  72. );
  73. return $response;
  74. }
  75. }