Macro.php (3691B)
1 <?php 2 3 /* 4 * This file is part of Twig. 5 * 6 * (c) 2009 Fabien Potencier 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12 /** 13 * Represents a macro node. 14 * 15 * @author Fabien Potencier <fabien@symfony.com> 16 */ 17 class Twig_Node_Macro extends Twig_Node 18 { 19 const VARARGS_NAME = 'varargs'; 20 21 public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface $arguments, $lineno, $tag = null) 22 { 23 foreach ($arguments as $argumentName => $argument) { 24 if (self::VARARGS_NAME === $argumentName) { 25 throw new Twig_Error_Syntax(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->getLine()); 26 } 27 } 28 29 parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag); 30 } 31 32 public function compile(Twig_Compiler $compiler) 33 { 34 $compiler 35 ->addDebugInfo($this) 36 ->write(sprintf('public function get%s(', $this->getAttribute('name'))) 37 ; 38 39 $count = count($this->getNode('arguments')); 40 $pos = 0; 41 foreach ($this->getNode('arguments') as $name => $default) { 42 $compiler 43 ->raw('$__'.$name.'__ = ') 44 ->subcompile($default) 45 ; 46 47 if (++$pos < $count) { 48 $compiler->raw(', '); 49 } 50 } 51 52 if (PHP_VERSION_ID >= 50600) { 53 if ($count) { 54 $compiler->raw(', '); 55 } 56 57 $compiler->raw('...$__varargs__'); 58 } 59 60 $compiler 61 ->raw(")\n") 62 ->write("{\n") 63 ->indent() 64 ; 65 66 $compiler 67 ->write("\$context = \$this->env->mergeGlobals(array(\n") 68 ->indent() 69 ; 70 71 foreach ($this->getNode('arguments') as $name => $default) { 72 $compiler 73 ->addIndentation() 74 ->string($name) 75 ->raw(' => $__'.$name.'__') 76 ->raw(",\n") 77 ; 78 } 79 80 $compiler 81 ->addIndentation() 82 ->string(self::VARARGS_NAME) 83 ->raw(' => ') 84 ; 85 86 if (PHP_VERSION_ID >= 50600) { 87 $compiler->raw("\$__varargs__,\n"); 88 } else { 89 $compiler 90 ->raw('func_num_args() > ') 91 ->repr($count) 92 ->raw(' ? array_slice(func_get_args(), ') 93 ->repr($count) 94 ->raw(") : array(),\n") 95 ; 96 } 97 98 $compiler 99 ->outdent() 100 ->write("));\n\n") 101 ->write("\$blocks = array();\n\n") 102 ->write("ob_start();\n") 103 ->write("try {\n") 104 ->indent() 105 ->subcompile($this->getNode('body')) 106 ->outdent() 107 ->write("} catch (Exception \$e) {\n") 108 ->indent() 109 ->write("ob_end_clean();\n\n") 110 ->write("throw \$e;\n") 111 ->outdent() 112 ->write("} catch (Throwable \$e) {\n") 113 ->indent() 114 ->write("ob_end_clean();\n\n") 115 ->write("throw \$e;\n") 116 ->outdent() 117 ->write("}\n\n") 118 ->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n") 119 ->outdent() 120 ->write("}\n\n") 121 ; 122 } 123 }