Przeglądaj źródła

implements downloadRequests support

Olivier Massot 3 lat temu
rodzic
commit
c8c367b0e0

+ 1 - 0
config/opentalent/products.yaml

@@ -14,6 +14,7 @@ opentalent:
           - Tagg
           - Enum
           - LicenceCmfOrganizationER
+          - DownloadRequest
         roles:
           - ROLE_IMPORT
           - ROLE_TAGG

+ 44 - 0
src/ApiResources/DownloadRequest.php

@@ -0,0 +1,44 @@
+<?php
+declare(strict_types=1);
+
+namespace App\ApiResources;
+
+use ApiPlatform\Core\Annotation\ApiProperty;
+use ApiPlatform\Core\Annotation\ApiResource;
+
+/**
+ * A request for a file from the FileStorage
+ */
+#[ApiResource(
+    collectionOperations:[],
+    itemOperations: [
+        'get' => [
+            'security' => 'is_granted("ROLE_FILE")',
+            'method' => 'GET',
+            'path' => '/download/{fileId}',
+            'requirements' => ['fileId' => '\d+']
+        ],
+    ],
+    compositeIdentifier: false,
+)]
+class DownloadRequest
+{
+    #[ApiProperty(identifier: true)]
+    private int $fileId;
+
+    /**
+     * @return int
+     */
+    public function getFileId(): int
+    {
+        return $this->fileId;
+    }
+
+    /**
+     * @param int $fileId
+     */
+    public function setFileId(int $fileId): void
+    {
+        $this->fileId = $fileId;
+    }
+}

+ 0 - 2
src/ApiResources/Export/ExportRequest.php

@@ -4,8 +4,6 @@ declare(strict_types=1);
 namespace App\ApiResources\Export;
 
 use ApiPlatform\Core\Annotation\ApiProperty;
-use ApiPlatform\Core\Annotation\ApiResource;
-use App\Entity\Access\Access;
 use Symfony\Component\Validator\Constraints as Assert;
 use App\Enum\Export\ExportFormatEnum;
 

+ 50 - 0
src/DataProvider/DownloadRequestDataProvider.php

@@ -0,0 +1,50 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DataProvider;
+
+use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
+use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
+use App\ApiResources\DownloadRequest;
+use App\Repository\Core\FileRepository;
+use App\Service\Storage\FileStorage;
+use Symfony\Component\HttpFoundation\BinaryFileResponse;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\HeaderUtils;
+
+/**
+ * Custom provider pour le téléchargement des fichiers du FileStorage
+ */
+final class DownloadRequestDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
+{
+    public function __construct(
+        private FileRepository $fileRepository,
+        private FileStorage $storage,
+    )
+    {}
+
+    public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
+    {
+        return DownloadRequest::class === $resourceClass;
+    }
+
+    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): Response
+    {
+        $file = $this->fileRepository->find($id);
+//
+//        return new BinaryFileResponse($this->storage->getPath($file));
+
+        $content = $this->storage->read($file);
+
+        $response = new Response($content);
+
+        $disposition = HeaderUtils::makeDisposition(
+            HeaderUtils::DISPOSITION_ATTACHMENT,
+            $file->getName()
+        );
+
+        $response->headers->set('Content-Disposition', $disposition);
+
+        return $response;
+    }
+}

+ 8 - 0
src/Entity/Core/File.php

@@ -158,6 +158,14 @@ class File
     #[Assert\Choice(callback: [FileStatusEnum::class, 'toArray'])]
     private ?string $status = null;
 
+    /**
+     * Statut du fichier (en cours de génération, prêt, supprimé, etc.)
+     * @var string | null
+     */
+    #[ORM\Column(length: 5)]
+    #[Assert\Choice(['api', 'ap2i'])]
+    private ?string $host = 'ap2i';
+
 //    #[ORM\Column]
 //    private ?int $eventReport_id;
 //

+ 4 - 0
src/Security/Voter/ModuleVoter.php

@@ -8,6 +8,7 @@ use App\Entity\Access\Access;
 use App\Entity\Organization\Organization;
 use App\Service\Security\Module;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+use Symfony\Component\Security\Core\Authentication\Token\NullToken;
 use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
 use Symfony\Component\Security\Core\Authorization\Voter\Voter;
 
@@ -42,6 +43,9 @@ class ModuleVoter extends Voter
         if (!$subject->attributes->get('_api_resource_class') || !$resourceMetadata = $this->resourceMetadataFactory->create($subject->attributes->get('_api_resource_class'))) {
             throw new AccessDeniedHttpException(sprintf('Missing resource class'));
         }
+        if ($token instanceof NullToken) {
+            return false;
+        }
 
         $module = $this->module->getModuleByResourceName($resourceMetadata->getShortName());
 

+ 3 - 3
src/Service/Export/LicenceCmfExporter.php

@@ -61,7 +61,7 @@ class LicenceCmfExporter extends BaseExporter
         $logo = $organization->getLogo();
         if ($logo) {
             $licenceCmf->setLogoUri(
-                $this->storage->getUri($logo)
+                $this->storage->getDownloadUri($logo)
             );
         }
 
@@ -69,7 +69,7 @@ class LicenceCmfExporter extends BaseExporter
         if (count($presidents) > 0) {
             $president = $presidents[0]->getPerson();
             $licenceCmf->setPersonId($president->getId());
-            $licenceCmf->setPersonGender($president->getGender());
+            $licenceCmf->setPersonGender($president->getGender() ?? '');
             $licenceCmf->setPersonFirstName($president->getGivenName());
             $licenceCmf->setPersonLastName($president->getName());
         }
@@ -79,7 +79,7 @@ class LicenceCmfExporter extends BaseExporter
         $qrCode = $cmf->getParameters()?->getQrCode();
         if ($qrCode) {
             $licenceCmf->setQrCodeUri(
-                $this->storage->getUri($qrCode)
+                $this->storage->getDownloadUri($qrCode)
             );
         }
 

+ 10 - 8
src/Service/Storage/FileStorage.php

@@ -51,14 +51,16 @@ class FileStorage
         return $this->filesystem->has($file->getSlug());
     }
 
-    /**
-     * Return the uri to download the given file
-     *
-     * @param File $file
-     * @return string
-     */
-    public function getUri(File $file): string {
-        return '';
+    public function getDownloadUri(File $file): string
+    {
+        // TODO: trouver solution plus propre
+        return $_SERVER['REQUEST_SCHEME'] . '://' . Path::join($_SERVER['HTTP_HOST'], 'api', 'download', $file->getID());
+    }
+
+    public function getPath(File $file): string
+    {
+        // TODO: trouver solution plus propre
+        return Path::join(Path::getProjectDir(), 'var', 'files', 'storage', $file->getSlug());
     }
 
     /**

+ 22 - 22
templates/export/licence_cmf.html.twig

@@ -176,14 +176,14 @@
                             <tbody>
                             <tr>
                                 <td width="340" class="relative">
-                                    <img src="{{ asset('static/cmf_licence.png') }}"
-                                            width="170" height="86"/>
+{#                                    <img src="{{ asset('#{app.server.request_scheme}://#{app.server.http_host}/static/cmf_licence.png') }}"#}
+{#                                            width="170" height="86"/>#}
                                     <span id="year_head">{{ licence.year }}</span>
                                 </td>
                                 <td width="340">
                                     <div align="right">
-                                        <img src="{{ asset('static/cmf-reseau.png') }}"
-                                                width="200" height="86"/>
+{#                                        <img src="{{ asset('#{app.server.request_scheme}://#{app.server.http_host}/static/cmf-reseau.png') }}"#}
+{#                                                width="200" height="86"/>#}
                                     </div>
                                 </td>
                             </tr>
@@ -239,13 +239,13 @@
                             <td width="80" id="avatar">
                                 <div align="center">
                                     {% if(licence.logoUri is null) %}
-                                        <img src="{{ asset('static/picto_face.png') }}"
-                                             width="85"
-                                             height="82"/>
+{#                                        <img src="{{ asset('#{app.server.request_scheme}://#{app.server.http_host}/static/picto_face.png') }}"#}
+{#                                             width="85"#}
+{#                                             height="82"/>#}
                                     {% else %}
-                                        <img src="{{ licence.logoUri }}"
-                                             width="85"
-                                             height="82"/>
+{#                                        <img src="{{ licence.logoUri }}"#}
+{#                                             width="85"#}
+{#                                             height="82"/>#}
                                     {% endif %}
                                 </div>
                             </td>
@@ -262,13 +262,13 @@
                             <td width="80" id="avatar">
                                 <div align="center">
                                     {% if(licence.personAvatarUri is null) %}
-                                        <img
-                                                src="{{ asset('static/picto_face.png') }}"
-                                                width="85"
-                                                height="82"/>
+{#                                        <img#}
+{#                                                src="{{ asset('#{app.server.request_scheme}://#{app.server.http_host}/static/picto_face.png') }}"#}
+{#                                                width="85"#}
+{#                                                height="82"/>#}
                                     {% else %}
-                                        <img class="avatar"
-                                             src="{{ asset(licence.personAvatarUri) }}"/>
+{#                                        <img class="avatar"#}
+{#                                             src="{{ asset(licence.personAvatarUri) }}"/>#}
                                     {% endif %}
                                 </div>
                             </td>
@@ -288,8 +288,8 @@
                         <td width="70" valign="middle"
                             style="vertical-align: top;">
                             <div align="center">
-                                <img src="{{ asset('static/cmf_licence.png') }}"
-                                     height="45"/>
+{#                                <img src="{{ asset('#{app.server.request_scheme}://#{app.server.http_host}/static/cmf_licence.png') }}"#}
+{#                                     height="45"/>#}
                                 <span id="year_card">{{ licence.year }}</span>
                             </div>
                         </td>
@@ -303,10 +303,10 @@
                         </td>
                         <td width="70" align="right" valign="middle" id="qrCode">
                             {% if(licence.qrCodeUri) %}
-                                <img style="margin-right: 10px;"
-                                     src="{{ asset(licence.qrCodeUri) }}"
-                                     alt=""
-                                     width="65" height="65"/>
+{#                                <img style="margin-right: 10px;"#}
+{#                                     src="{{ asset(licence.qrCodeUri) }}"#}
+{#                                     alt=""#}
+{#                                     width="65" height="65"/>#}
                             {% endif %}
                         </td>
                     </tr>