vendor/jms/translation-bundle/Twig/DefaultApplyingNodeVisitor.php line 57

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. namespace JMS\TranslationBundle\Twig;
  19. use JMS\TranslationBundle\Exception\RuntimeException;
  20. use JMS\TranslationBundle\Twig\Node\Transchoice;
  21. use Twig\Environment;
  22. use Twig\Node\Expression\ArrayExpression;
  23. use Twig\Node\Expression\Binary\EqualBinary;
  24. use Twig\Node\Expression\ConditionalExpression;
  25. use Twig\Node\Expression\ConstantExpression;
  26. use Twig\Node\Expression\FilterExpression;
  27. use Twig\Node\Node;
  28. use Twig\NodeVisitor\AbstractNodeVisitor;
  29. /**
  30. * Applies the value of the "desc" filter if the "trans" filter has no
  31. * translations.
  32. *
  33. * This is only active in your development environment.
  34. *
  35. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  36. */
  37. class DefaultApplyingNodeVisitor extends AbstractNodeVisitor
  38. {
  39. /**
  40. * @var bool
  41. */
  42. private $enabled = true;
  43. public function setEnabled($bool)
  44. {
  45. $this->enabled = (bool) $bool;
  46. }
  47. /**
  48. * @return Node
  49. */
  50. public function doEnterNode(Node $node, Environment $env)
  51. {
  52. if (!$this->enabled) {
  53. return $node;
  54. }
  55. if (
  56. $node instanceof FilterExpression
  57. && 'desc' === $node->getNode('filter')->getAttribute('value')
  58. ) {
  59. $transNode = $node->getNode('node');
  60. while (
  61. $transNode instanceof FilterExpression
  62. && 'trans' !== $transNode->getNode('filter')->getAttribute('value')
  63. && 'transchoice' !== $transNode->getNode('filter')->getAttribute('value')
  64. ) {
  65. $transNode = $transNode->getNode('node');
  66. }
  67. if (!$transNode instanceof FilterExpression) {
  68. throw new RuntimeException(sprintf('The "desc" filter in "%s" line %d must be applied after a "trans", or "transchoice" filter.', $node->getTemplateName(), $node->getTemplateLine()));
  69. }
  70. $wrappingNode = $node->getNode('node');
  71. $testNode = clone $wrappingNode;
  72. $arguments = iterator_to_array($node->getNode('arguments'));
  73. $defaultNode = $arguments[0];
  74. // if the |transchoice filter is used, delegate the call to the TranslationExtension
  75. // so that we can catch a possible exception when the default translation has not yet
  76. // been extracted
  77. if ('transchoice' === $transNode->getNode('filter')->getAttribute('value')) {
  78. $transchoiceArguments = new ArrayExpression([], $transNode->getTemplateLine());
  79. $transchoiceArguments->addElement($wrappingNode->getNode('node'));
  80. $transchoiceArguments->addElement($defaultNode);
  81. foreach ($wrappingNode->getNode('arguments') as $arg) {
  82. $transchoiceArguments->addElement($arg);
  83. }
  84. $transchoiceNode = new Transchoice($transchoiceArguments, $transNode->getTemplateLine());
  85. $node->setNode('node', $transchoiceNode);
  86. return $node;
  87. }
  88. $wrappingNodeArguments = iterator_to_array($wrappingNode->getNode('arguments'));
  89. // if the |trans filter has replacements parameters
  90. // (e.g. |trans({'%foo%': 'bar'}))
  91. if (isset($wrappingNodeArguments[0])) {
  92. $lineno = $wrappingNode->getTemplateLine();
  93. // remove the replacements from the test node
  94. $testNodeArguments = iterator_to_array($testNode->getNode('arguments'));
  95. $testNodeArguments[0] = new ArrayExpression([], $lineno);
  96. $testNode->setNode('arguments', new Node($testNodeArguments));
  97. // wrap the default node in a |replace filter
  98. $defaultNode = new FilterExpression(
  99. $arguments[0],
  100. new ConstantExpression('replace', $lineno),
  101. new Node([$wrappingNodeArguments[0]]),
  102. $lineno
  103. );
  104. }
  105. $condition = new ConditionalExpression(
  106. new EqualBinary($testNode, $transNode->getNode('node'), $wrappingNode->getTemplateLine()),
  107. $defaultNode,
  108. clone $wrappingNode,
  109. $wrappingNode->getTemplateLine()
  110. );
  111. $node->setNode('node', $condition);
  112. }
  113. return $node;
  114. }
  115. /**
  116. * @return Node
  117. */
  118. public function doLeaveNode(Node $node, Environment $env)
  119. {
  120. return $node;
  121. }
  122. /**
  123. * @return int
  124. */
  125. public function getPriority()
  126. {
  127. return -2;
  128. }
  129. }