From 874b8cbf002e9d8bf0ff39671e1501165016320a Mon Sep 17 00:00:00 2001 From: Michael Save Date: Mon, 9 Apr 2012 20:52:26 +1000 Subject: inc/contrib -> inc/lib --- inc/lib/Twig/Node/AutoEscape.php | 40 +++ inc/lib/Twig/Node/Block.php | 45 +++ inc/lib/Twig/Node/BlockReference.php | 38 +++ inc/lib/Twig/Node/Expression.php | 21 ++ inc/lib/Twig/Node/Expression/Array.php | 41 +++ inc/lib/Twig/Node/Expression/AssignName.php | 24 ++ inc/lib/Twig/Node/Expression/Binary.php | 40 +++ inc/lib/Twig/Node/Expression/Binary/Add.php | 18 ++ inc/lib/Twig/Node/Expression/Binary/And.php | 18 ++ inc/lib/Twig/Node/Expression/Binary/BitwiseAnd.php | 18 ++ inc/lib/Twig/Node/Expression/Binary/BitwiseOr.php | 18 ++ inc/lib/Twig/Node/Expression/Binary/BitwiseXor.php | 18 ++ inc/lib/Twig/Node/Expression/Binary/Concat.php | 18 ++ inc/lib/Twig/Node/Expression/Binary/Div.php | 18 ++ inc/lib/Twig/Node/Expression/Binary/Equal.php | 17 ++ inc/lib/Twig/Node/Expression/Binary/FloorDiv.php | 29 ++ inc/lib/Twig/Node/Expression/Binary/Greater.php | 17 ++ .../Twig/Node/Expression/Binary/GreaterEqual.php | 17 ++ inc/lib/Twig/Node/Expression/Binary/In.php | 33 +++ inc/lib/Twig/Node/Expression/Binary/Less.php | 17 ++ inc/lib/Twig/Node/Expression/Binary/LessEqual.php | 17 ++ inc/lib/Twig/Node/Expression/Binary/Mod.php | 18 ++ inc/lib/Twig/Node/Expression/Binary/Mul.php | 18 ++ inc/lib/Twig/Node/Expression/Binary/NotEqual.php | 17 ++ inc/lib/Twig/Node/Expression/Binary/NotIn.php | 33 +++ inc/lib/Twig/Node/Expression/Binary/Or.php | 18 ++ inc/lib/Twig/Node/Expression/Binary/Power.php | 33 +++ inc/lib/Twig/Node/Expression/Binary/Range.php | 33 +++ inc/lib/Twig/Node/Expression/Binary/Sub.php | 18 ++ inc/lib/Twig/Node/Expression/BlockReference.php | 52 ++++ inc/lib/Twig/Node/Expression/Conditional.php | 31 +++ inc/lib/Twig/Node/Expression/Constant.php | 23 ++ .../Twig/Node/Expression/ExtensionReference.php | 34 +++ inc/lib/Twig/Node/Expression/Filter.php | 72 +++++ inc/lib/Twig/Node/Expression/Function.php | 49 ++++ inc/lib/Twig/Node/Expression/GetAttr.php | 53 ++++ inc/lib/Twig/Node/Expression/Name.php | 41 +++ inc/lib/Twig/Node/Expression/Parent.php | 39 +++ inc/lib/Twig/Node/Expression/Test.php | 60 ++++ inc/lib/Twig/Node/Expression/Unary.php | 30 ++ inc/lib/Twig/Node/Expression/Unary/Neg.php | 18 ++ inc/lib/Twig/Node/Expression/Unary/Not.php | 18 ++ inc/lib/Twig/Node/Expression/Unary/Pos.php | 18 ++ inc/lib/Twig/Node/For.php | 141 ++++++++++ inc/lib/Twig/Node/If.php | 67 +++++ inc/lib/Twig/Node/Import.php | 51 ++++ inc/lib/Twig/Node/Include.php | 88 ++++++ inc/lib/Twig/Node/Macro.php | 73 +++++ inc/lib/Twig/Node/Module.php | 302 +++++++++++++++++++++ inc/lib/Twig/Node/Print.php | 40 +++ inc/lib/Twig/Node/Sandbox.php | 48 ++++ inc/lib/Twig/Node/SandboxedModule.php | 71 +++++ inc/lib/Twig/Node/SandboxedPrint.php | 60 ++++ inc/lib/Twig/Node/Set.php | 102 +++++++ inc/lib/Twig/Node/Spaceless.php | 41 +++ inc/lib/Twig/Node/Text.php | 40 +++ 56 files changed, 2372 insertions(+) create mode 100644 inc/lib/Twig/Node/AutoEscape.php create mode 100644 inc/lib/Twig/Node/Block.php create mode 100644 inc/lib/Twig/Node/BlockReference.php create mode 100644 inc/lib/Twig/Node/Expression.php create mode 100644 inc/lib/Twig/Node/Expression/Array.php create mode 100644 inc/lib/Twig/Node/Expression/AssignName.php create mode 100644 inc/lib/Twig/Node/Expression/Binary.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Add.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/And.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/BitwiseAnd.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/BitwiseOr.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/BitwiseXor.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Concat.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Div.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Equal.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/FloorDiv.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Greater.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/GreaterEqual.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/In.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Less.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/LessEqual.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Mod.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Mul.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/NotEqual.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/NotIn.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Or.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Power.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Range.php create mode 100644 inc/lib/Twig/Node/Expression/Binary/Sub.php create mode 100644 inc/lib/Twig/Node/Expression/BlockReference.php create mode 100644 inc/lib/Twig/Node/Expression/Conditional.php create mode 100644 inc/lib/Twig/Node/Expression/Constant.php create mode 100644 inc/lib/Twig/Node/Expression/ExtensionReference.php create mode 100644 inc/lib/Twig/Node/Expression/Filter.php create mode 100644 inc/lib/Twig/Node/Expression/Function.php create mode 100644 inc/lib/Twig/Node/Expression/GetAttr.php create mode 100644 inc/lib/Twig/Node/Expression/Name.php create mode 100644 inc/lib/Twig/Node/Expression/Parent.php create mode 100644 inc/lib/Twig/Node/Expression/Test.php create mode 100644 inc/lib/Twig/Node/Expression/Unary.php create mode 100644 inc/lib/Twig/Node/Expression/Unary/Neg.php create mode 100644 inc/lib/Twig/Node/Expression/Unary/Not.php create mode 100644 inc/lib/Twig/Node/Expression/Unary/Pos.php create mode 100644 inc/lib/Twig/Node/For.php create mode 100644 inc/lib/Twig/Node/If.php create mode 100644 inc/lib/Twig/Node/Import.php create mode 100644 inc/lib/Twig/Node/Include.php create mode 100644 inc/lib/Twig/Node/Macro.php create mode 100644 inc/lib/Twig/Node/Module.php create mode 100644 inc/lib/Twig/Node/Print.php create mode 100644 inc/lib/Twig/Node/Sandbox.php create mode 100644 inc/lib/Twig/Node/SandboxedModule.php create mode 100644 inc/lib/Twig/Node/SandboxedPrint.php create mode 100644 inc/lib/Twig/Node/Set.php create mode 100644 inc/lib/Twig/Node/Spaceless.php create mode 100644 inc/lib/Twig/Node/Text.php (limited to 'inc/lib/Twig/Node') diff --git a/inc/lib/Twig/Node/AutoEscape.php b/inc/lib/Twig/Node/AutoEscape.php new file mode 100644 index 00000000..a0c2ee6d --- /dev/null +++ b/inc/lib/Twig/Node/AutoEscape.php @@ -0,0 +1,40 @@ + + */ +class Twig_Node_AutoEscape extends Twig_Node +{ + public function __construct($value, Twig_NodeInterface $body, $lineno, $tag = 'autoescape') + { + parent::__construct(array('body' => $body), array('value' => $value), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->subcompile($this->getNode('body')); + } +} diff --git a/inc/lib/Twig/Node/Block.php b/inc/lib/Twig/Node/Block.php new file mode 100644 index 00000000..5548ad06 --- /dev/null +++ b/inc/lib/Twig/Node/Block.php @@ -0,0 +1,45 @@ + + */ +class Twig_Node_Block extends Twig_Node +{ + public function __construct($name, Twig_NodeInterface $body, $lineno, $tag = null) + { + parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write(sprintf("public function block_%s(\$context, array \$blocks = array())\n", $this->getAttribute('name')), "{\n") + ->indent() + ; + + $compiler + ->subcompile($this->getNode('body')) + ->outdent() + ->write("}\n\n") + ; + } +} diff --git a/inc/lib/Twig/Node/BlockReference.php b/inc/lib/Twig/Node/BlockReference.php new file mode 100644 index 00000000..53f6287c --- /dev/null +++ b/inc/lib/Twig/Node/BlockReference.php @@ -0,0 +1,38 @@ + + */ +class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInterface +{ + public function __construct($name, $lineno, $tag = null) + { + parent::__construct(array(), array('name' => $name), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write(sprintf("\$this->displayBlock('%s', \$context, \$blocks);\n", $this->getAttribute('name'))) + ; + } +} diff --git a/inc/lib/Twig/Node/Expression.php b/inc/lib/Twig/Node/Expression.php new file mode 100644 index 00000000..13b170e5 --- /dev/null +++ b/inc/lib/Twig/Node/Expression.php @@ -0,0 +1,21 @@ + + */ +abstract class Twig_Node_Expression extends Twig_Node +{ +} diff --git a/inc/lib/Twig/Node/Expression/Array.php b/inc/lib/Twig/Node/Expression/Array.php new file mode 100644 index 00000000..2d860823 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Array.php @@ -0,0 +1,41 @@ +raw('array('); + $first = true; + foreach ($this->nodes as $name => $node) { + if (!$first) { + $compiler->raw(', '); + } + $first = false; + + $compiler + ->repr($name) + ->raw(' => ') + ->subcompile($node) + ; + } + $compiler->raw(')'); + } +} diff --git a/inc/lib/Twig/Node/Expression/AssignName.php b/inc/lib/Twig/Node/Expression/AssignName.php new file mode 100644 index 00000000..67f12509 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/AssignName.php @@ -0,0 +1,24 @@ +raw(sprintf('$context[\'%s\']', $this->getAttribute('name'))); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary.php b/inc/lib/Twig/Node/Expression/Binary.php new file mode 100644 index 00000000..9dd5de2c --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary.php @@ -0,0 +1,40 @@ + $left, 'right' => $right), array(), $lineno); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->raw('(') + ->subcompile($this->getNode('left')) + ->raw(' ') + ; + $this->operator($compiler); + $compiler + ->raw(' ') + ->subcompile($this->getNode('right')) + ->raw(')') + ; + } + + abstract public function operator(Twig_Compiler $compiler); +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Add.php b/inc/lib/Twig/Node/Expression/Binary/Add.php new file mode 100644 index 00000000..0ef8e117 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Add.php @@ -0,0 +1,18 @@ +raw('+'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/And.php b/inc/lib/Twig/Node/Expression/Binary/And.php new file mode 100644 index 00000000..d5752ebb --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/And.php @@ -0,0 +1,18 @@ +raw('&&'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/BitwiseAnd.php b/inc/lib/Twig/Node/Expression/Binary/BitwiseAnd.php new file mode 100644 index 00000000..9a46d845 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/BitwiseAnd.php @@ -0,0 +1,18 @@ +raw('&'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/BitwiseOr.php b/inc/lib/Twig/Node/Expression/Binary/BitwiseOr.php new file mode 100644 index 00000000..058a20bf --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/BitwiseOr.php @@ -0,0 +1,18 @@ +raw('|'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/BitwiseXor.php b/inc/lib/Twig/Node/Expression/Binary/BitwiseXor.php new file mode 100644 index 00000000..f4da73d4 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/BitwiseXor.php @@ -0,0 +1,18 @@ +raw('^'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Concat.php b/inc/lib/Twig/Node/Expression/Binary/Concat.php new file mode 100644 index 00000000..f9a64627 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Concat.php @@ -0,0 +1,18 @@ +raw('.'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Div.php b/inc/lib/Twig/Node/Expression/Binary/Div.php new file mode 100644 index 00000000..e0797a61 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Div.php @@ -0,0 +1,18 @@ +raw('/'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Equal.php b/inc/lib/Twig/Node/Expression/Binary/Equal.php new file mode 100644 index 00000000..7b1236d0 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Equal.php @@ -0,0 +1,17 @@ +raw('=='); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/FloorDiv.php b/inc/lib/Twig/Node/Expression/Binary/FloorDiv.php new file mode 100644 index 00000000..e86b1ea0 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/FloorDiv.php @@ -0,0 +1,29 @@ +raw('floor('); + parent::compile($compiler); + $compiler->raw(')'); + } + + public function operator(Twig_Compiler $compiler) + { + return $compiler->raw('/'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Greater.php b/inc/lib/Twig/Node/Expression/Binary/Greater.php new file mode 100644 index 00000000..a110bd92 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Greater.php @@ -0,0 +1,17 @@ +raw('>'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/GreaterEqual.php b/inc/lib/Twig/Node/Expression/Binary/GreaterEqual.php new file mode 100644 index 00000000..3754fed2 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/GreaterEqual.php @@ -0,0 +1,17 @@ +raw('>='); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/In.php b/inc/lib/Twig/Node/Expression/Binary/In.php new file mode 100644 index 00000000..788f9377 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/In.php @@ -0,0 +1,33 @@ +raw('twig_in_filter(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw(')') + ; + } + + public function operator(Twig_Compiler $compiler) + { + return $compiler->raw('in'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Less.php b/inc/lib/Twig/Node/Expression/Binary/Less.php new file mode 100644 index 00000000..45fd3004 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Less.php @@ -0,0 +1,17 @@ +raw('<'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/LessEqual.php b/inc/lib/Twig/Node/Expression/Binary/LessEqual.php new file mode 100644 index 00000000..e38e257c --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/LessEqual.php @@ -0,0 +1,17 @@ +raw('<='); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Mod.php b/inc/lib/Twig/Node/Expression/Binary/Mod.php new file mode 100644 index 00000000..9924114f --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Mod.php @@ -0,0 +1,18 @@ +raw('%'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Mul.php b/inc/lib/Twig/Node/Expression/Binary/Mul.php new file mode 100644 index 00000000..c91529ca --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Mul.php @@ -0,0 +1,18 @@ +raw('*'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/NotEqual.php b/inc/lib/Twig/Node/Expression/Binary/NotEqual.php new file mode 100644 index 00000000..26867ba2 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/NotEqual.php @@ -0,0 +1,17 @@ +raw('!='); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/NotIn.php b/inc/lib/Twig/Node/Expression/Binary/NotIn.php new file mode 100644 index 00000000..f347b7b6 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/NotIn.php @@ -0,0 +1,33 @@ +raw('!twig_in_filter(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw(')') + ; + } + + public function operator(Twig_Compiler $compiler) + { + return $compiler->raw('not in'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Or.php b/inc/lib/Twig/Node/Expression/Binary/Or.php new file mode 100644 index 00000000..adba49c6 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Or.php @@ -0,0 +1,18 @@ +raw('||'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Power.php b/inc/lib/Twig/Node/Expression/Binary/Power.php new file mode 100644 index 00000000..b2c59040 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Power.php @@ -0,0 +1,33 @@ +raw('pow(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw(')') + ; + } + + public function operator(Twig_Compiler $compiler) + { + return $compiler->raw('**'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Range.php b/inc/lib/Twig/Node/Expression/Binary/Range.php new file mode 100644 index 00000000..bea4f2a6 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Range.php @@ -0,0 +1,33 @@ +raw('range(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw(')') + ; + } + + public function operator(Twig_Compiler $compiler) + { + return $compiler->raw('..'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Binary/Sub.php b/inc/lib/Twig/Node/Expression/Binary/Sub.php new file mode 100644 index 00000000..d4463991 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Binary/Sub.php @@ -0,0 +1,18 @@ +raw('-'); + } +} diff --git a/inc/lib/Twig/Node/Expression/BlockReference.php b/inc/lib/Twig/Node/Expression/BlockReference.php new file mode 100644 index 00000000..174d9097 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/BlockReference.php @@ -0,0 +1,52 @@ + + */ +class Twig_Node_Expression_BlockReference extends Twig_Node_Expression +{ + public function __construct(Twig_NodeInterface $name, $asString = false, $lineno, $tag = null) + { + parent::__construct(array('name' => $name), array('as_string' => $asString, 'output' => false), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + if ($this->getAttribute('as_string')) { + $compiler->raw('(string) '); + } + + if ($this->getAttribute('output')) { + $compiler + ->addDebugInfo($this) + ->write("\$this->displayBlock(") + ->subcompile($this->getNode('name')) + ->raw(", \$context, \$blocks);\n") + ; + } else { + $compiler + ->raw("\$this->renderBlock(") + ->subcompile($this->getNode('name')) + ->raw(", \$context, \$blocks)") + ; + } + } +} diff --git a/inc/lib/Twig/Node/Expression/Conditional.php b/inc/lib/Twig/Node/Expression/Conditional.php new file mode 100644 index 00000000..edcb1e2d --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Conditional.php @@ -0,0 +1,31 @@ + $expr1, 'expr2' => $expr2, 'expr3' => $expr3), array(), $lineno); + } + + public function compile(Twig_Compiler $compiler) + { + $compiler + ->raw('((') + ->subcompile($this->getNode('expr1')) + ->raw(') ? (') + ->subcompile($this->getNode('expr2')) + ->raw(') : (') + ->subcompile($this->getNode('expr3')) + ->raw('))') + ; + } +} diff --git a/inc/lib/Twig/Node/Expression/Constant.php b/inc/lib/Twig/Node/Expression/Constant.php new file mode 100644 index 00000000..a91dc698 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Constant.php @@ -0,0 +1,23 @@ + $value), $lineno); + } + + public function compile(Twig_Compiler $compiler) + { + $compiler->repr($this->getAttribute('value')); + } +} diff --git a/inc/lib/Twig/Node/Expression/ExtensionReference.php b/inc/lib/Twig/Node/Expression/ExtensionReference.php new file mode 100644 index 00000000..cb4efad0 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/ExtensionReference.php @@ -0,0 +1,34 @@ + + */ +class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression +{ + public function __construct($name, $lineno, $tag = null) + { + parent::__construct(array(), array('name' => $name), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name'))); + } +} diff --git a/inc/lib/Twig/Node/Expression/Filter.php b/inc/lib/Twig/Node/Expression/Filter.php new file mode 100644 index 00000000..101e6df0 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Filter.php @@ -0,0 +1,72 @@ + $node, 'filter' => $filterName, 'arguments' => $arguments), array(), $lineno, $tag); + } + + public function compile(Twig_Compiler $compiler) + { + $name = $this->getNode('filter')->getAttribute('value'); + if (false === $filter = $compiler->getEnvironment()->getFilter($name)) { + throw new Twig_Error_Syntax(sprintf('The filter "%s" does not exist', $name), $this->getLine()); + } + + $node = $this->getNode('node'); + + // The default filter is intercepted when the filtered value + // is a name (like obj) or an attribute (like obj.attr) + // In such a case, it's compiled to {{ obj is defined ? obj|default('bar') : 'bar' }} + if ('default' === $name && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) { + $compiler + ->raw('((') + ->subcompile(new Twig_Node_Expression_Test($node, 'defined', new Twig_Node(), $this->getLine())) + ->raw(') ? (') + ; + + $this->compileFilter($compiler, $filter); + + $compiler->raw(') : ('); + + if ($this->getNode('arguments')->hasNode(0)) { + $compiler->subcompile($this->getNode('arguments')->getNode(0)); + } else { + $compiler->string(''); + } + + $compiler->raw('))'); + } else { + $this->compileFilter($compiler, $filter); + } + } + + protected function compileFilter(Twig_Compiler $compiler, Twig_FilterInterface $filter) + { + $compiler + ->raw($filter->compile().'(') + ->raw($filter->needsEnvironment() ? '$this->env, ' : '') + ->raw($filter->needsContext() ? '$context, ' : '') + ->subcompile($this->getNode('node')) + ; + + foreach ($this->getNode('arguments') as $node) { + $compiler + ->raw(', ') + ->subcompile($node) + ; + } + + $compiler->raw(')'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Function.php b/inc/lib/Twig/Node/Expression/Function.php new file mode 100644 index 00000000..3f457199 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Function.php @@ -0,0 +1,49 @@ + $arguments), array('name' => $name), $lineno); + } + + public function compile(Twig_Compiler $compiler) + { + $function = $compiler->getEnvironment()->getFunction($this->getAttribute('name')); + if (false === $function) { + throw new Twig_Error_Syntax(sprintf('The function "%s" does not exist', $this->getAttribute('name')), $this->getLine()); + } + + $compiler + ->raw($function->compile().'(') + ->raw($function->needsEnvironment() ? '$this->env' : '') + ; + + if ($function->needsContext()) { + $compiler->raw($function->needsEnvironment() ? ', $context' : '$context'); + } + + $first = true; + foreach ($this->getNode('arguments') as $node) { + if (!$first) { + $compiler->raw(', '); + } else { + if ($function->needsEnvironment() || $function->needsContext()) { + $compiler->raw(', '); + } + $first = false; + } + $compiler->subcompile($node); + } + + $compiler->raw(')'); + } +} diff --git a/inc/lib/Twig/Node/Expression/GetAttr.php b/inc/lib/Twig/Node/Expression/GetAttr.php new file mode 100644 index 00000000..eb9e6050 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/GetAttr.php @@ -0,0 +1,53 @@ + $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type), $lineno); + } + + public function compile(Twig_Compiler $compiler) + { + $compiler->raw('$this->getAttribute('); + + if ($this->hasAttribute('is_defined_test') && $compiler->getEnvironment()->isStrictVariables()) { + $compiler->subcompile(new Twig_Node_Expression_Filter( + $this->getNode('node'), + new Twig_Node_Expression_Constant('default', $this->getLine()), + new Twig_Node(), + $this->getLine() + )); + } else { + $compiler->subcompile($this->getNode('node')); + } + + $compiler + ->raw(', ') + ->subcompile($this->getNode('attribute')) + ->raw(', array(') + ; + + foreach ($this->getNode('arguments') as $node) { + $compiler + ->subcompile($node) + ->raw(', ') + ; + } + + $compiler + ->raw('), ') + ->repr($this->getAttribute('type')) + ->raw($this->hasAttribute('is_defined_test') ? ', true' : ', false') + ->raw(')'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Name.php b/inc/lib/Twig/Node/Expression/Name.php new file mode 100644 index 00000000..fceda2b7 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Name.php @@ -0,0 +1,41 @@ + $name), $lineno); + } + + public function compile(Twig_Compiler $compiler) + { + static $specialVars = array( + '_self' => '$this', + '_context' => '$context', + '_charset' => '$this->env->getCharset()', + ); + + $name = $this->getAttribute('name'); + + if ($this->hasAttribute('is_defined_test')) { + if (isset($specialVars[$name])) { + $compiler->repr(true); + } else { + $compiler->raw('array_key_exists(')->repr($name)->raw(', $context)'); + } + } elseif (isset($specialVars[$name])) { + $compiler->raw($specialVars[$name]); + } else { + $compiler->raw(sprintf('$this->getContext($context, \'%s\')', $name)); + } + } +} diff --git a/inc/lib/Twig/Node/Expression/Parent.php b/inc/lib/Twig/Node/Expression/Parent.php new file mode 100644 index 00000000..5689fe45 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Parent.php @@ -0,0 +1,39 @@ + + */ +class Twig_Node_Expression_Parent extends Twig_Node_Expression +{ + public function __construct($name, $lineno, $tag = null) + { + parent::__construct(array(), array('name' => $name), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->raw("\$this->renderParentBlock(") + ->string($this->getAttribute('name')) + ->raw(", \$context, \$blocks)") + ; + } +} diff --git a/inc/lib/Twig/Node/Expression/Test.php b/inc/lib/Twig/Node/Expression/Test.php new file mode 100644 index 00000000..ef35df6b --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Test.php @@ -0,0 +1,60 @@ + $node, 'arguments' => $arguments), array('name' => $name), $lineno); + } + + public function compile(Twig_Compiler $compiler) + { + $testMap = $compiler->getEnvironment()->getTests(); + if (!isset($testMap[$this->getAttribute('name')])) { + throw new Twig_Error_Syntax(sprintf('The test "%s" does not exist', $this->getAttribute('name')), $this->getLine()); + } + + $name = $this->getAttribute('name'); + $node = $this->getNode('node'); + + // defined is a special case + if ('defined' === $name) { + if ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr) { + $node->setAttribute('is_defined_test', true); + $compiler->subcompile($node); + $node->removeAttribute('is_defined_test'); + } else { + throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine()); + } + return; + } + + $compiler + ->raw($testMap[$name]->compile().'(') + ->subcompile($node) + ; + + if (null !== $this->getNode('arguments')) { + $compiler->raw(', '); + + $max = count($this->getNode('arguments')) - 1; + foreach ($this->getNode('arguments') as $i => $arg) { + $compiler->subcompile($arg); + + if ($i != $max) { + $compiler->raw(', '); + } + } + } + + $compiler->raw(')'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Unary.php b/inc/lib/Twig/Node/Expression/Unary.php new file mode 100644 index 00000000..c514388e --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Unary.php @@ -0,0 +1,30 @@ + $node), array(), $lineno); + } + + public function compile(Twig_Compiler $compiler) + { + $compiler->raw('('); + $this->operator($compiler); + $compiler + ->subcompile($this->getNode('node')) + ->raw(')') + ; + } + + abstract public function operator(Twig_Compiler $compiler); +} diff --git a/inc/lib/Twig/Node/Expression/Unary/Neg.php b/inc/lib/Twig/Node/Expression/Unary/Neg.php new file mode 100644 index 00000000..2a3937ec --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Unary/Neg.php @@ -0,0 +1,18 @@ +raw('-'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Unary/Not.php b/inc/lib/Twig/Node/Expression/Unary/Not.php new file mode 100644 index 00000000..f94073cf --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Unary/Not.php @@ -0,0 +1,18 @@ +raw('!'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Unary/Pos.php b/inc/lib/Twig/Node/Expression/Unary/Pos.php new file mode 100644 index 00000000..04edb52a --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Unary/Pos.php @@ -0,0 +1,18 @@ +raw('+'); + } +} diff --git a/inc/lib/Twig/Node/For.php b/inc/lib/Twig/Node/For.php new file mode 100644 index 00000000..eb204e28 --- /dev/null +++ b/inc/lib/Twig/Node/For.php @@ -0,0 +1,141 @@ + + */ +class Twig_Node_For extends Twig_Node +{ + public function __construct(Twig_Node_Expression_AssignName $keyTarget, Twig_Node_Expression_AssignName $valueTarget, Twig_Node_Expression $seq, Twig_Node_Expression $ifexpr = null, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null) + { + parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'ifexpr' => $ifexpr, 'body' => $body, 'else' => $else), array('with_loop' => true), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + // the (array) cast bypasses a PHP 5.2.6 bug + ->write("\$context['_parent'] = (array) \$context;\n") + ->write("\$context['_seq'] = twig_ensure_traversable(") + ->subcompile($this->getNode('seq')) + ->raw(");\n") + ; + + if (null !== $this->getNode('else')) { + $compiler->write("\$context['_iterated'] = false;\n"); + } + + if ($this->getAttribute('with_loop')) { + $compiler + ->write("\$context['loop'] = array(\n") + ->write(" 'parent' => \$context['_parent'],\n") + ->write(" 'index0' => 0,\n") + ->write(" 'index' => 1,\n") + ->write(" 'first' => true,\n") + ->write(");\n") + ; + + if (null === $this->getNode('ifexpr')) { + $compiler + ->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) {\n") + ->indent() + ->write("\$length = count(\$context['_seq']);\n") + ->write("\$context['loop']['revindex0'] = \$length - 1;\n") + ->write("\$context['loop']['revindex'] = \$length;\n") + ->write("\$context['loop']['length'] = \$length;\n") + ->write("\$context['loop']['last'] = 1 === \$length;\n") + ->outdent() + ->write("}\n") + ; + } + } + + $compiler + ->write("foreach (\$context['_seq'] as ") + ->subcompile($this->getNode('key_target')) + ->raw(" => ") + ->subcompile($this->getNode('value_target')) + ->raw(") {\n") + ->indent() + ; + + if (null !== $this->getNode('ifexpr')) { + $compiler + ->write("if (!(") + ->subcompile($this->getNode('ifexpr')) + ->raw(")) {\n") + ->indent() + ->write("continue;\n") + ->outdent() + ->write("}\n\n") + ; + } + + $compiler->subcompile($this->getNode('body')); + + if (null !== $this->getNode('else')) { + $compiler->write("\$context['_iterated'] = true;\n"); + } + + if ($this->getAttribute('with_loop')) { + $compiler + ->write("++\$context['loop']['index0'];\n") + ->write("++\$context['loop']['index'];\n") + ->write("\$context['loop']['first'] = false;\n") + ; + + if (null === $this->getNode('ifexpr')) { + $compiler + ->write("if (isset(\$context['loop']['length'])) {\n") + ->indent() + ->write("--\$context['loop']['revindex0'];\n") + ->write("--\$context['loop']['revindex'];\n") + ->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n") + ->outdent() + ->write("}\n") + ; + } + } + + $compiler + ->outdent() + ->write("}\n") + ; + + if (null !== $this->getNode('else')) { + $compiler + ->write("if (!\$context['_iterated']) {\n") + ->indent() + ->subcompile($this->getNode('else')) + ->outdent() + ->write("}\n") + ; + } + + $compiler->write("\$_parent = \$context['_parent'];\n"); + + // remove some "private" loop variables (needed for nested loops) + $compiler->write('unset($context[\'_seq\'], $context[\'_iterated\'], $context[\''.$this->getNode('key_target')->getAttribute('name').'\'], $context[\''.$this->getNode('value_target')->getAttribute('name').'\'], $context[\'_parent\'], $context[\'loop\']);'."\n"); + + // keep the values set in the inner context for variables defined in the outer context + $compiler->write("\$context = array_merge(\$_parent, array_intersect_key(\$context, \$_parent));\n"); + } +} diff --git a/inc/lib/Twig/Node/If.php b/inc/lib/Twig/Node/If.php new file mode 100644 index 00000000..aa12efbe --- /dev/null +++ b/inc/lib/Twig/Node/If.php @@ -0,0 +1,67 @@ + + */ +class Twig_Node_If extends Twig_Node +{ + public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null) + { + parent::__construct(array('tests' => $tests, 'else' => $else), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); + for ($i = 0; $i < count($this->getNode('tests')); $i += 2) { + if ($i > 0) { + $compiler + ->outdent() + ->write("} elseif (") + ; + } else { + $compiler + ->write('if (') + ; + } + + $compiler + ->subcompile($this->getNode('tests')->getNode($i)) + ->raw(") {\n") + ->indent() + ->subcompile($this->getNode('tests')->getNode($i + 1)) + ; + } + + if ($this->hasNode('else') && null !== $this->getNode('else')) { + $compiler + ->outdent() + ->write("} else {\n") + ->indent() + ->subcompile($this->getNode('else')) + ; + } + + $compiler + ->outdent() + ->write("}\n"); + } +} diff --git a/inc/lib/Twig/Node/Import.php b/inc/lib/Twig/Node/Import.php new file mode 100644 index 00000000..a327411d --- /dev/null +++ b/inc/lib/Twig/Node/Import.php @@ -0,0 +1,51 @@ + + */ +class Twig_Node_Import extends Twig_Node +{ + public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $var, $lineno, $tag = null) + { + parent::__construct(array('expr' => $expr, 'var' => $var), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write('') + ->subcompile($this->getNode('var')) + ->raw(' = ') + ; + + if ($this->getNode('expr') instanceof Twig_Node_Expression_Name && '_self' === $this->getNode('expr')->getAttribute('name')) { + $compiler->raw("\$this"); + } else { + $compiler + ->raw('$this->env->loadTemplate(') + ->subcompile($this->getNode('expr')) + ->raw(")") + ; + } + + $compiler->raw(";\n"); + } +} diff --git a/inc/lib/Twig/Node/Include.php b/inc/lib/Twig/Node/Include.php new file mode 100644 index 00000000..467749b5 --- /dev/null +++ b/inc/lib/Twig/Node/Include.php @@ -0,0 +1,88 @@ + + */ +class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface +{ + public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) + { + parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (Boolean) $only, 'ignore_missing' => (Boolean) $ignoreMissing), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); + + if ($this->getAttribute('ignore_missing')) { + $compiler + ->write("try {\n") + ->indent() + ; + } + + if ($this->getNode('expr') instanceof Twig_Node_Expression_Constant) { + $compiler + ->write("\$this->env->loadTemplate(") + ->subcompile($this->getNode('expr')) + ->raw(")->display(") + ; + } else { + $compiler + ->write("\$template = \$this->env->resolveTemplate(") + ->subcompile($this->getNode('expr')) + ->raw(");\n") + ->write('$template->display(') + ; + } + + if (false === $this->getAttribute('only')) { + if (null === $this->getNode('variables')) { + $compiler->raw('$context'); + } else { + $compiler + ->raw('array_merge($context, ') + ->subcompile($this->getNode('variables')) + ->raw(')') + ; + } + } else { + if (null === $this->getNode('variables')) { + $compiler->raw('array()'); + } else { + $compiler->subcompile($this->getNode('variables')); + } + } + + $compiler->raw(");\n"); + + if ($this->getAttribute('ignore_missing')) { + $compiler + ->outdent() + ->write("} catch (Twig_Error_Loader \$e) {\n") + ->indent() + ->write("// ignore missing template\n") + ->outdent() + ->write("}\n\n") + ; + } + } +} diff --git a/inc/lib/Twig/Node/Macro.php b/inc/lib/Twig/Node/Macro.php new file mode 100644 index 00000000..9f95570f --- /dev/null +++ b/inc/lib/Twig/Node/Macro.php @@ -0,0 +1,73 @@ + + */ +class Twig_Node_Macro extends Twig_Node +{ + public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface $arguments, $lineno, $tag = null) + { + parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $arguments = array(); + foreach ($this->getNode('arguments') as $argument) { + $arguments[] = '$'.$argument->getAttribute('name').' = null'; + } + + $compiler + ->addDebugInfo($this) + ->write(sprintf("public function get%s(%s)\n", $this->getAttribute('name'), implode(', ', $arguments)), "{\n") + ->indent() + ->write("\$context = array_merge(\$this->env->getGlobals(), array(\n") + ->indent() + ; + + foreach ($this->getNode('arguments') as $argument) { + $compiler + ->write('') + ->string($argument->getAttribute('name')) + ->raw(' => $'.$argument->getAttribute('name')) + ->raw(",\n") + ; + } + + $compiler + ->outdent() + ->write("));\n\n") + ->write("ob_start();\n") + ->write("try {\n") + ->indent() + ->subcompile($this->getNode('body')) + ->outdent() + ->write("} catch(Exception \$e) {\n") + ->indent() + ->write("ob_end_clean();\n\n") + ->write("throw \$e;\n") + ->outdent() + ->write("}\n\n") + ->write("return ob_get_clean();\n") + ->outdent() + ->write("}\n\n") + ; + } +} diff --git a/inc/lib/Twig/Node/Module.php b/inc/lib/Twig/Node/Module.php new file mode 100644 index 00000000..9b8c55e3 --- /dev/null +++ b/inc/lib/Twig/Node/Module.php @@ -0,0 +1,302 @@ + + */ +class Twig_Node_Module extends Twig_Node +{ + public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $filename) + { + parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits), array('filename' => $filename), 1); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $this->compileTemplate($compiler); + } + + protected function compileTemplate(Twig_Compiler $compiler) + { + $this->compileClassHeader($compiler); + + if (count($this->getNode('blocks')) || count($this->getNode('traits'))) { + $this->compileConstructor($compiler); + } + + $this->compileGetParent($compiler); + + $this->compileDisplayHeader($compiler); + + $this->compileDisplayBody($compiler); + + $this->compileDisplayFooter($compiler); + + $compiler->subcompile($this->getNode('blocks')); + + $this->compileMacros($compiler); + + $this->compileGetTemplateName($compiler); + + $this->compileIsTraitable($compiler); + + $this->compileClassFooter($compiler); + } + + protected function compileGetParent(Twig_Compiler $compiler) + { + $compiler + ->write("protected function doGetParent(array \$context)\n", "{\n") + ->indent() + ->write("return ") + ; + + if (null === $this->getNode('parent')) { + $compiler->raw("false"); + } else { + if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { + $compiler->subcompile($this->getNode('parent')); + } else { + $compiler + ->raw("\$this->env->resolveTemplate(") + ->subcompile($this->getNode('parent')) + ->raw(")") + ; + } + } + + $compiler + ->raw(";\n") + ->outdent() + ->write("}\n\n") + ; + } + + protected function compileDisplayBody(Twig_Compiler $compiler) + { + $compiler->write("\$context = array_merge(\$this->env->getGlobals(), \$context);\n\n"); + $compiler->subcompile($this->getNode('body')); + + if (null !== $this->getNode('parent')) { + $compiler->write("\$this->getParent(\$context)->display(\$context, array_merge(\$this->blocks, \$blocks));\n"); + } + } + + protected function compileClassHeader(Twig_Compiler $compiler) + { + $compiler + ->write("write("/* ".str_replace('*/', '* /', $this->getAttribute('filename'))." */\n") + ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'))) + ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass())) + ->write("{\n") + ->indent() + ; + } + + protected function compileConstructor(Twig_Compiler $compiler) + { + $compiler + ->write("public function __construct(Twig_Environment \$env)\n", "{\n") + ->indent() + ->write("parent::__construct(\$env);\n\n") + ; + + $countTraits = count($this->getNode('traits')); + if ($countTraits) { + // traits + foreach ($this->getNode('traits') as $i => $trait) { + $this->compileLoadTemplate($compiler, $trait->getNode('template'), sprintf('$_trait_%s', $i)); + + $compiler + ->addDebugInfo($trait->getNode('template')) + ->write(sprintf("if (!\$_trait_%s->isTraitable()) {\n", $i)) + ->indent() + ->write("throw new Twig_Error_Runtime('Template \"'.") + ->subcompile($trait->getNode('template')) + ->raw(".'\" cannot be used as a trait.');\n") + ->outdent() + ->write("}\n") + ->write(sprintf("\$_trait_%s_blocks = \$_trait_%s->getBlocks();\n\n", $i, $i)) + ; + + foreach ($trait->getNode('targets') as $key => $value) { + $compiler + ->write(sprintf("\$_trait_%s_blocks[", $i)) + ->subcompile($value) + ->raw(sprintf("] = \$_trait_%s_blocks[", $i)) + ->string($key) + ->raw(sprintf("]; unset(\$_trait_%s_blocks[", $i)) + ->string($key) + ->raw("]);\n\n") + ; + } + } + + $compiler + ->write("\$this->blocks = array_merge(\n") + ->indent() + ; + + for ($i = 0; $i < $countTraits; $i++) { + $compiler + ->write(sprintf("\$_trait_%s_blocks,\n", $i)) + ; + } + + $compiler + ->write("array(\n") + ; + } else { + $compiler + ->write("\$this->blocks = array(\n") + ; + } + + // blocks + $compiler + ->indent() + ; + + foreach ($this->getNode('blocks') as $name => $node) { + $compiler + ->write(sprintf("'%s' => array(\$this, 'block_%s'),\n", $name, $name)) + ; + } + + if ($countTraits) { + $compiler + ->outdent() + ->write(")\n") + ; + } + + $compiler + ->outdent() + ->write(");\n") + ->outdent() + ->write("}\n\n"); + ; + } + + protected function compileDisplayHeader(Twig_Compiler $compiler) + { + $compiler + ->write("protected function doDisplay(array \$context, array \$blocks = array())\n", "{\n") + ->indent() + ; + } + + protected function compileDisplayFooter(Twig_Compiler $compiler) + { + $compiler + ->outdent() + ->write("}\n\n") + ; + } + + protected function compileClassFooter(Twig_Compiler $compiler) + { + $compiler + ->outdent() + ->write("}\n") + ; + } + + protected function compileMacros(Twig_Compiler $compiler) + { + $compiler->subcompile($this->getNode('macros')); + } + + protected function compileGetTemplateName(Twig_Compiler $compiler) + { + $compiler + ->write("public function getTemplateName()\n", "{\n") + ->indent() + ->write('return ') + ->repr($this->getAttribute('filename')) + ->raw(";\n") + ->outdent() + ->write("}\n\n") + ; + } + + protected function compileIsTraitable(Twig_Compiler $compiler) + { + // A template can be used as a trait if: + // * it has no parent + // * it has no macros + // * it has no body + // + // Put another way, a template can be used as a trait if it + // only contains blocks and use statements. + $traitable = null === $this->getNode('parent') && 0 === count($this->getNode('macros')); + if ($traitable) { + if (!count($nodes = $this->getNode('body'))) { + $nodes = new Twig_Node(array($this->getNode('body'))); + } + + foreach ($nodes as $node) { + if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) { + continue; + } + + if ($node instanceof Twig_Node_BlockReference) { + continue; + } + + $traitable = false; + break; + } + } + + $compiler + ->write("public function isTraitable()\n", "{\n") + ->indent() + ->write(sprintf("return %s;\n", $traitable ? 'true' : 'false')) + ->outdent() + ->write("}\n") + ; + } + + public function compileLoadTemplate(Twig_Compiler $compiler, $node, $var) + { + if ($node instanceof Twig_Node_Expression_Constant) { + $compiler + ->write(sprintf("%s = \$this->env->loadTemplate(", $var)) + ->subcompile($node) + ->raw(");\n") + ; + } else { + $compiler + ->write(sprintf("%s = ", $var)) + ->subcompile($node) + ->raw(";\n") + ->write(sprintf("if (!%s", $var)) + ->raw(" instanceof Twig_Template) {\n") + ->indent() + ->write(sprintf("%s = \$this->env->loadTemplate(%s);\n", $var, $var)) + ->outdent() + ->write("}\n") + ; + } + } +} diff --git a/inc/lib/Twig/Node/Print.php b/inc/lib/Twig/Node/Print.php new file mode 100644 index 00000000..766725ff --- /dev/null +++ b/inc/lib/Twig/Node/Print.php @@ -0,0 +1,40 @@ + + */ +class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface +{ + public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null) + { + parent::__construct(array('expr' => $expr), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write('echo ') + ->subcompile($this->getNode('expr')) + ->raw(";\n") + ; + } +} diff --git a/inc/lib/Twig/Node/Sandbox.php b/inc/lib/Twig/Node/Sandbox.php new file mode 100644 index 00000000..cbfcb411 --- /dev/null +++ b/inc/lib/Twig/Node/Sandbox.php @@ -0,0 +1,48 @@ + + */ +class Twig_Node_Sandbox extends Twig_Node +{ + public function __construct(Twig_NodeInterface $body, $lineno, $tag = null) + { + parent::__construct(array('body' => $body), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write("\$sandbox = \$this->env->getExtension('sandbox');\n") + ->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n") + ->indent() + ->write("\$sandbox->enableSandbox();\n") + ->outdent() + ->write("}\n") + ->subcompile($this->getNode('body')) + ->write("if (!\$alreadySandboxed) {\n") + ->indent() + ->write("\$sandbox->disableSandbox();\n") + ->outdent() + ->write("}\n") + ; + } +} diff --git a/inc/lib/Twig/Node/SandboxedModule.php b/inc/lib/Twig/Node/SandboxedModule.php new file mode 100644 index 00000000..36d9f198 --- /dev/null +++ b/inc/lib/Twig/Node/SandboxedModule.php @@ -0,0 +1,71 @@ + + */ +class Twig_Node_SandboxedModule extends Twig_Node_Module +{ + protected $usedFilters; + protected $usedTags; + protected $usedFunctions; + + public function __construct(Twig_Node_Module $node, array $usedFilters, array $usedTags, array $usedFunctions) + { + parent::__construct($node->getNode('body'), $node->getNode('parent'), $node->getNode('blocks'), $node->getNode('macros'), $node->getNode('traits'), $node->getAttribute('filename'), $node->getLine(), $node->getNodeTag()); + + $this->usedFilters = $usedFilters; + $this->usedTags = $usedTags; + $this->usedFunctions = $usedFunctions; + } + + protected function compileDisplayBody(Twig_Compiler $compiler) + { + if (null === $this->getNode('parent')) { + $compiler->write("\$this->checkSecurity();\n"); + } + + parent::compileDisplayBody($compiler); + } + + protected function compileDisplayFooter(Twig_Compiler $compiler) + { + parent::compileDisplayFooter($compiler); + + $compiler + ->write("protected function checkSecurity() {\n") + ->indent() + ->write("\$this->env->getExtension('sandbox')->checkSecurity(\n") + ->indent() + ->write(!$this->usedTags ? "array(),\n" : "array('".implode('\', \'', $this->usedTags)."'),\n") + ->write(!$this->usedFilters ? "array(),\n" : "array('".implode('\', \'', $this->usedFilters)."'),\n") + ->write(!$this->usedFunctions ? "array()\n" : "array('".implode('\', \'', $this->usedFunctions)."')\n") + ->outdent() + ->write(");\n") + ; + + if (null !== $this->getNode('parent')) { + $compiler + ->raw("\n") + ->write("\$this->parent->checkSecurity();\n") + ; + } + + $compiler + ->outdent() + ->write("}\n\n") + ; + } +} diff --git a/inc/lib/Twig/Node/SandboxedPrint.php b/inc/lib/Twig/Node/SandboxedPrint.php new file mode 100644 index 00000000..77730d8c --- /dev/null +++ b/inc/lib/Twig/Node/SandboxedPrint.php @@ -0,0 +1,60 @@ + + */ +class Twig_Node_SandboxedPrint extends Twig_Node_Print +{ + public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null) + { + parent::__construct($expr, $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write('echo $this->env->getExtension(\'sandbox\')->ensureToStringAllowed(') + ->subcompile($this->getNode('expr')) + ->raw(");\n") + ; + } + + /** + * Removes node filters. + * + * This is mostly needed when another visitor adds filters (like the escaper one). + * + * @param Twig_Node $node A Node + */ + protected function removeNodeFilter($node) + { + if ($node instanceof Twig_Node_Expression_Filter) { + return $this->removeNodeFilter($node->getNode('node')); + } + + return $node; + } +} diff --git a/inc/lib/Twig/Node/Set.php b/inc/lib/Twig/Node/Set.php new file mode 100644 index 00000000..9913664f --- /dev/null +++ b/inc/lib/Twig/Node/Set.php @@ -0,0 +1,102 @@ + + */ +class Twig_Node_Set extends Twig_Node +{ + public function __construct($capture, Twig_NodeInterface $names, Twig_NodeInterface $values, $lineno, $tag = null) + { + parent::__construct(array('names' => $names, 'values' => $values), array('capture' => $capture, 'safe' => false), $lineno, $tag); + + /* + * Optimizes the node when capture is used for a large block of text. + * + * {% set foo %}foo{% endset %} is compiled to $context['foo'] = new Twig_Markup("foo"); + */ + if ($this->getAttribute('capture')) { + $this->setAttribute('safe', true); + + $values = $this->getNode('values'); + if ($values instanceof Twig_Node_Text) { + $this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getLine())); + $this->setAttribute('capture', false); + } + } + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); + + if (count($this->getNode('names')) > 1) { + $compiler->write('list('); + foreach ($this->getNode('names') as $idx => $node) { + if ($idx) { + $compiler->raw(', '); + } + + $compiler->subcompile($node); + } + $compiler->raw(')'); + } else { + if ($this->getAttribute('capture')) { + $compiler + ->write("ob_start();\n") + ->subcompile($this->getNode('values')) + ; + } + + $compiler->subcompile($this->getNode('names'), false); + + if ($this->getAttribute('capture')) { + $compiler->raw(" = new Twig_Markup(ob_get_clean())"); + } + } + + if (!$this->getAttribute('capture')) { + $compiler->raw(' = '); + + if (count($this->getNode('names')) > 1) { + $compiler->write('array('); + foreach ($this->getNode('values') as $idx => $value) { + if ($idx) { + $compiler->raw(', '); + } + + $compiler->subcompile($value); + } + $compiler->raw(')'); + } else { + if ($this->getAttribute('safe')) { + $compiler + ->raw("new Twig_Markup(") + ->subcompile($this->getNode('values')) + ->raw(")") + ; + } else { + $compiler->subcompile($this->getNode('values')); + } + } + } + + $compiler->raw(";\n"); + } +} diff --git a/inc/lib/Twig/Node/Spaceless.php b/inc/lib/Twig/Node/Spaceless.php new file mode 100644 index 00000000..46013466 --- /dev/null +++ b/inc/lib/Twig/Node/Spaceless.php @@ -0,0 +1,41 @@ + + */ +class Twig_Node_Spaceless extends Twig_Node +{ + public function __construct(Twig_NodeInterface $body, $lineno, $tag = 'spaceless') + { + parent::__construct(array('body' => $body), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write("ob_start();\n") + ->subcompile($this->getNode('body')) + ->write("echo trim(preg_replace('/>\s+<', ob_get_clean()));\n") + ; + } +} diff --git a/inc/lib/Twig/Node/Text.php b/inc/lib/Twig/Node/Text.php new file mode 100644 index 00000000..0c1c0928 --- /dev/null +++ b/inc/lib/Twig/Node/Text.php @@ -0,0 +1,40 @@ + + */ +class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface +{ + public function __construct($data, $lineno) + { + parent::__construct(array(), array('data' => $data), $lineno); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write('echo ') + ->string($this->getAttribute('data')) + ->raw(";\n") + ; + } +} -- cgit v1.3