vendor/symfony/twig-bridge/Extension/TranslationExtension.php line 103

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Bridge\Twig\Extension;
  11. use Symfony\Bridge\Twig\NodeVisitor\TranslationDefaultDomainNodeVisitor;
  12. use Symfony\Bridge\Twig\NodeVisitor\TranslationNodeVisitor;
  13. use Symfony\Bridge\Twig\TokenParser\TransDefaultDomainTokenParser;
  14. use Symfony\Bridge\Twig\TokenParser\TransTokenParser;
  15. use Symfony\Component\Translation\TranslatableMessage;
  16. use Symfony\Contracts\Translation\TranslatableInterface;
  17. use Symfony\Contracts\Translation\TranslatorInterface;
  18. use Symfony\Contracts\Translation\TranslatorTrait;
  19. use Twig\Extension\AbstractExtension;
  20. use Twig\TwigFilter;
  21. use Twig\TwigFunction;
  22. // Help opcache.preload discover always-needed symbols
  23. class_exists(TranslatorInterface::class);
  24. class_exists(TranslatorTrait::class);
  25. /**
  26.  * Provides integration of the Translation component with Twig.
  27.  *
  28.  * @author Fabien Potencier <fabien@symfony.com>
  29.  */
  30. final class TranslationExtension extends AbstractExtension
  31. {
  32.     private $translator;
  33.     private $translationNodeVisitor;
  34.     public function __construct(?TranslatorInterface $translator null, ?TranslationNodeVisitor $translationNodeVisitor null)
  35.     {
  36.         $this->translator $translator;
  37.         $this->translationNodeVisitor $translationNodeVisitor;
  38.     }
  39.     public function getTranslator(): TranslatorInterface
  40.     {
  41.         if (null === $this->translator) {
  42.             if (!interface_exists(TranslatorInterface::class)) {
  43.                 throw new \LogicException(sprintf('You cannot use the "%s" if the Translation Contracts are not available. Try running "composer require symfony/translation".'__CLASS__));
  44.             }
  45.             $this->translator = new class() implements TranslatorInterface {
  46.                 use TranslatorTrait;
  47.             };
  48.         }
  49.         return $this->translator;
  50.     }
  51.     /**
  52.      * {@inheritdoc}
  53.      */
  54.     public function getFunctions(): array
  55.     {
  56.         return [
  57.             new TwigFunction('t', [$this'createTranslatable']),
  58.         ];
  59.     }
  60.     /**
  61.      * {@inheritdoc}
  62.      */
  63.     public function getFilters(): array
  64.     {
  65.         return [
  66.             new TwigFilter('trans', [$this'trans']),
  67.         ];
  68.     }
  69.     /**
  70.      * {@inheritdoc}
  71.      */
  72.     public function getTokenParsers(): array
  73.     {
  74.         return [
  75.             // {% trans %}Symfony is great!{% endtrans %}
  76.             new TransTokenParser(),
  77.             // {% trans_default_domain "foobar" %}
  78.             new TransDefaultDomainTokenParser(),
  79.         ];
  80.     }
  81.     /**
  82.      * {@inheritdoc}
  83.      */
  84.     public function getNodeVisitors(): array
  85.     {
  86.         return [$this->getTranslationNodeVisitor(), new TranslationDefaultDomainNodeVisitor()];
  87.     }
  88.     public function getTranslationNodeVisitor(): TranslationNodeVisitor
  89.     {
  90.         return $this->translationNodeVisitor ?: $this->translationNodeVisitor = new TranslationNodeVisitor();
  91.     }
  92.     /**
  93.      * @param string|\Stringable|TranslatableInterface|null $message
  94.      * @param array|string                                  $arguments Can be the locale as a string when $message is a TranslatableInterface
  95.      */
  96.     public function trans($message$arguments = [], ?string $domain null, ?string $locale null, ?int $count null): string
  97.     {
  98.         if ($message instanceof TranslatableInterface) {
  99.             if ([] !== $arguments && !\is_string($arguments)) {
  100.                 throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be a locale passed as a string when the message is a "%s", "%s" given.'__METHOD__TranslatableInterface::class, get_debug_type($arguments)));
  101.             }
  102.             if ($message instanceof TranslatableMessage && '' === $message->getMessage()) {
  103.                 return '';
  104.             }
  105.             return $message->trans($this->getTranslator(), $locale ?? (\is_string($arguments) ? $arguments null));
  106.         }
  107.         if (!\is_array($arguments)) {
  108.             throw new \TypeError(sprintf('Unless the message is a "%s", argument 2 passed to "%s()" must be an array of parameters, "%s" given.'TranslatableInterface::class, __METHOD__get_debug_type($arguments)));
  109.         }
  110.         if ('' === $message = (string) $message) {
  111.             return '';
  112.         }
  113.         if (null !== $count) {
  114.             $arguments['%count%'] = $count;
  115.         }
  116.         return $this->getTranslator()->trans($message$arguments$domain$locale);
  117.     }
  118.     public function createTranslatable(string $message, array $parameters = [], ?string $domain null): TranslatableMessage
  119.     {
  120.         if (!class_exists(TranslatableMessage::class)) {
  121.             throw new \LogicException(sprintf('You cannot use the "%s" as the Translation Component is not installed. Try running "composer require symfony/translation".'__CLASS__));
  122.         }
  123.         return new TranslatableMessage($message$parameters$domain);
  124.     }
  125. }