TransNode.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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\Node;
  11. use Twig\Compiler;
  12. use Twig\Node\Expression\AbstractExpression;
  13. use Twig\Node\Expression\ArrayExpression;
  14. use Twig\Node\Expression\ConstantExpression;
  15. use Twig\Node\Expression\NameExpression;
  16. use Twig\Node\Node;
  17. use Twig\Node\TextNode;
  18. /**
  19. * @author Fabien Potencier <fabien@symfony.com>
  20. */
  21. final class TransNode extends Node
  22. {
  23. public function __construct(Node $body, Node $domain = null, AbstractExpression $count = null, AbstractExpression $vars = null, AbstractExpression $locale = null, int $lineno = 0, string $tag = null)
  24. {
  25. $nodes = ['body' => $body];
  26. if (null !== $domain) {
  27. $nodes['domain'] = $domain;
  28. }
  29. if (null !== $count) {
  30. $nodes['count'] = $count;
  31. }
  32. if (null !== $vars) {
  33. $nodes['vars'] = $vars;
  34. }
  35. if (null !== $locale) {
  36. $nodes['locale'] = $locale;
  37. }
  38. parent::__construct($nodes, [], $lineno, $tag);
  39. }
  40. public function compile(Compiler $compiler): void
  41. {
  42. $compiler->addDebugInfo($this);
  43. $defaults = new ArrayExpression([], -1);
  44. if ($this->hasNode('vars') && ($vars = $this->getNode('vars')) instanceof ArrayExpression) {
  45. $defaults = $this->getNode('vars');
  46. $vars = null;
  47. }
  48. [$msg, $defaults] = $this->compileString($this->getNode('body'), $defaults, (bool) $vars);
  49. $compiler
  50. ->write('echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->trans(')
  51. ->subcompile($msg)
  52. ;
  53. $compiler->raw(', ');
  54. if (null !== $vars) {
  55. $compiler
  56. ->raw('array_merge(')
  57. ->subcompile($defaults)
  58. ->raw(', ')
  59. ->subcompile($this->getNode('vars'))
  60. ->raw(')')
  61. ;
  62. } else {
  63. $compiler->subcompile($defaults);
  64. }
  65. $compiler->raw(', ');
  66. if (!$this->hasNode('domain')) {
  67. $compiler->repr('messages');
  68. } else {
  69. $compiler->subcompile($this->getNode('domain'));
  70. }
  71. if ($this->hasNode('locale')) {
  72. $compiler
  73. ->raw(', ')
  74. ->subcompile($this->getNode('locale'))
  75. ;
  76. } elseif ($this->hasNode('count')) {
  77. $compiler->raw(', null');
  78. }
  79. if ($this->hasNode('count')) {
  80. $compiler
  81. ->raw(', ')
  82. ->subcompile($this->getNode('count'))
  83. ;
  84. }
  85. $compiler->raw(");\n");
  86. }
  87. private function compileString(Node $body, ArrayExpression $vars, bool $ignoreStrictCheck = false): array
  88. {
  89. if ($body instanceof ConstantExpression) {
  90. $msg = $body->getAttribute('value');
  91. } elseif ($body instanceof TextNode) {
  92. $msg = $body->getAttribute('data');
  93. } else {
  94. return [$body, $vars];
  95. }
  96. preg_match_all('/(?<!%)%([^%]+)%/', $msg, $matches);
  97. foreach ($matches[1] as $var) {
  98. $key = new ConstantExpression('%'.$var.'%', $body->getTemplateLine());
  99. if (!$vars->hasElement($key)) {
  100. if ('count' === $var && $this->hasNode('count')) {
  101. $vars->addElement($this->getNode('count'), $key);
  102. } else {
  103. $varExpr = new NameExpression($var, $body->getTemplateLine());
  104. $varExpr->setAttribute('ignore_strict_check', $ignoreStrictCheck);
  105. $vars->addElement($varExpr, $key);
  106. }
  107. }
  108. }
  109. return [new ConstantExpression(str_replace('%%', '%', trim($msg)), $body->getTemplateLine()), $vars];
  110. }
  111. }