From e3f85cf242a6a7a58239971670f9041759de7e03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Guillaume=20Perr=C3=A9al?= <guillaume.perreal@irstea.fr>
Date: Thu, 26 Nov 2015 16:41:19 +0100
Subject: [PATCH] =?UTF-8?q?Ajout=20d'un=20service=20et=20d'une=20fonction?=
 =?UTF-8?q?=20Twig=20pour=20g=C3=A9n=C3=A9rer=20des=20URLs=20pour=20les=20?=
 =?UTF-8?q?fichiers.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Service: irstea_file_upload.url_generator
Fonction Twig: irstea_file_path(file.id, referenceType=false)
---
 Resources/config/services.yml                 |  8 +++
 .../views/Extension/uploaded_file.html.twig   |  9 +--
 Service/FileUrlGenerator.php                  | 57 +++++++++++++++++++
 Service/FileUrlGeneratorInterface.php         | 27 +++++++++
 Twig/FileUploadExtension.php                  | 40 +++++++++++--
 5 files changed, 129 insertions(+), 12 deletions(-)
 create mode 100644 Service/FileUrlGenerator.php
 create mode 100644 Service/FileUrlGeneratorInterface.php

diff --git a/Resources/config/services.yml b/Resources/config/services.yml
index 7ca45a9f..770f4a8d 100644
--- a/Resources/config/services.yml
+++ b/Resources/config/services.yml
@@ -71,5 +71,13 @@ services:
         class: Irstea\FileUploadBundle\Twig\FileUploadExtension
         arguments:
             - @translator
+            - @irstea_file_upload.url_generator
         tags:
             - { name: twig.extension }
+
+    # Générateur d'URL
+    irstea_file_upload.url_generator:
+        class: Irstea\FileUploadBundle\Service\FileUrlGenerator
+        arguments:
+            - @router
+            - @security.csrf.token_manager
diff --git a/Resources/views/Extension/uploaded_file.html.twig b/Resources/views/Extension/uploaded_file.html.twig
index 3b929a1f..17f5952a 100644
--- a/Resources/views/Extension/uploaded_file.html.twig
+++ b/Resources/views/Extension/uploaded_file.html.twig
@@ -2,14 +2,7 @@
     <span class="uploaded-file">
         {{- irstea_file_icon(file.type|default(null)) -}}
         &nbsp;<span class="name">
-            <a href="{{
-                path('file_upload_get_content', {
-                    'id': file.id|default('__id__'),
-                    'token': csrf_token(constant('Irstea\\FileUploadBundle\\Controller\\UploadController::CSRF_INTENTION'))
-                })
-            }}">
-            {{- file.name|default('') -}}
-            </a>
+            <a href="{{ irstea_file_url(file.id|default('__id__')) }}">{{ file.name|default('') }}</a>
         </span>&nbsp;(<span class="size">
             {{- file.size|default(0)|irstea_file_size -}}
         </span>)
diff --git a/Service/FileUrlGenerator.php b/Service/FileUrlGenerator.php
new file mode 100644
index 00000000..16bc22af
--- /dev/null
+++ b/Service/FileUrlGenerator.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * Copyright (C) 2015 IRSTEA
+ * All rights reserved.
+ */
+
+namespace Irstea\FileUploadBundle\Service;
+
+use Irstea\FileUploadBundle\Controller\UploadController;
+use Irstea\FileUploadBundle\Model\UploadedFileInterface;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
+
+/**
+ * Implémentation de FileUrlInterface utilisant les services de Symfony.
+ *
+ * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
+ */
+class FileUrlGenerator implements FileUrlGeneratorInterface
+{
+    /**
+     * @var UrlGeneratorInterface
+     */
+    protected $urlGenerator;
+
+    /**
+     * @var CsrfTokenManagerInterface
+     */
+    protected $tokenManager;
+
+    /**
+     * @param UrlGeneratorInterface $urlGenerator
+     * @param CsrfTokenManagerInterface $tokenManager
+     */
+    public function __construct(UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $tokenManager)
+    {
+        $this->urlGenerator = $urlGenerator;
+        $this->tokenManager = $tokenManager;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function generate($idFile, $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
+    {
+        $token = $this->tokenManager->getToken(UploadController::CSRF_INTENTION);
+
+        $url = $this->urlGenerator->generate(
+            'file_upload_get_content',
+            ['id' => $idFile, 'token' => $token->getValue()],
+            $referenceType
+        );
+
+        return $url;
+    }
+}
diff --git a/Service/FileUrlGeneratorInterface.php b/Service/FileUrlGeneratorInterface.php
new file mode 100644
index 00000000..123941fc
--- /dev/null
+++ b/Service/FileUrlGeneratorInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * Copyright (C) 2015 IRSTEA
+ * All rights reserved.
+ */
+
+namespace Irstea\FileUploadBundle\Service;
+
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+
+/**
+ * Service générant/vérifiant une URL pour un fichier.
+ *
+ * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
+ */
+interface FileUrlGeneratorInterface
+{
+    /**
+     * Génère une URL sécurisée pour un fichier.
+     *
+     * @param string $idFile Identifiant du fichier pour lequel générer l'URL.
+     * @param string|bool $referenceType Type d'URL à générer.
+     * @return string L'url générée.
+     */
+    public function generate($idFile, $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH);
+}
diff --git a/Twig/FileUploadExtension.php b/Twig/FileUploadExtension.php
index 45d42ac1..3b804bcd 100644
--- a/Twig/FileUploadExtension.php
+++ b/Twig/FileUploadExtension.php
@@ -10,9 +10,13 @@
 
 namespace Irstea\FileUploadBundle\Twig;
 
+use InvalidArgumentException;
+use Irstea\FileUploadBundle\Entity\UploadedFile;
 use Irstea\FileUploadBundle\Model\UploadedFileInterface;
+use Irstea\FileUploadBundle\Service\FileUrlGeneratorInterface;
 use Irstea\FileUploadBundle\Utils\MimeTypeIcon;
-use \NumberFormatter;
+use NumberFormatter;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
 use Symfony\Component\Translation\TranslatorInterface;
 use Twig_Environment;
 use Twig_Extension;
@@ -29,13 +33,19 @@ class FileUploadExtension extends Twig_Extension
      */
     private $translator;
 
+    /**
+     * @var FileUrlGeneratorInterface
+     */
+    private $urlGenerator;
+
     /**
      *
      * @param TranslatorInterface $translator
      */
-    public function __construct(TranslatorInterface $translator)
+    public function __construct(TranslatorInterface $translator, FileUrlGeneratorInterface $urlGenerator)
     {
         $this->translator = $translator;
+        $this->urlGenerator = $urlGenerator;
     }
 
     /**
@@ -52,6 +62,13 @@ class FileUploadExtension extends Twig_Extension
                     'is_safe' => ['html']
                 ]
             ),
+            new Twig_SimpleFunction(
+                'irstea_file_url',
+                [$this, 'generateFileUrl'],
+                [
+                    'is_safe' => ['html', 'html_attr']
+                ]
+            ),
             new Twig_SimpleFunction(
                 'irstea_file_icon',
                 [$this, 'formatFileIcon'],
@@ -97,15 +114,30 @@ class FileUploadExtension extends Twig_Extension
     {
         if(null === $file) {
             return '';
-        } elseif($file instanceof \Irstea\FileUploadBundle\Entity\UploadedFile) {
+        } elseif($file instanceof UploadedFile) {
             $file = $file->toArray();
         } elseif(!is_array($file)) {
-            throw new \InvalidArgumentException("irstea_uploaded_file expects an UploadedFile instance, array or null");
+            throw new InvalidArgumentException("irstea_uploaded_file expects an UploadedFile instance, array or null");
         }
 
         return $env->render('IrsteaFileUploadBundle:Extension:uploaded_file.html.twig', ['file' => $file]);
     }
 
+
+    /** Genère un URL sécurisée pour télécharger un fichier.
+     *
+     * Usage : `{{ irstea_file_path(file.id) }}`
+     *
+     * @param string $idFile
+     * @param string|bool $referenceType
+     *
+     * @return string
+     */
+    public function generateFileUrl($idFile, $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
+    {
+        return $this->urlGenerator->generate($idFile, $referenceType);
+    }
+
     /** Génère un tag "icône" Font-Awesome pour le type MIME indiqué.
      *
      * Usage : `{{ irstea_file_icon(mimeType) }}`
-- 
GitLab