vendor/twig/twig/src/Node/MacroNode.php line 26

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of Twig.
  4. *
  5. * (c) Fabien Potencier
  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 Twig\Node;
  11. use Twig\Compiler;
  12. use Twig\Error\SyntaxError;
  13. /**
  14. * Represents a macro node.
  15. *
  16. * @author Fabien Potencier <fabien@symfony.com>
  17. */
  18. class MacroNode extends Node
  19. {
  20. public const VARARGS_NAME = 'varargs';
  21. public function __construct(string $name, Node $body, Node $arguments, int $lineno, string $tag = null)
  22. {
  23. foreach ($arguments as $argumentName => $argument) {
  24. if (self::VARARGS_NAME === $argumentName) {
  25. throw new SyntaxError(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getTemplateLine(), $argument->getSourceContext());
  26. }
  27. }
  28. parent::__construct(['body' => $body, 'arguments' => $arguments], ['name' => $name], $lineno, $tag);
  29. }
  30. public function compile(Compiler $compiler)
  31. {
  32. $compiler
  33. ->addDebugInfo($this)
  34. ->write(sprintf('public function macro_%s(', $this->getAttribute('name')))
  35. ;
  36. $count = \count($this->getNode('arguments'));
  37. $pos = 0;
  38. foreach ($this->getNode('arguments') as $name => $default) {
  39. $compiler
  40. ->raw('$__'.$name.'__ = ')
  41. ->subcompile($default)
  42. ;
  43. if (++$pos < $count) {
  44. $compiler->raw(', ');
  45. }
  46. }
  47. if ($count) {
  48. $compiler->raw(', ');
  49. }
  50. $compiler
  51. ->raw('...$__varargs__')
  52. ->raw(")\n")
  53. ->write("{\n")
  54. ->indent()
  55. ->write("\$macros = \$this->macros;\n")
  56. ->write("\$context = \$this->env->mergeGlobals([\n")
  57. ->indent()
  58. ;
  59. foreach ($this->getNode('arguments') as $name => $default) {
  60. $compiler
  61. ->write('')
  62. ->string($name)
  63. ->raw(' => $__'.$name.'__')
  64. ->raw(",\n")
  65. ;
  66. }
  67. $compiler
  68. ->write('')
  69. ->string(self::VARARGS_NAME)
  70. ->raw(' => ')
  71. ;
  72. $compiler
  73. ->raw("\$__varargs__,\n")
  74. ->outdent()
  75. ->write("]);\n\n")
  76. ->write("\$blocks = [];\n\n")
  77. ;
  78. if ($compiler->getEnvironment()->isDebug()) {
  79. $compiler->write("ob_start();\n");
  80. } else {
  81. $compiler->write("ob_start(function () { return ''; });\n");
  82. }
  83. $compiler
  84. ->write("try {\n")
  85. ->indent()
  86. ->subcompile($this->getNode('body'))
  87. ->raw("\n")
  88. ->write("return ('' === \$tmp = ob_get_contents()) ? '' : new Markup(\$tmp, \$this->env->getCharset());\n")
  89. ->outdent()
  90. ->write("} finally {\n")
  91. ->indent()
  92. ->write("ob_end_clean();\n")
  93. ->outdent()
  94. ->write("}\n")
  95. ->outdent()
  96. ->write("}\n\n")
  97. ;
  98. }
  99. }
  100. class_alias('Twig\Node\MacroNode', 'Twig_Node_Macro');