TranslationDefaultDomainNodeVisitor.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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\NodeVisitor;
  11. use Symfony\Bridge\Twig\Node\TransNode;
  12. use Symfony\Bridge\Twig\Node\TransDefaultDomainNode;
  13. use Twig\Environment;
  14. use Twig\Node\BlockNode;
  15. use Twig\Node\Expression\ArrayExpression;
  16. use Twig\Node\Expression\AssignNameExpression;
  17. use Twig\Node\Expression\ConstantExpression;
  18. use Twig\Node\Expression\FilterExpression;
  19. use Twig\Node\Expression\NameExpression;
  20. use Twig\Node\ModuleNode;
  21. use Twig\Node\Node;
  22. use Twig\Node\SetNode;
  23. use Twig\NodeVisitor\AbstractNodeVisitor;
  24. /**
  25. * TranslationDefaultDomainNodeVisitor.
  26. *
  27. * @author Fabien Potencier <fabien@symfony.com>
  28. */
  29. class TranslationDefaultDomainNodeVisitor extends AbstractNodeVisitor
  30. {
  31. /**
  32. * @var Scope
  33. */
  34. private $scope;
  35. /**
  36. * Constructor.
  37. */
  38. public function __construct()
  39. {
  40. $this->scope = new Scope();
  41. }
  42. /**
  43. * {@inheritdoc}
  44. */
  45. protected function doEnterNode(Node $node, Environment $env)
  46. {
  47. if ($node instanceof BlockNode || $node instanceof ModuleNode) {
  48. $this->scope = $this->scope->enter();
  49. }
  50. if ($node instanceof TransDefaultDomainNode) {
  51. if ($node->getNode('expr') instanceof ConstantExpression) {
  52. $this->scope->set('domain', $node->getNode('expr'));
  53. return $node;
  54. } else {
  55. $var = $this->getVarName();
  56. $name = new AssignNameExpression($var, $node->getTemplateLine());
  57. $this->scope->set('domain', new NameExpression($var, $node->getTemplateLine()));
  58. return new SetNode(false, new Node(array($name)), new Node(array($node->getNode('expr'))), $node->getTemplateLine());
  59. }
  60. }
  61. if (!$this->scope->has('domain')) {
  62. return $node;
  63. }
  64. if ($node instanceof FilterExpression && in_array($node->getNode('filter')->getAttribute('value'), array('trans', 'transchoice'))) {
  65. $arguments = $node->getNode('arguments');
  66. $ind = 'trans' === $node->getNode('filter')->getAttribute('value') ? 1 : 2;
  67. if ($this->isNamedArguments($arguments)) {
  68. if (!$arguments->hasNode('domain') && !$arguments->hasNode($ind)) {
  69. $arguments->setNode('domain', $this->scope->get('domain'));
  70. }
  71. } else {
  72. if (!$arguments->hasNode($ind)) {
  73. if (!$arguments->hasNode($ind - 1)) {
  74. $arguments->setNode($ind - 1, new ArrayExpression(array(), $node->getTemplateLine()));
  75. }
  76. $arguments->setNode($ind, $this->scope->get('domain'));
  77. }
  78. }
  79. } elseif ($node instanceof TransNode) {
  80. if (!$node->hasNode('domain')) {
  81. $node->setNode('domain', $this->scope->get('domain'));
  82. }
  83. }
  84. return $node;
  85. }
  86. /**
  87. * {@inheritdoc}
  88. */
  89. protected function doLeaveNode(Node $node, Environment $env)
  90. {
  91. if ($node instanceof TransDefaultDomainNode) {
  92. return false;
  93. }
  94. if ($node instanceof BlockNode || $node instanceof ModuleNode) {
  95. $this->scope = $this->scope->leave();
  96. }
  97. return $node;
  98. }
  99. /**
  100. * {@inheritdoc}
  101. */
  102. public function getPriority()
  103. {
  104. return -10;
  105. }
  106. /**
  107. * @return bool
  108. */
  109. private function isNamedArguments($arguments)
  110. {
  111. foreach ($arguments as $name => $node) {
  112. if (!is_int($name)) {
  113. return true;
  114. }
  115. }
  116. return false;
  117. }
  118. private function getVarName()
  119. {
  120. return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
  121. }
  122. }