vendor/willdurand/js-translation-bundle/Controller/Controller.php line 117

Open in your IDE?
  1. <?php
  2. namespace Bazinga\Bundle\JsTranslationBundle\Controller;
  3. use Bazinga\Bundle\JsTranslationBundle\Finder\TranslationFinder;
  4. use Bazinga\Bundle\JsTranslationBundle\Util;
  5. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  6. use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
  7. use Symfony\Contracts\Translation\TranslatorInterface;
  8. use Symfony\Component\HttpFoundation\Response;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\Config\ConfigCache;
  11. use Symfony\Component\Config\Resource\FileResource;
  12. use Symfony\Component\Filesystem\Exception\IOException;
  13. use Twig\Environment;
  14. use Twig\Loader\LoaderInterface;
  15. /**
  16.  * @author William DURAND <william.durand1@gmail.com>
  17.  *
  18.  * @final
  19.  */
  20. class Controller
  21. {
  22.     /**
  23.      * @var TranslatorInterface
  24.      */
  25.     private $translator;
  26.     /**
  27.      * @var Environment
  28.      */
  29.     private $twig;
  30.     /**
  31.      * @var TranslationFinder
  32.      */
  33.     private $translationFinder;
  34.     /**
  35.      * @var array
  36.      */
  37.     private $loaders = array();
  38.     /**
  39.      * @var string
  40.      */
  41.     private $cacheDir;
  42.     /**
  43.      * @var boolean
  44.      */
  45.     private $debug;
  46.     /**
  47.      * @var string
  48.      */
  49.     private $localeFallback;
  50.     /**
  51.      * @var string
  52.      */
  53.     private $defaultDomain;
  54.     /**
  55.      * @var int
  56.      */
  57.     private $httpCacheTime;
  58.     /**
  59.      * @param TranslatorInterface           $translator        The translator.
  60.      * @param Environment                   $twig              The twig environment.
  61.      * @param TranslationFinder             $translationFinder The translation finder.
  62.      * @param string                        $cacheDir
  63.      * @param boolean                       $debug
  64.      * @param string                        $localeFallback
  65.      * @param string                        $defaultDomain
  66.      * @param int                           $httpCacheTime
  67.      * @throws \InvalidArgumentException
  68.      */
  69.     public function __construct(
  70.         $translator,
  71.         Environment $twig,
  72.         TranslationFinder $translationFinder,
  73.         $cacheDir,
  74.         $debug          = false,
  75.         $localeFallback = '',
  76.         $defaultDomain  = '',
  77.         $httpCacheTime  = 86400
  78.     ) {
  79.         if (!$translator instanceof TranslatorInterface && !$translator instanceof LegacyTranslatorInterface) {
  80.             throw new \InvalidArgumentException(sprintf('Providing an instance of "%s" as translator is not supported.', get_class($translator)));
  81.         }
  82.         $this->translator        = $translator;
  83.         $this->twig              = $twig;
  84.         $this->translationFinder = $translationFinder;
  85.         $this->cacheDir          = $cacheDir;
  86.         $this->debug             = $debug;
  87.         $this->localeFallback    = $localeFallback;
  88.         $this->defaultDomain     = $defaultDomain;
  89.         $this->httpCacheTime     = $httpCacheTime;
  90.     }
  91.     /**
  92.      * Add a translation loader if it does not exist.
  93.      *
  94.      * @param string          $id     The loader id.
  95.      * @param LoaderInterface $loader A translation loader.
  96.      */
  97.     public function addLoader($id, $loader)
  98.     {
  99.         if (!array_key_exists($id, $this->loaders)) {
  100.             $this->loaders[$id] = $loader;
  101.         }
  102.     }
  103.     public function getTranslationsAction(Request $request, $domain, $_format)
  104.     {
  105.         $locales = $this->getLocales($request);
  106.         if (0 === count($locales)) {
  107.             throw new NotFoundHttpException();
  108.         }
  109.         $cache = new ConfigCache(sprintf('%s/%s.%s.%s',
  110.             $this->cacheDir,
  111.             $domain,
  112.             implode('-', $locales),
  113.             $_format
  114.         ), $this->debug);
  115.         if (!$cache->isFresh()) {
  116.             $resources    = array();
  117.             $translations = array();
  118.             foreach ($locales as $locale) {
  119.                 $translations[$locale] = array();
  120.                 $files = $this->translationFinder->get($domain, $locale);
  121.                 foreach ($files as $filename) {
  122.                     [$currentDomain] = Util::extractCatalogueInformationFromFilename($filename);
  123.                     if (!isset($translations[$locale][$currentDomain])) {
  124.                         $translations[$locale][$currentDomain] = array();
  125.                     }
  126.                     $extension = pathinfo($filename, \PATHINFO_EXTENSION);
  127.                     if (isset($this->loaders[$extension])) {
  128.                         $resources[] = new FileResource($filename);
  129.                         $catalogue   = $this->loaders[$extension]
  130.                             ->load($filename, $locale, $currentDomain);
  131.                         $translations[$locale][$currentDomain] = array_replace_recursive(
  132.                             $translations[$locale][$currentDomain],
  133.                             $catalogue->all($currentDomain)
  134.                         );
  135.                     }
  136.                 }
  137.             }
  138.             $content = $this->twig->render('@BazingaJsTranslation/getTranslations.' . $_format . '.twig', array(
  139.                 'fallback'       => $this->localeFallback,
  140.                 'defaultDomain'  => $this->defaultDomain,
  141.                 'translations'   => $translations,
  142.                 'include_config' => true,
  143.             ));
  144.             try {
  145.                 $cache->write($content, $resources);
  146.             } catch (IOException $e) {
  147.                 throw new NotFoundHttpException();
  148.             }
  149.         }
  150.         if (method_exists($cache, 'getPath')) {
  151.             $cachePath = $cache->getPath();
  152.         } else {
  153.             $cachePath = (string) $cache;
  154.         }
  155.         $expirationTime = new \DateTime();
  156.         $expirationTime->modify('+' . $this->httpCacheTime . ' seconds');
  157.         $response = new Response(
  158.             file_get_contents($cachePath),
  159.             200,
  160.             array('Content-Type' => $request->getMimeType($_format))
  161.         );
  162.         $response->prepare($request);
  163.         $response->setPublic();
  164.         $response->setETag(md5($response->getContent()));
  165.         $response->isNotModified($request);
  166.         $response->setExpires($expirationTime);
  167.         return $response;
  168.     }
  169.     private function getLocales(Request $request)
  170.     {
  171.         if (null !== $locales = $request->query->get('locales')) {
  172.             $locales = explode(',', $locales);
  173.         } else {
  174.             $locales = array($request->getLocale());
  175.         }
  176.         $locales = array_filter($locales, function ($locale) {
  177.             return 1 === preg_match('/^[a-z]{2,3}([-_]{1}[a-zA-Z]{2})?$/', $locale);
  178.         });
  179.         $locales = array_unique(array_map(function ($locale) {
  180.             return trim($locale);
  181.         }, $locales));
  182.         return $locales;
  183.     }
  184. }