NodeTrans.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <?php
  2. declare(strict_types=1);
  3. namespace PhpMyAdmin\Twig\I18n;
  4. use PhpMyAdmin\Twig\Extensions\Node\TransNode;
  5. use Twig\Compiler;
  6. use Twig\Node\Expression\AbstractExpression;
  7. use Twig\Node\Node;
  8. use function array_merge;
  9. use function str_replace;
  10. use function trim;
  11. class NodeTrans extends TransNode
  12. {
  13. /**
  14. * The nodes are automatically made available as properties ($this->node).
  15. * The attributes are automatically made available as array items ($this['name']).
  16. *
  17. * @param Node $body Body of node trans
  18. * @param Node|null $plural Node plural
  19. * @param AbstractExpression $count Node count
  20. * @param Node|null $context Node context
  21. * @param Node|null $notes Node notes
  22. * @param int $lineno The line number
  23. * @param string $tag The tag name associated with the Node
  24. */
  25. public function __construct(
  26. Node $body,
  27. ?Node $plural,
  28. ?AbstractExpression $count,
  29. ?Node $context,
  30. ?Node $notes,
  31. int $lineno,
  32. string $tag
  33. ) {
  34. $nodes = ['body' => $body];
  35. if ($count !== null) {
  36. $nodes['count'] = $count;
  37. }
  38. if ($plural !== null) {
  39. $nodes['plural'] = $plural;
  40. }
  41. if ($context !== null) {
  42. $nodes['context'] = $context;
  43. }
  44. if ($notes !== null) {
  45. $nodes['notes'] = $notes;
  46. }
  47. Node::__construct($nodes, [], $lineno, $tag);
  48. }
  49. /**
  50. * Compiles the node to PHP.
  51. *
  52. * @param Compiler $compiler Node compiler
  53. *
  54. * @return void
  55. */
  56. public function compile(Compiler $compiler)
  57. {
  58. $compiler->addDebugInfo($this);
  59. [$msg, $vars] = $this->compileString($this->getNode('body'));
  60. $msg1 = null;
  61. if ($this->hasNode('plural')) {
  62. [$msg1, $vars1] = $this->compileString($this->getNode('plural'));
  63. $vars = array_merge($vars, $vars1);
  64. }
  65. $function = $this->getTransFunction(
  66. $this->hasNode('plural'),
  67. $this->hasNode('context')
  68. );
  69. if ($this->hasNode('notes')) {
  70. $message = trim($this->getNode('notes')->getAttribute('data'));
  71. // line breaks are not allowed cause we want a single line comment
  72. $message = str_replace(["\n", "\r"], ' ', $message);
  73. $compiler->write('// l10n: ' . $message . "\n");
  74. }
  75. if ($vars) {
  76. $compiler
  77. ->write('echo strtr(' . $function . '(')
  78. ->subcompile($msg);
  79. if ($this->hasNode('plural')) {
  80. $compiler
  81. ->raw(', ')
  82. ->subcompile($msg1)
  83. ->raw(', abs(')
  84. ->subcompile($this->hasNode('count') ? $this->getNode('count') : null)
  85. ->raw(')');
  86. }
  87. $compiler->raw('), array(');
  88. foreach ($vars as $var) {
  89. if ($var->getAttribute('name') === 'count') {
  90. $compiler
  91. ->string('%count%')
  92. ->raw(' => abs(')
  93. ->subcompile($this->hasNode('count') ? $this->getNode('count') : null)
  94. ->raw('), ');
  95. } else {
  96. $compiler
  97. ->string('%' . $var->getAttribute('name') . '%')
  98. ->raw(' => ')
  99. ->subcompile($var)
  100. ->raw(', ');
  101. }
  102. }
  103. $compiler->raw("));\n");
  104. } else {
  105. $compiler->write('echo ' . $function . '(');
  106. if ($this->hasNode('context')) {
  107. $context = trim($this->getNode('context')->getAttribute('data'));
  108. $compiler->write('"' . $context . '", ');
  109. }
  110. $compiler->subcompile($msg);
  111. if ($this->hasNode('plural')) {
  112. $compiler
  113. ->raw(', ')
  114. ->subcompile($msg1)
  115. ->raw(', abs(')
  116. ->subcompile($this->hasNode('count') ? $this->getNode('count') : null)
  117. ->raw(')');
  118. }
  119. $compiler->raw(");\n");
  120. }
  121. }
  122. /**
  123. * @param bool $plural Return plural or singular function to use
  124. * @param bool $hasMsgContext It has message context?
  125. */
  126. protected function getTransFunction($plural, bool $hasMsgContext = false): string
  127. {
  128. if ($hasMsgContext) {
  129. return $plural ? '_ngettext' : '_pgettext';
  130. }
  131. return $plural ? '_ngettext' : '_gettext';
  132. }
  133. }