/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php

https://github.com/gimler/symfony · PHP · 134 lines · 91 code · 20 blank · 23 comment · 19 complexity · 1129d59ca2aac41883d32a21d8193939 MD5 · raw file

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