Start working
Modified some paths to be more generic and not require rewrite. Some instances of phase names have been changed, others are still in process.
This commit is contained in:
39
Twig/Node/AutoEscape.php
Normal file
39
Twig/Node/AutoEscape.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents an autoescape node.
|
||||
*
|
||||
* The value is the escaping strategy (can be html, js, ...)
|
||||
*
|
||||
* The true value is equivalent to html.
|
||||
*
|
||||
* If autoescaping is disabled, then the value is false.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->subcompile($this->getNode('body'));
|
||||
}
|
||||
}
|
44
Twig/Node/Block.php
Normal file
44
Twig/Node/Block.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a block node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $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")
|
||||
;
|
||||
}
|
||||
}
|
37
Twig/Node/BlockReference.php
Normal file
37
Twig/Node/BlockReference.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a block call node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $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')))
|
||||
;
|
||||
}
|
||||
}
|
19
Twig/Node/Body.php
Normal file
19
Twig/Node/Body.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a body node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Body extends Twig_Node
|
||||
{
|
||||
}
|
78
Twig/Node/CheckSecurity.php
Normal file
78
Twig/Node/CheckSecurity.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2015 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_CheckSecurity extends Twig_Node
|
||||
{
|
||||
protected $usedFilters;
|
||||
protected $usedTags;
|
||||
protected $usedFunctions;
|
||||
|
||||
public function __construct(array $usedFilters, array $usedTags, array $usedFunctions)
|
||||
{
|
||||
$this->usedFilters = $usedFilters;
|
||||
$this->usedTags = $usedTags;
|
||||
$this->usedFunctions = $usedFunctions;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$tags = $filters = $functions = array();
|
||||
foreach (array('tags', 'filters', 'functions') as $type) {
|
||||
foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
|
||||
if ($node instanceof Twig_Node) {
|
||||
${$type}[$name] = $node->getLine();
|
||||
} else {
|
||||
${$type}[$node] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write('$tags = ')->repr(array_filter($tags))->raw(";\n")
|
||||
->write('$filters = ')->repr(array_filter($filters))->raw(";\n")
|
||||
->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
|
||||
->write("try {\n")
|
||||
->indent()
|
||||
->write("\$this->env->getExtension('sandbox')->checkSecurity(\n")
|
||||
->indent()
|
||||
->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n")
|
||||
->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n")
|
||||
->write(!$functions ? "array()\n" : "array('".implode("', '", array_keys($functions))."')\n")
|
||||
->outdent()
|
||||
->write(");\n")
|
||||
->outdent()
|
||||
->write("} catch (Twig_Sandbox_SecurityError \$e) {\n")
|
||||
->indent()
|
||||
->write("\$e->setTemplateFile(\$this->getTemplateName());\n\n")
|
||||
->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
|
||||
->indent()
|
||||
->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
|
||||
->outdent()
|
||||
->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFilterError && isset(\$filters[\$e->getFilterName()])) {\n")
|
||||
->indent()
|
||||
->write("\$e->setTemplateLine(\$filters[\$e->getFilterName()]);\n")
|
||||
->outdent()
|
||||
->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFunctionError && isset(\$functions[\$e->getFunctionName()])) {\n")
|
||||
->indent()
|
||||
->write("\$e->setTemplateLine(\$functions[\$e->getFunctionName()]);\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
->write("throw \$e;\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
}
|
38
Twig/Node/Do.php
Normal file
38
Twig/Node/Do.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a do node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Do extends Twig_Node
|
||||
{
|
||||
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 $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(";\n")
|
||||
;
|
||||
}
|
||||
}
|
42
Twig/Node/Embed.php
Normal file
42
Twig/Node/Embed.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2012 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents an embed node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Embed extends Twig_Node_Include
|
||||
{
|
||||
// we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
|
||||
public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
|
||||
|
||||
$this->setAttribute('filename', $filename);
|
||||
$this->setAttribute('index', $index);
|
||||
}
|
||||
|
||||
protected function addGetTemplate(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write('$this->loadTemplate(')
|
||||
->string($this->getAttribute('filename'))
|
||||
->raw(', ')
|
||||
->repr($compiler->getFilename())
|
||||
->raw(', ')
|
||||
->repr($this->getLine())
|
||||
->raw(', ')
|
||||
->string($this->getAttribute('index'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
}
|
20
Twig/Node/Expression.php
Normal file
20
Twig/Node/Expression.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract class for all nodes that represents an expression.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class Twig_Node_Expression extends Twig_Node
|
||||
{
|
||||
}
|
86
Twig/Node/Expression/Array.php
Normal file
86
Twig/Node/Expression/Array.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Array extends Twig_Node_Expression
|
||||
{
|
||||
protected $index;
|
||||
|
||||
public function __construct(array $elements, $lineno)
|
||||
{
|
||||
parent::__construct($elements, array(), $lineno);
|
||||
|
||||
$this->index = -1;
|
||||
foreach ($this->getKeyValuePairs() as $pair) {
|
||||
if ($pair['key'] instanceof Twig_Node_Expression_Constant && ctype_digit((string) $pair['key']->getAttribute('value')) && $pair['key']->getAttribute('value') > $this->index) {
|
||||
$this->index = $pair['key']->getAttribute('value');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getKeyValuePairs()
|
||||
{
|
||||
$pairs = array();
|
||||
|
||||
foreach (array_chunk($this->nodes, 2) as $pair) {
|
||||
$pairs[] = array(
|
||||
'key' => $pair[0],
|
||||
'value' => $pair[1],
|
||||
);
|
||||
}
|
||||
|
||||
return $pairs;
|
||||
}
|
||||
|
||||
public function hasElement(Twig_Node_Expression $key)
|
||||
{
|
||||
foreach ($this->getKeyValuePairs() as $pair) {
|
||||
// we compare the string representation of the keys
|
||||
// to avoid comparing the line numbers which are not relevant here.
|
||||
if ((string) $key == (string) $pair['key']) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null)
|
||||
{
|
||||
if (null === $key) {
|
||||
$key = new Twig_Node_Expression_Constant(++$this->index, $value->getLine());
|
||||
}
|
||||
|
||||
array_push($this->nodes, $key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('array(');
|
||||
$first = true;
|
||||
foreach ($this->getKeyValuePairs() as $pair) {
|
||||
if (!$first) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
$first = false;
|
||||
|
||||
$compiler
|
||||
->subcompile($pair['key'])
|
||||
->raw(' => ')
|
||||
->subcompile($pair['value'])
|
||||
;
|
||||
}
|
||||
$compiler->raw(')');
|
||||
}
|
||||
}
|
28
Twig/Node/Expression/AssignName.php
Normal file
28
Twig/Node/Expression/AssignName.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
|
||||
{
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('$context[')
|
||||
->string($this->getAttribute('name'))
|
||||
->raw(']')
|
||||
;
|
||||
}
|
||||
}
|
40
Twig/Node/Expression/Binary.php
Normal file
40
Twig/Node/Expression/Binary.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
|
||||
{
|
||||
parent::__construct(array('left' => $left, 'right' => $right), array(), $lineno);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $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);
|
||||
}
|
18
Twig/Node/Expression/Binary/Add.php
Normal file
18
Twig/Node/Expression/Binary/Add.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Add extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('+');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Binary/And.php
Normal file
18
Twig/Node/Expression/Binary/And.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_And extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('&&');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Binary/BitwiseAnd.php
Normal file
18
Twig/Node/Expression/Binary/BitwiseAnd.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_BitwiseAnd extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('&');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Binary/BitwiseOr.php
Normal file
18
Twig/Node/Expression/Binary/BitwiseOr.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_BitwiseOr extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('|');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Binary/BitwiseXor.php
Normal file
18
Twig/Node/Expression/Binary/BitwiseXor.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_BitwiseXor extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('^');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Binary/Concat.php
Normal file
18
Twig/Node/Expression/Binary/Concat.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Concat extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('.');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Binary/Div.php
Normal file
18
Twig/Node/Expression/Binary/Div.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Div extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('/');
|
||||
}
|
||||
}
|
30
Twig/Node/Expression/Binary/EndsWith.php
Normal file
30
Twig/Node/Expression/Binary/EndsWith.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2013 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$left = $compiler->getVarName();
|
||||
$right = $compiler->getVarName();
|
||||
$compiler
|
||||
->raw(sprintf('(is_string($%s = ', $left))
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(sprintf(') && is_string($%s = ', $right))
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(sprintf(') && (\'\' === $%2$s || $%2$s === substr($%1$s, -strlen($%2$s))))', $left, $right))
|
||||
;
|
||||
}
|
||||
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('');
|
||||
}
|
||||
}
|
17
Twig/Node/Expression/Binary/Equal.php
Normal file
17
Twig/Node/Expression/Binary/Equal.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Equal extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('==');
|
||||
}
|
||||
}
|
29
Twig/Node/Expression/Binary/FloorDiv.php
Normal file
29
Twig/Node/Expression/Binary/FloorDiv.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
|
||||
{
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('intval(floor(');
|
||||
parent::compile($compiler);
|
||||
$compiler->raw('))');
|
||||
}
|
||||
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('/');
|
||||
}
|
||||
}
|
17
Twig/Node/Expression/Binary/Greater.php
Normal file
17
Twig/Node/Expression/Binary/Greater.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Greater extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('>');
|
||||
}
|
||||
}
|
17
Twig/Node/Expression/Binary/GreaterEqual.php
Normal file
17
Twig/Node/Expression/Binary/GreaterEqual.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_GreaterEqual extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('>=');
|
||||
}
|
||||
}
|
33
Twig/Node/Expression/Binary/In.php
Normal file
33
Twig/Node/Expression/Binary/In.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
|
||||
{
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('twig_in_filter(')
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('in');
|
||||
}
|
||||
}
|
17
Twig/Node/Expression/Binary/Less.php
Normal file
17
Twig/Node/Expression/Binary/Less.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Less extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('<');
|
||||
}
|
||||
}
|
17
Twig/Node/Expression/Binary/LessEqual.php
Normal file
17
Twig/Node/Expression/Binary/LessEqual.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_LessEqual extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('<=');
|
||||
}
|
||||
}
|
28
Twig/Node/Expression/Binary/Matches.php
Normal file
28
Twig/Node/Expression/Binary/Matches.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2013 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Matches extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('preg_match(')
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Binary/Mod.php
Normal file
18
Twig/Node/Expression/Binary/Mod.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Mod extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('%');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Binary/Mul.php
Normal file
18
Twig/Node/Expression/Binary/Mul.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Mul extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('*');
|
||||
}
|
||||
}
|
17
Twig/Node/Expression/Binary/NotEqual.php
Normal file
17
Twig/Node/Expression/Binary/NotEqual.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_NotEqual extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('!=');
|
||||
}
|
||||
}
|
33
Twig/Node/Expression/Binary/NotIn.php
Normal file
33
Twig/Node/Expression/Binary/NotIn.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
|
||||
{
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->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');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Binary/Or.php
Normal file
18
Twig/Node/Expression/Binary/Or.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Or extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('||');
|
||||
}
|
||||
}
|
33
Twig/Node/Expression/Binary/Power.php
Normal file
33
Twig/Node/Expression/Binary/Power.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
|
||||
{
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('pow(')
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('**');
|
||||
}
|
||||
}
|
33
Twig/Node/Expression/Binary/Range.php
Normal file
33
Twig/Node/Expression/Binary/Range.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
|
||||
{
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('range(')
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('..');
|
||||
}
|
||||
}
|
30
Twig/Node/Expression/Binary/StartsWith.php
Normal file
30
Twig/Node/Expression/Binary/StartsWith.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2013 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_StartsWith extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$left = $compiler->getVarName();
|
||||
$right = $compiler->getVarName();
|
||||
$compiler
|
||||
->raw(sprintf('(is_string($%s = ', $left))
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(sprintf(') && is_string($%s = ', $right))
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(sprintf(') && (\'\' === $%2$s || 0 === strpos($%1$s, $%2$s)))', $left, $right))
|
||||
;
|
||||
}
|
||||
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Binary/Sub.php
Normal file
18
Twig/Node/Expression/Binary/Sub.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Sub extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('-');
|
||||
}
|
||||
}
|
51
Twig/Node/Expression/BlockReference.php
Normal file
51
Twig/Node/Expression/BlockReference.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a block call node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $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)')
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
247
Twig/Node/Expression/Call.php
Normal file
247
Twig/Node/Expression/Call.php
Normal file
@ -0,0 +1,247 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2012 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
||||
{
|
||||
protected function compileCallable(Twig_Compiler $compiler)
|
||||
{
|
||||
$closingParenthesis = false;
|
||||
if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
|
||||
if (is_string($callable)) {
|
||||
$compiler->raw($callable);
|
||||
} elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) {
|
||||
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', $callable[0]->getName(), $callable[1]));
|
||||
} else {
|
||||
$type = ucfirst($this->getAttribute('type'));
|
||||
$compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name')));
|
||||
$closingParenthesis = true;
|
||||
}
|
||||
} else {
|
||||
$compiler->raw($this->getAttribute('thing')->compile());
|
||||
}
|
||||
|
||||
$this->compileArguments($compiler);
|
||||
|
||||
if ($closingParenthesis) {
|
||||
$compiler->raw(')');
|
||||
}
|
||||
}
|
||||
|
||||
protected function compileArguments(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('(');
|
||||
|
||||
$first = true;
|
||||
|
||||
if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
|
||||
$compiler->raw('$this->env');
|
||||
$first = false;
|
||||
}
|
||||
|
||||
if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
|
||||
if (!$first) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
$compiler->raw('$context');
|
||||
$first = false;
|
||||
}
|
||||
|
||||
if ($this->hasAttribute('arguments')) {
|
||||
foreach ($this->getAttribute('arguments') as $argument) {
|
||||
if (!$first) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
$compiler->string($argument);
|
||||
$first = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->hasNode('node')) {
|
||||
if (!$first) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
$compiler->subcompile($this->getNode('node'));
|
||||
$first = false;
|
||||
}
|
||||
|
||||
if ($this->hasNode('arguments') && null !== $this->getNode('arguments')) {
|
||||
$callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
|
||||
|
||||
$arguments = $this->getArguments($callable, $this->getNode('arguments'));
|
||||
|
||||
foreach ($arguments as $node) {
|
||||
if (!$first) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
$compiler->subcompile($node);
|
||||
$first = false;
|
||||
}
|
||||
}
|
||||
|
||||
$compiler->raw(')');
|
||||
}
|
||||
|
||||
protected function getArguments($callable, $arguments)
|
||||
{
|
||||
$callType = $this->getAttribute('type');
|
||||
$callName = $this->getAttribute('name');
|
||||
|
||||
$parameters = array();
|
||||
$named = false;
|
||||
foreach ($arguments as $name => $node) {
|
||||
if (!is_int($name)) {
|
||||
$named = true;
|
||||
$name = $this->normalizeName($name);
|
||||
} elseif ($named) {
|
||||
throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName));
|
||||
}
|
||||
|
||||
$parameters[$name] = $node;
|
||||
}
|
||||
|
||||
$isVariadic = $this->hasAttribute('is_variadic') && $this->getAttribute('is_variadic');
|
||||
if (!$named && !$isVariadic) {
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
if (!$callable) {
|
||||
if ($named) {
|
||||
$message = sprintf('Named arguments are not supported for %s "%s".', $callType, $callName);
|
||||
} else {
|
||||
$message = sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
|
||||
}
|
||||
|
||||
throw new LogicException($message);
|
||||
}
|
||||
|
||||
// manage named arguments
|
||||
if (is_array($callable)) {
|
||||
$r = new ReflectionMethod($callable[0], $callable[1]);
|
||||
} elseif (is_object($callable) && !$callable instanceof Closure) {
|
||||
$r = new ReflectionObject($callable);
|
||||
$r = $r->getMethod('__invoke');
|
||||
} elseif (is_string($callable) && false !== strpos($callable, '::')) {
|
||||
$r = new ReflectionMethod($callable);
|
||||
} else {
|
||||
$r = new ReflectionFunction($callable);
|
||||
}
|
||||
|
||||
$definition = $r->getParameters();
|
||||
if ($this->hasNode('node')) {
|
||||
array_shift($definition);
|
||||
}
|
||||
if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
|
||||
array_shift($definition);
|
||||
}
|
||||
if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
|
||||
array_shift($definition);
|
||||
}
|
||||
if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
|
||||
foreach ($this->getAttribute('arguments') as $argument) {
|
||||
array_shift($definition);
|
||||
}
|
||||
}
|
||||
if ($isVariadic) {
|
||||
$argument = end($definition);
|
||||
if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && array() === $argument->getDefaultValue()) {
|
||||
array_pop($definition);
|
||||
} else {
|
||||
$callableName = $r->name;
|
||||
if ($r->getDeclaringClass()) {
|
||||
$callableName = $r->getDeclaringClass()->name.'::'.$callableName;
|
||||
}
|
||||
|
||||
throw new LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = array()".', $callableName, $callType, $callName));
|
||||
}
|
||||
}
|
||||
|
||||
$arguments = array();
|
||||
$names = array();
|
||||
$missingArguments = array();
|
||||
$optionalArguments = array();
|
||||
$pos = 0;
|
||||
foreach ($definition as $param) {
|
||||
$names[] = $name = $this->normalizeName($param->name);
|
||||
|
||||
if (array_key_exists($name, $parameters)) {
|
||||
if (array_key_exists($pos, $parameters)) {
|
||||
throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName));
|
||||
}
|
||||
|
||||
if (!empty($missingArguments)) {
|
||||
throw new Twig_Error_Syntax(sprintf(
|
||||
'Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".',
|
||||
$name, $callType, $callName, implode(', ', $names), count($missingArguments) > 1 ? 's' : '', implode('", "', $missingArguments))
|
||||
);
|
||||
}
|
||||
|
||||
$arguments = array_merge($arguments, $optionalArguments);
|
||||
$arguments[] = $parameters[$name];
|
||||
unset($parameters[$name]);
|
||||
$optionalArguments = array();
|
||||
} elseif (array_key_exists($pos, $parameters)) {
|
||||
$arguments = array_merge($arguments, $optionalArguments);
|
||||
$arguments[] = $parameters[$pos];
|
||||
unset($parameters[$pos]);
|
||||
$optionalArguments = array();
|
||||
++$pos;
|
||||
} elseif ($param->isDefaultValueAvailable()) {
|
||||
$optionalArguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1);
|
||||
} elseif ($param->isOptional()) {
|
||||
if (empty($parameters)) {
|
||||
break;
|
||||
} else {
|
||||
$missingArguments[] = $name;
|
||||
}
|
||||
} else {
|
||||
throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName));
|
||||
}
|
||||
}
|
||||
|
||||
if ($isVariadic) {
|
||||
$arbitraryArguments = new Twig_Node_Expression_Array(array(), -1);
|
||||
foreach ($parameters as $key => $value) {
|
||||
if (is_int($key)) {
|
||||
$arbitraryArguments->addElement($value);
|
||||
} else {
|
||||
$arbitraryArguments->addElement($value, new Twig_Node_Expression_Constant($key, -1));
|
||||
}
|
||||
unset($parameters[$key]);
|
||||
}
|
||||
|
||||
if ($arbitraryArguments->count()) {
|
||||
$arguments = array_merge($arguments, $optionalArguments);
|
||||
$arguments[] = $arbitraryArguments;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($parameters)) {
|
||||
$unknownParameter = null;
|
||||
foreach ($parameters as $parameter) {
|
||||
if ($parameter instanceof Twig_Node) {
|
||||
$unknownParameter = $parameter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Twig_Error_Syntax(sprintf(
|
||||
'Unknown argument%s "%s" for %s "%s(%s)".',
|
||||
count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)
|
||||
), $unknownParameter ? $unknownParameter->getLine() : -1);
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
protected function normalizeName($name)
|
||||
{
|
||||
return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $name));
|
||||
}
|
||||
}
|
31
Twig/Node/Expression/Conditional.php
Normal file
31
Twig/Node/Expression/Conditional.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Conditional extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct(Twig_Node_Expression $expr1, Twig_Node_Expression $expr2, Twig_Node_Expression $expr3, $lineno)
|
||||
{
|
||||
parent::__construct(array('expr1' => $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('))')
|
||||
;
|
||||
}
|
||||
}
|
23
Twig/Node/Expression/Constant.php
Normal file
23
Twig/Node/Expression/Constant.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Constant extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct($value, $lineno)
|
||||
{
|
||||
parent::__construct(array(), array('value' => $value), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->repr($this->getAttribute('value'));
|
||||
}
|
||||
}
|
33
Twig/Node/Expression/ExtensionReference.php
Normal file
33
Twig/Node/Expression/ExtensionReference.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents an extension call node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name')));
|
||||
}
|
||||
}
|
39
Twig/Node/Expression/Filter.php
Normal file
39
Twig/Node/Expression/Filter.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Filter extends Twig_Node_Expression_Call
|
||||
{
|
||||
public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(array('node' => $node, 'filter' => $filterName, 'arguments' => $arguments), array(), $lineno, $tag);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$name = $this->getNode('filter')->getAttribute('value');
|
||||
$filter = $compiler->getEnvironment()->getFilter($name);
|
||||
|
||||
$this->setAttribute('name', $name);
|
||||
$this->setAttribute('type', 'filter');
|
||||
$this->setAttribute('thing', $filter);
|
||||
$this->setAttribute('needs_environment', $filter->needsEnvironment());
|
||||
$this->setAttribute('needs_context', $filter->needsContext());
|
||||
$this->setAttribute('arguments', $filter->getArguments());
|
||||
if ($filter instanceof Twig_FilterCallableInterface || $filter instanceof Twig_SimpleFilter) {
|
||||
$this->setAttribute('callable', $filter->getCallable());
|
||||
}
|
||||
if ($filter instanceof Twig_SimpleFilter) {
|
||||
$this->setAttribute('is_variadic', $filter->isVariadic());
|
||||
}
|
||||
|
||||
$this->compileCallable($compiler);
|
||||
}
|
||||
}
|
43
Twig/Node/Expression/Filter/Default.php
Normal file
43
Twig/Node/Expression/Filter/Default.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the value or the default value when it is undefined or empty.
|
||||
*
|
||||
* <pre>
|
||||
* {{ var.foo|default('foo item on var is not defined') }}
|
||||
* </pre>
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter
|
||||
{
|
||||
public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
|
||||
{
|
||||
$default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getLine()), $arguments, $node->getLine());
|
||||
|
||||
if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) {
|
||||
$test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getLine());
|
||||
$false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getLine());
|
||||
|
||||
$node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getLine());
|
||||
} else {
|
||||
$node = $default;
|
||||
}
|
||||
|
||||
parent::__construct($node, $filterName, $arguments, $lineno, $tag);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->subcompile($this->getNode('node'));
|
||||
}
|
||||
}
|
38
Twig/Node/Expression/Function.php
Normal file
38
Twig/Node/Expression/Function.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Function extends Twig_Node_Expression_Call
|
||||
{
|
||||
public function __construct($name, Twig_NodeInterface $arguments, $lineno)
|
||||
{
|
||||
parent::__construct(array('arguments' => $arguments), array('name' => $name), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$name = $this->getAttribute('name');
|
||||
$function = $compiler->getEnvironment()->getFunction($name);
|
||||
|
||||
$this->setAttribute('name', $name);
|
||||
$this->setAttribute('type', 'function');
|
||||
$this->setAttribute('thing', $function);
|
||||
$this->setAttribute('needs_environment', $function->needsEnvironment());
|
||||
$this->setAttribute('needs_context', $function->needsContext());
|
||||
$this->setAttribute('arguments', $function->getArguments());
|
||||
if ($function instanceof Twig_FunctionCallableInterface || $function instanceof Twig_SimpleFunction) {
|
||||
$this->setAttribute('callable', $function->getCallable());
|
||||
}
|
||||
if ($function instanceof Twig_SimpleFunction) {
|
||||
$this->setAttribute('is_variadic', $function->isVariadic());
|
||||
}
|
||||
|
||||
$this->compileCallable($compiler);
|
||||
}
|
||||
}
|
63
Twig/Node/Expression/GetAttr.php
Normal file
63
Twig/Node/Expression/GetAttr.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression $arguments = null, $type, $lineno)
|
||||
{
|
||||
parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
if (function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) {
|
||||
$compiler->raw('twig_template_get_attributes($this, ');
|
||||
} else {
|
||||
$compiler->raw('$this->getAttribute(');
|
||||
}
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check')) {
|
||||
$this->getNode('node')->setAttribute('ignore_strict_check', true);
|
||||
}
|
||||
|
||||
$compiler->subcompile($this->getNode('node'));
|
||||
|
||||
$compiler->raw(', ')->subcompile($this->getNode('attribute'));
|
||||
|
||||
// only generate optional arguments when needed (to make generated code more readable)
|
||||
$needFourth = $this->getAttribute('ignore_strict_check');
|
||||
$needThird = $needFourth || $this->getAttribute('is_defined_test');
|
||||
$needSecond = $needThird || Twig_Template::ANY_CALL !== $this->getAttribute('type');
|
||||
$needFirst = $needSecond || null !== $this->getNode('arguments');
|
||||
|
||||
if ($needFirst) {
|
||||
if (null !== $this->getNode('arguments')) {
|
||||
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
|
||||
} else {
|
||||
$compiler->raw(', array()');
|
||||
}
|
||||
}
|
||||
|
||||
if ($needSecond) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('type'));
|
||||
}
|
||||
|
||||
if ($needThird) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('is_defined_test'));
|
||||
}
|
||||
|
||||
if ($needFourth) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('ignore_strict_check'));
|
||||
}
|
||||
|
||||
$compiler->raw(')');
|
||||
}
|
||||
}
|
41
Twig/Node/Expression/MethodCall.php
Normal file
41
Twig/Node/Expression/MethodCall.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2012 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_MethodCall extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct(Twig_Node_Expression $node, $method, Twig_Node_Expression_Array $arguments, $lineno)
|
||||
{
|
||||
parent::__construct(array('node' => $node, 'arguments' => $arguments), array('method' => $method, 'safe' => false), $lineno);
|
||||
|
||||
if ($node instanceof Twig_Node_Expression_Name) {
|
||||
$node->setAttribute('always_defined', true);
|
||||
}
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw('->')
|
||||
->raw($this->getAttribute('method'))
|
||||
->raw('(')
|
||||
;
|
||||
$first = true;
|
||||
foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) {
|
||||
if (!$first) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
$first = false;
|
||||
|
||||
$compiler->subcompile($pair['value']);
|
||||
}
|
||||
$compiler->raw(')');
|
||||
}
|
||||
}
|
98
Twig/Node/Expression/Name.php
Normal file
98
Twig/Node/Expression/Name.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Name extends Twig_Node_Expression
|
||||
{
|
||||
protected $specialVars = array(
|
||||
'_self' => '$this',
|
||||
'_context' => '$context',
|
||||
'_charset' => '$this->env->getCharset()',
|
||||
);
|
||||
|
||||
public function __construct($name, $lineno)
|
||||
{
|
||||
parent::__construct(array(), array('name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false, 'always_defined' => false), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$name = $this->getAttribute('name');
|
||||
|
||||
$compiler->addDebugInfo($this);
|
||||
|
||||
if ($this->getAttribute('is_defined_test')) {
|
||||
if ($this->isSpecial()) {
|
||||
if ('_self' === $name) {
|
||||
@trigger_error(sprintf('Global variable "_self" is deprecated in %s at line %d', '?', $this->getLine()), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$compiler->repr(true);
|
||||
} else {
|
||||
$compiler->raw('array_key_exists(')->repr($name)->raw(', $context)');
|
||||
}
|
||||
} elseif ($this->isSpecial()) {
|
||||
if ('_self' === $name) {
|
||||
@trigger_error(sprintf('Global variable "_self" is deprecated in %s at line %d', '?', $this->getLine()), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$compiler->raw($this->specialVars[$name]);
|
||||
} elseif ($this->getAttribute('always_defined')) {
|
||||
$compiler
|
||||
->raw('$context[')
|
||||
->string($name)
|
||||
->raw(']')
|
||||
;
|
||||
} else {
|
||||
// remove the non-PHP 5.4 version when PHP 5.3 support is dropped
|
||||
// as the non-optimized version is just a workaround for slow ternary operator
|
||||
// when the context has a lot of variables
|
||||
if (PHP_VERSION_ID >= 50400) {
|
||||
// PHP 5.4 ternary operator performance was optimized
|
||||
$compiler
|
||||
->raw('(isset($context[')
|
||||
->string($name)
|
||||
->raw(']) ? $context[')
|
||||
->string($name)
|
||||
->raw('] : ')
|
||||
;
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
|
||||
$compiler->raw('null)');
|
||||
} else {
|
||||
$compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
|
||||
}
|
||||
} else {
|
||||
$compiler
|
||||
->raw('$this->getContext($context, ')
|
||||
->string($name)
|
||||
;
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check')) {
|
||||
$compiler->raw(', true');
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function isSpecial()
|
||||
{
|
||||
return isset($this->specialVars[$this->getAttribute('name')]);
|
||||
}
|
||||
|
||||
public function isSimple()
|
||||
{
|
||||
return !$this->isSpecial() && !$this->getAttribute('is_defined_test');
|
||||
}
|
||||
}
|
47
Twig/Node/Expression/Parent.php
Normal file
47
Twig/Node/Expression/Parent.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a parent node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Expression_Parent extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct($name, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(array(), array('output' => false, 'name' => $name), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
if ($this->getAttribute('output')) {
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('$this->displayParentBlock(')
|
||||
->string($this->getAttribute('name'))
|
||||
->raw(", \$context, \$blocks);\n")
|
||||
;
|
||||
} else {
|
||||
$compiler
|
||||
->raw('$this->renderParentBlock(')
|
||||
->string($this->getAttribute('name'))
|
||||
->raw(', $context, $blocks)')
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
26
Twig/Node/Expression/TempName.php
Normal file
26
Twig/Node/Expression/TempName.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_TempName extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct($name, $lineno)
|
||||
{
|
||||
parent::__construct(array(), array('name' => $name), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('$_')
|
||||
->raw($this->getAttribute('name'))
|
||||
->raw('_')
|
||||
;
|
||||
}
|
||||
}
|
35
Twig/Node/Expression/Test.php
Normal file
35
Twig/Node/Expression/Test.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Test extends Twig_Node_Expression_Call
|
||||
{
|
||||
public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
|
||||
{
|
||||
parent::__construct(array('node' => $node, 'arguments' => $arguments), array('name' => $name), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$name = $this->getAttribute('name');
|
||||
$test = $compiler->getEnvironment()->getTest($name);
|
||||
|
||||
$this->setAttribute('name', $name);
|
||||
$this->setAttribute('type', 'test');
|
||||
$this->setAttribute('thing', $test);
|
||||
if ($test instanceof Twig_TestCallableInterface || $test instanceof Twig_SimpleTest) {
|
||||
$this->setAttribute('callable', $test->getCallable());
|
||||
}
|
||||
if ($test instanceof Twig_SimpleTest) {
|
||||
$this->setAttribute('is_variadic', $test->isVariadic());
|
||||
}
|
||||
|
||||
$this->compileCallable($compiler);
|
||||
}
|
||||
}
|
46
Twig/Node/Expression/Test/Constant.php
Normal file
46
Twig/Node/Expression/Test/Constant.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if a variable is the exact same value as a constant.
|
||||
*
|
||||
* <pre>
|
||||
* {% if post.status is constant('Post::PUBLISHED') %}
|
||||
* the status attribute is exactly the same as Post::PUBLISHED
|
||||
* {% endif %}
|
||||
* </pre>
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Expression_Test_Constant extends Twig_Node_Expression_Test
|
||||
{
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('(')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(' === constant(')
|
||||
;
|
||||
|
||||
if ($this->getNode('arguments')->hasNode(1)) {
|
||||
$compiler
|
||||
->raw('get_class(')
|
||||
->subcompile($this->getNode('arguments')->getNode(1))
|
||||
->raw(')."::".')
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->subcompile($this->getNode('arguments')->getNode(0))
|
||||
->raw('))')
|
||||
;
|
||||
}
|
||||
}
|
54
Twig/Node/Expression/Test/Defined.php
Normal file
54
Twig/Node/Expression/Test/Defined.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if a variable is defined in the current context.
|
||||
*
|
||||
* <pre>
|
||||
* {# defined works with variable names and variable attributes #}
|
||||
* {% if foo is defined %}
|
||||
* {# ... #}
|
||||
* {% endif %}
|
||||
* </pre>
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test
|
||||
{
|
||||
public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
|
||||
{
|
||||
parent::__construct($node, $name, $arguments, $lineno);
|
||||
|
||||
if ($node instanceof Twig_Node_Expression_Name) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
} elseif ($node instanceof Twig_Node_Expression_GetAttr) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
|
||||
$this->changeIgnoreStrictCheck($node);
|
||||
} else {
|
||||
throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine());
|
||||
}
|
||||
}
|
||||
|
||||
protected function changeIgnoreStrictCheck(Twig_Node_Expression_GetAttr $node)
|
||||
{
|
||||
$node->setAttribute('ignore_strict_check', true);
|
||||
|
||||
if ($node->getNode('node') instanceof Twig_Node_Expression_GetAttr) {
|
||||
$this->changeIgnoreStrictCheck($node->getNode('node'));
|
||||
}
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->subcompile($this->getNode('node'));
|
||||
}
|
||||
}
|
33
Twig/Node/Expression/Test/Divisibleby.php
Normal file
33
Twig/Node/Expression/Test/Divisibleby.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if a variable is divisible by a number.
|
||||
*
|
||||
* <pre>
|
||||
* {% if loop.index is divisible by(3) %}
|
||||
* </pre>
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Expression_Test_Divisibleby extends Twig_Node_Expression_Test
|
||||
{
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('(0 == ')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(' % ')
|
||||
->subcompile($this->getNode('arguments')->getNode(0))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
}
|
32
Twig/Node/Expression/Test/Even.php
Normal file
32
Twig/Node/Expression/Test/Even.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if a number is even.
|
||||
*
|
||||
* <pre>
|
||||
* {{ var is even }}
|
||||
* </pre>
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Expression_Test_Even extends Twig_Node_Expression_Test
|
||||
{
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('(')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(' % 2 == 0')
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
}
|
31
Twig/Node/Expression/Test/Null.php
Normal file
31
Twig/Node/Expression/Test/Null.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks that a variable is null.
|
||||
*
|
||||
* <pre>
|
||||
* {{ var is none }}
|
||||
* </pre>
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Expression_Test_Null extends Twig_Node_Expression_Test
|
||||
{
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('(null === ')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
}
|
32
Twig/Node/Expression/Test/Odd.php
Normal file
32
Twig/Node/Expression/Test/Odd.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if a number is odd.
|
||||
*
|
||||
* <pre>
|
||||
* {{ var is odd }}
|
||||
* </pre>
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test
|
||||
{
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('(')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(' % 2 == 1')
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
}
|
29
Twig/Node/Expression/Test/Sameas.php
Normal file
29
Twig/Node/Expression/Test/Sameas.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if a variable is the same as another one (=== in PHP).
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Expression_Test_Sameas extends Twig_Node_Expression_Test
|
||||
{
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('(')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(' === ')
|
||||
->subcompile($this->getNode('arguments')->getNode(0))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
}
|
27
Twig/Node/Expression/Unary.php
Normal file
27
Twig/Node/Expression/Unary.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
abstract class Twig_Node_Expression_Unary extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct(Twig_NodeInterface $node, $lineno)
|
||||
{
|
||||
parent::__construct(array('node' => $node), array(), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw(' ');
|
||||
$this->operator($compiler);
|
||||
$compiler->subcompile($this->getNode('node'));
|
||||
}
|
||||
|
||||
abstract public function operator(Twig_Compiler $compiler);
|
||||
}
|
18
Twig/Node/Expression/Unary/Neg.php
Normal file
18
Twig/Node/Expression/Unary/Neg.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Unary_Neg extends Twig_Node_Expression_Unary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('-');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Unary/Not.php
Normal file
18
Twig/Node/Expression/Unary/Not.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Unary_Not extends Twig_Node_Expression_Unary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('!');
|
||||
}
|
||||
}
|
18
Twig/Node/Expression/Unary/Pos.php
Normal file
18
Twig/Node/Expression/Unary/Pos.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Unary_Pos extends Twig_Node_Expression_Unary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('+');
|
||||
}
|
||||
}
|
36
Twig/Node/Flush.php
Normal file
36
Twig/Node/Flush.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a flush node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Flush extends Twig_Node
|
||||
{
|
||||
public function __construct($lineno, $tag)
|
||||
{
|
||||
parent::__construct(array(), array(), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write("flush();\n")
|
||||
;
|
||||
}
|
||||
}
|
111
Twig/Node/For.php
Normal file
111
Twig/Node/For.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a for node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_For extends Twig_Node
|
||||
{
|
||||
protected $loop;
|
||||
|
||||
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)
|
||||
{
|
||||
$body = new Twig_Node(array($body, $this->loop = new Twig_Node_ForLoop($lineno, $tag)));
|
||||
|
||||
if (null !== $ifexpr) {
|
||||
$body = new Twig_Node_If(new Twig_Node(array($ifexpr, $body)), null, $lineno, $tag);
|
||||
}
|
||||
|
||||
parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else), array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write("\$context['_parent'] = \$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 (!$this->getAttribute('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")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
$this->loop->setAttribute('else', null !== $this->getNode('else'));
|
||||
$this->loop->setAttribute('with_loop', $this->getAttribute('with_loop'));
|
||||
$this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr'));
|
||||
|
||||
$compiler
|
||||
->write("foreach (\$context['_seq'] as ")
|
||||
->subcompile($this->getNode('key_target'))
|
||||
->raw(' => ')
|
||||
->subcompile($this->getNode('value_target'))
|
||||
->raw(") {\n")
|
||||
->indent()
|
||||
->subcompile($this->getNode('body'))
|
||||
->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_intersect_key(\$context, \$_parent) + \$_parent;\n");
|
||||
}
|
||||
}
|
55
Twig/Node/ForLoop.php
Normal file
55
Twig/Node/ForLoop.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internal node used by the for node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_ForLoop extends Twig_Node
|
||||
{
|
||||
public function __construct($lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(array(), array('with_loop' => false, 'ifexpr' => false, 'else' => false), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
if ($this->getAttribute('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 (!$this->getAttribute('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")
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
66
Twig/Node/If.php
Normal file
66
Twig/Node/If.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents an if node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
for ($i = 0, $count = count($this->getNode('tests')); $i < $count; $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");
|
||||
}
|
||||
}
|
54
Twig/Node/Import.php
Normal file
54
Twig/Node/Import.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents an import node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $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->loadTemplate(')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(', ')
|
||||
->repr($compiler->getFilename())
|
||||
->raw(', ')
|
||||
->repr($this->getLine())
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
$compiler->raw(";\n");
|
||||
}
|
||||
}
|
88
Twig/Node/Include.php
Normal file
88
Twig/Node/Include.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents an include node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
|
||||
if ($this->getAttribute('ignore_missing')) {
|
||||
$compiler
|
||||
->write("try {\n")
|
||||
->indent()
|
||||
;
|
||||
}
|
||||
|
||||
$this->addGetTemplate($compiler);
|
||||
|
||||
$compiler->raw('->display(');
|
||||
|
||||
$this->addTemplateArguments($compiler);
|
||||
|
||||
$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")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
protected function addGetTemplate(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write('$this->loadTemplate(')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(', ')
|
||||
->repr($compiler->getFilename())
|
||||
->raw(', ')
|
||||
->repr($this->getLine())
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
protected function addTemplateArguments(Twig_Compiler $compiler)
|
||||
{
|
||||
if (null === $this->getNode('variables')) {
|
||||
$compiler->raw(false === $this->getAttribute('only') ? '$context' : 'array()');
|
||||
} elseif (false === $this->getAttribute('only')) {
|
||||
$compiler
|
||||
->raw('array_merge($context, ')
|
||||
->subcompile($this->getNode('variables'))
|
||||
->raw(')')
|
||||
;
|
||||
} else {
|
||||
$compiler->subcompile($this->getNode('variables'));
|
||||
}
|
||||
}
|
||||
}
|
123
Twig/Node/Macro.php
Normal file
123
Twig/Node/Macro.php
Normal file
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a macro node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Macro extends Twig_Node
|
||||
{
|
||||
const VARARGS_NAME = 'varargs';
|
||||
|
||||
public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface $arguments, $lineno, $tag = null)
|
||||
{
|
||||
foreach ($arguments as $argumentName => $argument) {
|
||||
if (self::VARARGS_NAME === $argumentName) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write(sprintf('public function get%s(', $this->getAttribute('name')))
|
||||
;
|
||||
|
||||
$count = count($this->getNode('arguments'));
|
||||
$pos = 0;
|
||||
foreach ($this->getNode('arguments') as $name => $default) {
|
||||
$compiler
|
||||
->raw('$__'.$name.'__ = ')
|
||||
->subcompile($default)
|
||||
;
|
||||
|
||||
if (++$pos < $count) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
if ($count) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
|
||||
$compiler->raw('...$__varargs__');
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw(")\n")
|
||||
->write("{\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
$compiler
|
||||
->write("\$context = \$this->env->mergeGlobals(array(\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
foreach ($this->getNode('arguments') as $name => $default) {
|
||||
$compiler
|
||||
->addIndentation()
|
||||
->string($name)
|
||||
->raw(' => $__'.$name.'__')
|
||||
->raw(",\n")
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->addIndentation()
|
||||
->string(self::VARARGS_NAME)
|
||||
->raw(' => ')
|
||||
;
|
||||
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
$compiler->raw("\$__varargs__,\n");
|
||||
} else {
|
||||
$compiler
|
||||
->raw('func_num_args() > ')
|
||||
->repr($count)
|
||||
->raw(' ? array_slice(func_get_args(), ')
|
||||
->repr($count)
|
||||
->raw(") : array(),\n")
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->outdent()
|
||||
->write("));\n\n")
|
||||
->write("\$blocks = array();\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 ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
}
|
408
Twig/Node/Module.php
Normal file
408
Twig/Node/Module.php
Normal file
@ -0,0 +1,408 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a module node.
|
||||
*
|
||||
* Consider this class as being final. If you need to customize the behavior of
|
||||
* the generated class, consider adding nodes to the following nodes: display_start,
|
||||
* display_end, constructor_start, constructor_end, and class_end.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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, $embeddedTemplates, $filename)
|
||||
{
|
||||
// embedded templates are set as attributes so that they are only visited once by the visitors
|
||||
parent::__construct(array(
|
||||
'parent' => $parent,
|
||||
'body' => $body,
|
||||
'blocks' => $blocks,
|
||||
'macros' => $macros,
|
||||
'traits' => $traits,
|
||||
'display_start' => new Twig_Node(),
|
||||
'display_end' => new Twig_Node(),
|
||||
'constructor_start' => new Twig_Node(),
|
||||
'constructor_end' => new Twig_Node(),
|
||||
'class_end' => new Twig_Node(),
|
||||
), array(
|
||||
'filename' => $filename,
|
||||
'index' => null,
|
||||
'embedded_templates' => $embeddedTemplates,
|
||||
), 1);
|
||||
}
|
||||
|
||||
public function setIndex($index)
|
||||
{
|
||||
$this->setAttribute('index', $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$this->compileTemplate($compiler);
|
||||
|
||||
foreach ($this->getAttribute('embedded_templates') as $template) {
|
||||
$compiler->subcompile($template);
|
||||
}
|
||||
}
|
||||
|
||||
protected function compileTemplate(Twig_Compiler $compiler)
|
||||
{
|
||||
if (!$this->getAttribute('index')) {
|
||||
$compiler->write('<?php');
|
||||
}
|
||||
|
||||
$this->compileClassHeader($compiler);
|
||||
|
||||
if (
|
||||
count($this->getNode('blocks'))
|
||||
|| count($this->getNode('traits'))
|
||||
|| null === $this->getNode('parent')
|
||||
|| $this->getNode('parent') instanceof Twig_Node_Expression_Constant
|
||||
|| count($this->getNode('constructor_start'))
|
||||
|| count($this->getNode('constructor_end'))
|
||||
) {
|
||||
$this->compileConstructor($compiler);
|
||||
}
|
||||
|
||||
$this->compileGetParent($compiler);
|
||||
|
||||
$this->compileDisplay($compiler);
|
||||
|
||||
$compiler->subcompile($this->getNode('blocks'));
|
||||
|
||||
$this->compileMacros($compiler);
|
||||
|
||||
$this->compileGetTemplateName($compiler);
|
||||
|
||||
$this->compileIsTraitable($compiler);
|
||||
|
||||
$this->compileDebugInfo($compiler);
|
||||
|
||||
$this->compileClassFooter($compiler);
|
||||
}
|
||||
|
||||
protected function compileGetParent(Twig_Compiler $compiler)
|
||||
{
|
||||
if (null === $parent = $this->getNode('parent')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write("protected function doGetParent(array \$context)\n", "{\n")
|
||||
->indent()
|
||||
->addDebugInfo($parent)
|
||||
->write('return ')
|
||||
;
|
||||
|
||||
if ($parent instanceof Twig_Node_Expression_Constant) {
|
||||
$compiler->subcompile($parent);
|
||||
} else {
|
||||
$compiler
|
||||
->raw('$this->loadTemplate(')
|
||||
->subcompile($parent)
|
||||
->raw(', ')
|
||||
->repr($compiler->getFilename())
|
||||
->raw(', ')
|
||||
->repr($this->getNode('parent')->getLine())
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw(";\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
protected function compileClassHeader(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write("\n\n")
|
||||
// if the filename contains */, add a blank to avoid a PHP parse error
|
||||
->write('/* '.str_replace('*/', '* /', $this->getAttribute('filename'))." */\n")
|
||||
->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'), $this->getAttribute('index')))
|
||||
->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()
|
||||
->subcompile($this->getNode('constructor_start'))
|
||||
->write("parent::__construct(\$env);\n\n")
|
||||
;
|
||||
|
||||
// parent
|
||||
if (null === $parent = $this->getNode('parent')) {
|
||||
$compiler->write("\$this->parent = false;\n\n");
|
||||
} elseif ($parent instanceof Twig_Node_Expression_Constant) {
|
||||
$compiler
|
||||
->addDebugInfo($parent)
|
||||
->write('$this->parent = $this->loadTemplate(')
|
||||
->subcompile($parent)
|
||||
->raw(', ')
|
||||
->repr($compiler->getFilename())
|
||||
->raw(', ')
|
||||
->repr($this->getNode('parent')->getLine())
|
||||
->raw(");\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('if (!isset($_trait_%s_blocks[', $i))
|
||||
->string($key)
|
||||
->raw("])) {\n")
|
||||
->indent()
|
||||
->write("throw new Twig_Error_Runtime(sprintf('Block ")
|
||||
->string($key)
|
||||
->raw(' is not defined in trait ')
|
||||
->subcompile($trait->getNode('template'))
|
||||
->raw(".'));\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
|
||||
->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")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if ($countTraits > 1) {
|
||||
$compiler
|
||||
->write("\$this->traits = array_merge(\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
for ($i = 0; $i < $countTraits; ++$i) {
|
||||
$compiler
|
||||
->write(sprintf('$_trait_%s_blocks'.($i == $countTraits - 1 ? '' : ',')."\n", $i))
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->outdent()
|
||||
->write(");\n\n")
|
||||
;
|
||||
} else {
|
||||
$compiler
|
||||
->write("\$this->traits = \$_trait_0_blocks;\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write("\$this->blocks = array_merge(\n")
|
||||
->indent()
|
||||
->write("\$this->traits,\n")
|
||||
->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()
|
||||
->subcompile($this->getNode('constructor_end'))
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
protected function compileDisplay(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write("protected function doDisplay(array \$context, array \$blocks = array())\n", "{\n")
|
||||
->indent()
|
||||
->subcompile($this->getNode('display_start'))
|
||||
->subcompile($this->getNode('body'))
|
||||
;
|
||||
|
||||
if (null !== $parent = $this->getNode('parent')) {
|
||||
$compiler->addDebugInfo($parent);
|
||||
if ($parent instanceof Twig_Node_Expression_Constant) {
|
||||
$compiler->write('$this->parent');
|
||||
} else {
|
||||
$compiler->write('$this->getParent($context)');
|
||||
}
|
||||
$compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n");
|
||||
}
|
||||
|
||||
$compiler
|
||||
->subcompile($this->getNode('display_end'))
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
protected function compileClassFooter(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->subcompile($this->getNode('class_end'))
|
||||
->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 ($this->getNode('body') instanceof Twig_Node_Body) {
|
||||
$nodes = $this->getNode('body')->getNode(0);
|
||||
} else {
|
||||
$nodes = $this->getNode('body');
|
||||
}
|
||||
|
||||
if (!count($nodes)) {
|
||||
$nodes = new Twig_Node(array($nodes));
|
||||
}
|
||||
|
||||
foreach ($nodes as $node) {
|
||||
if (!count($node)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($node instanceof Twig_Node_BlockReference) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$traitable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($traitable) {
|
||||
return;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write("public function isTraitable()\n", "{\n")
|
||||
->indent()
|
||||
->write(sprintf("return %s;\n", $traitable ? 'true' : 'false'))
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
protected function compileDebugInfo(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write("public function getDebugInfo()\n", "{\n")
|
||||
->indent()
|
||||
->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true))))
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
;
|
||||
}
|
||||
|
||||
protected function compileLoadTemplate(Twig_Compiler $compiler, $node, $var)
|
||||
{
|
||||
if ($node instanceof Twig_Node_Expression_Constant) {
|
||||
$compiler
|
||||
->write(sprintf('%s = $this->loadTemplate(', $var))
|
||||
->subcompile($node)
|
||||
->raw(', ')
|
||||
->repr($compiler->getFilename())
|
||||
->raw(', ')
|
||||
->repr($node->getLine())
|
||||
->raw(");\n")
|
||||
;
|
||||
} else {
|
||||
throw new LogicException('Trait templates can only be constant nodes');
|
||||
}
|
||||
}
|
||||
}
|
39
Twig/Node/Print.php
Normal file
39
Twig/Node/Print.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a node that outputs an expression.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('echo ')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(";\n")
|
||||
;
|
||||
}
|
||||
}
|
47
Twig/Node/Sandbox.php
Normal file
47
Twig/Node/Sandbox.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a sandbox node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $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")
|
||||
;
|
||||
}
|
||||
}
|
61
Twig/Node/SandboxedPrint.php
Normal file
61
Twig/Node/SandboxedPrint.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Twig_Node_SandboxedPrint adds a check for the __toString() method
|
||||
* when the variable is an object and the sandbox is activated.
|
||||
*
|
||||
* When there is a simple Print statement, like {{ article }},
|
||||
* and if the sandbox is enabled, we need to check that the __toString()
|
||||
* method is allowed if 'article' is an object.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $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
|
||||
*
|
||||
* @return Twig_Node
|
||||
*/
|
||||
protected function removeNodeFilter($node)
|
||||
{
|
||||
if ($node instanceof Twig_Node_Expression_Filter) {
|
||||
return $this->removeNodeFilter($node->getNode('node'));
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
101
Twig/Node/Set.php
Normal file
101
Twig/Node/Set.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a set node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $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(" = ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset())");
|
||||
}
|
||||
}
|
||||
|
||||
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("('' === \$tmp = ")
|
||||
->subcompile($this->getNode('values'))
|
||||
->raw(") ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset())")
|
||||
;
|
||||
} else {
|
||||
$compiler->subcompile($this->getNode('values'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$compiler->raw(";\n");
|
||||
}
|
||||
}
|
35
Twig/Node/SetTemp.php
Normal file
35
Twig/Node/SetTemp.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class Twig_Node_SetTemp extends Twig_Node
|
||||
{
|
||||
public function __construct($name, $lineno)
|
||||
{
|
||||
parent::__construct(array(), array('name' => $name), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$name = $this->getAttribute('name');
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('if (isset($context[')
|
||||
->string($name)
|
||||
->raw('])) { $_')
|
||||
->raw($name)
|
||||
->raw('_ = $context[')
|
||||
->repr($name)
|
||||
->raw(']; } else { $_')
|
||||
->raw($name)
|
||||
->raw("_ = null; }\n")
|
||||
;
|
||||
}
|
||||
}
|
40
Twig/Node/Spaceless.php
Normal file
40
Twig/Node/Spaceless.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a spaceless node.
|
||||
*
|
||||
* It removes spaces between HTML tags.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $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")
|
||||
;
|
||||
}
|
||||
}
|
39
Twig/Node/Text.php
Normal file
39
Twig/Node/Text.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a text node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
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 $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('echo ')
|
||||
->string($this->getAttribute('data'))
|
||||
->raw(";\n")
|
||||
;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user