Newer
Older
Guillaume Perréal
committed
<?php
/*
* Copyright (C) 2015 IRSTEA
* All rights reserved.
*
* @copyright 2015 Irstea
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
Guillaume Perréal
committed
*/
namespace Irstea\FileUploadBundle\Twig;
Guillaume Perréal
committed
use InvalidArgumentException;
use Irstea\FileUploadBundle\Entity\UploadedFile;
Guillaume Perréal
committed
use Irstea\FileUploadBundle\Model\UploadedFileInterface;
Guillaume Perréal
committed
use Irstea\FileUploadBundle\Service\FileUrlGeneratorInterface;
Guillaume Perréal
committed
use Irstea\FileUploadBundle\Utils\MimeTypeIcon;
Guillaume Perréal
committed
use NumberFormatter;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
Guillaume Perréal
committed
use Symfony\Component\Translation\TranslatorInterface;
use Twig_Environment;
use Twig_Extension;
use Twig_SimpleFilter;
use Twig_SimpleFunction;
/** Extension Twig pour les fichiers uploadés.
Guillaume Perréal
committed
*/
class FileUploadExtension extends Twig_Extension
{
/**
*
* @var TranslatorInterface
*/
private $translator;
Guillaume Perréal
committed
/**
* @var FileUrlGeneratorInterface
*/
private $urlGenerator;
Guillaume Perréal
committed
/**
*
* @param TranslatorInterface $translator
*/
Guillaume Perréal
committed
public function __construct(TranslatorInterface $translator, FileUrlGeneratorInterface $urlGenerator)
Guillaume Perréal
committed
{
$this->translator = $translator;
Guillaume Perréal
committed
$this->urlGenerator = $urlGenerator;
Guillaume Perréal
committed
}
Guillaume Perréal
committed
public function getFunctions()
{
return [
new Twig_SimpleFunction(
'irstea_uploaded_file',
[$this, 'formatUploadedFile'],
[
'needs_environment' => true,
'is_safe' => ['html']
]
),
Guillaume Perréal
committed
new Twig_SimpleFunction(
'irstea_file_url',
[$this, 'generateFileUrl'],
[
'is_safe' => ['html', 'html_attr']
]
),
Guillaume Perréal
committed
new Twig_SimpleFunction(
'irstea_file_icon',
[$this, 'formatFileIcon'],
['is_safe' => ['html']]
),
];
}
Guillaume Perréal
committed
public function getFilters()
{
return [
new Twig_SimpleFilter(
'irstea_file_size',
[$this, 'formatFileSize'],
['needs_context' => true]
Guillaume Perréal
committed
];
}
Guillaume Perréal
committed
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
*/
Guillaume Perréal
committed
public function formatUploadedFile(Twig_Environment $env, $file = null)
{
if(null === $file) {
return '';
Guillaume Perréal
committed
} elseif($file instanceof UploadedFile) {
Guillaume Perréal
committed
$file = $file->toArray();
} elseif(!is_array($file)) {
Guillaume Perréal
committed
throw new InvalidArgumentException("irstea_uploaded_file expects an UploadedFile instance, array or null");
Guillaume Perréal
committed
}
return $env->render('IrsteaFileUploadBundle:Extension:uploaded_file.html.twig', ['file' => $file]);
}
Guillaume Perréal
committed
/** 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
*/
Guillaume Perréal
committed
public function formatFileIcon($mimeType)
{
$icon = MimeTypeIcon::getMimeTypeIcon($mimeType);
return sprintf('<i class="icon fa fa-file%s-o"></i>', ($icon && $icon !== 'file') ? ('-'.$icon) : '');
}
*
* 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
*/
Guillaume Perréal
committed
public function formatFileSize($context, $size, $precision = null, $locale = null)
{
if(!is_numeric($size)) {
return '';
}
if($size > 1000000000) {
$size /= 1000000000.0;
Guillaume Perréal
committed
$defaultPrecision = 2;
Guillaume Perréal
committed
$unit = 'Gi';
} elseif($size > 1000000) {
$size /= 1000000.0;
Guillaume Perréal
committed
$defaultPrecision = 1;
Guillaume Perréal
committed
$unit = 'Mi';
} elseif($size > 1000) {
$size /= 1000.0;
Guillaume Perréal
committed
$defaultPrecision = 1;
Guillaume Perréal
committed
$unit = 'Ki';
} else {
$unit = '';
Guillaume Perréal
committed
$defaultPrecision = 0;
}
Guillaume Perréal
committed
if(null === $locale) {
$locale = $context['app']->getRequest()->getLocale();
}
$formatter = NumberFormatter::create($locale, NumberFormatter::DECIMAL);
Guillaume Perréal
committed
$formatter->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, null !== $precision ? $precision : 0);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, null !== $precision ? $precision : $defaultPrecision);
Guillaume Perréal
committed
return $this->translator->trans(
Guillaume Perréal
committed
'file_size(%size%,%unit%)',
Guillaume Perréal
committed
[
'%size%' => $formatter->format($size),
'%unit%' => $unit,
],
Guillaume Perréal
committed
'file_upload',
Guillaume Perréal
committed
$locale
);
}
}