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

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 nullTranslationNodeVisitor $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 array|string $arguments Can be the locale as a string when $message is a TranslatableInterface
  94.      */
  95.     public function trans(string|\Stringable|TranslatableInterface|null $message, array|string $arguments = [], string $domain nullstring $locale nullint $count null): string
  96.     {
  97.         if ($message instanceof TranslatableInterface) {
  98.             if ([] !== $arguments && !\is_string($arguments)) {
  99.                 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)));
  100.             }
  101.             return $message->trans($this->getTranslator(), $locale ?? (\is_string($arguments) ? $arguments null));
  102.         }
  103.         if (!\is_array($arguments)) {
  104.             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)));
  105.         }
  106.         if ('' === $message = (string) $message) {
  107.             return '';
  108.         }
  109.         if (null !== $count) {
  110.             $arguments['%count%'] = $count;
  111.         }
  112.         return $this->getTranslator()->trans($message$arguments$domain$locale);
  113.     }
  114.     public function createTranslatable(string $message, array $parameters = [], string $domain null): TranslatableMessage
  115.     {
  116.         if (!class_exists(TranslatableMessage::class)) {
  117.             throw new \LogicException(sprintf('You cannot use the "%s" as the Translation Component is not installed. Try running "composer require symfony/translation".'__CLASS__));
  118.         }
  119.         return new TranslatableMessage($message$parameters$domain);
  120.     }
  121. }