FileUploadExtension.php 5.8 KB
Newer Older
<?php

/*
 * Copyright (C) 2015 IRSTEA
 * All rights reserved.
 *
 * @copyright 2015 Irstea
 * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
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 Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Twig_Environment;
use Twig_Extension;
use Twig_SimpleFilter;
use Twig_SimpleFunction;

/** Extension Twig pour les fichiers uploadés.
 */
class FileUploadExtension extends Twig_Extension
{
    /**
     *
     * @var TranslatorInterface
     */
    private $translator;

    /**
     * @var FileUrlGeneratorInterface
     */
    private $urlGenerator;

    /**
     *
     * @param TranslatorInterface $translator
     */
    public function __construct(TranslatorInterface $translator, FileUrlGeneratorInterface $urlGenerator)
    /**
     * {@inheritdoc}
     */
    public function getFunctions()
    {
        return [
            new Twig_SimpleFunction(
                'irstea_uploaded_file',
                [$this, 'formatUploadedFile'],
                [
                    'needs_environment' => true,
                    'is_safe' => ['html']
                ]
            ),
            new Twig_SimpleFunction(
                'irstea_file_url',
                [$this, 'generateFileUrl'],
                [
                    'is_safe' => ['html', 'html_attr']
                ]
            ),
            new Twig_SimpleFunction(
                'irstea_file_icon',
                [$this, 'formatFileIcon'],
                ['is_safe' => ['html']]
            ),
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function getFilters()
    {
        return [
            new Twig_SimpleFilter(
                'irstea_file_size',
                [$this, 'formatFileSize'],
                ['needs_context' => true]
Guillaume Perréal's avatar
Guillaume Perréal committed
            ),
    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return "irstea_file_upload";
    }

    /** Genère un tag HTML pour représenter le fichier.
     *
     * Inclut un lien sécurisé qui permet de télécharger le fichier, mais uniquement à l'utilisateur qui a affiché la page.
     *
     * Usage : `{{ irstea_uploaded_file(file) }}`
     *
     * @param Twig_Environment      $env
     * @param UploadedFileInterface $file
     *
     * @return string
     */
    public function formatUploadedFile(Twig_Environment $env, $file = null)
    {
        if(null === $file) {
            return '';
            $file = $file->toArray();
        } elseif(!is_array($file)) {
            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) }}`
     *
     * @param string $mimeType Type MIME.
     *
     * @return string Un tag <i></i> avec les classes Font-Awesome.
     *
     * @uses MimeTypeIcon::getMimeTypeIcon
     */
    public function formatFileIcon($mimeType)
    {
        $icon = MimeTypeIcon::getMimeTypeIcon($mimeType);
        return sprintf('<i class="icon fa fa-file%s-o"></i>', ($icon && $icon !== 'file') ? ('-'.$icon) : '');
    }

    /** Formate une taille de fichier.
     *
     * Usage : `{{ size|irstea_file_size([precision][, locale]) }}`
     *
     * @param array $context Contexte Twig.
     * @param integer $size Taille du fichier.
     * @param integer $precision Nombre de chiffres après la virgule.
     * @param string $locale Langue
     *
     * @return string
     *
     * @uses \NumberFormatter
     */
    public function formatFileSize($context, $size, $precision = null, $locale = null)
    {
        if(!is_numeric($size)) {
            return '';
        }

        if($size > 1000000000) {
            $size /= 1000000000.0;
            $unit = 'Gi';
        } elseif($size > 1000000) {
            $size /= 1000000.0;
            $unit = 'Mi';
        } elseif($size > 1000) {
            $size /= 1000.0;

        if(null === $locale) {
            $locale = $context['app']->getRequest()->getLocale();
        }

        $formatter = NumberFormatter::create($locale, NumberFormatter::DECIMAL);
        $formatter->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, null !== $precision ? $precision : 0);
        $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, null !== $precision ? $precision : $defaultPrecision);
            [
                '%size%' => $formatter->format($size),
                '%unit%' => $unit,
            ],