forked from leftypol/leftypol
Twig update to latest Twig 1.x legacy as per vichan
This commit is contained in:
parent
4ecd84f81d
commit
e6c07544da
198 changed files with 6150 additions and 2506 deletions
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -27,13 +27,10 @@ class Twig_Node_AutoEscape extends Twig_Node
|
|||
parent::__construct(array('body' => $body), array('value' => $value), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->subcompile($this->getNode('body'));
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_AutoEscape', 'Twig\Node\AutoEscapeNode', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -22,11 +22,6 @@ class Twig_Node_Block extends Twig_Node
|
|||
parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -42,3 +37,5 @@ class Twig_Node_Block extends Twig_Node
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Block', 'Twig\Node\BlockNode', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -22,11 +22,6 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter
|
|||
parent::__construct(array(), array('name' => $name), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -35,3 +30,5 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_BlockReference', 'Twig\Node\BlockReferenceNode', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -17,3 +17,5 @@
|
|||
class Twig_Node_Body extends Twig_Node
|
||||
{
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Body', 'Twig\Node\BodyNode', false);
|
||||
|
|
80
inc/lib/Twig/Node/CheckSecurity.php
Normal file
80
inc/lib/Twig/Node/CheckSecurity.php
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 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->getTemplateLine();
|
||||
} 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('Twig_Extension_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->setSourceContext(\$this->getSourceContext());\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")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_CheckSecurity', 'Twig\Node\CheckSecurityNode', false);
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -21,11 +21,6 @@ class Twig_Node_Do extends Twig_Node
|
|||
parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -36,3 +31,5 @@ class Twig_Node_Do extends Twig_Node
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Do', 'Twig\Node\DoNode', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2012 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -17,22 +17,30 @@
|
|||
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)
|
||||
public function __construct($name, $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('name', $name);
|
||||
// to be removed in 2.0, used name instead
|
||||
$this->setAttribute('filename', $name);
|
||||
$this->setAttribute('index', $index);
|
||||
}
|
||||
|
||||
protected function addGetTemplate(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write("\$this->env->loadTemplate(")
|
||||
->string($this->getAttribute('filename'))
|
||||
->write('$this->loadTemplate(')
|
||||
->string($this->getAttribute('name'))
|
||||
->raw(', ')
|
||||
->repr($this->getTemplateName())
|
||||
->raw(', ')
|
||||
->repr($this->getTemplateLine())
|
||||
->raw(', ')
|
||||
->string($this->getAttribute('index'))
|
||||
->raw(")")
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Embed', 'Twig\Node\EmbedNode', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -18,3 +18,5 @@
|
|||
abstract class Twig_Node_Expression extends Twig_Node
|
||||
{
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression', 'Twig\Node\Expression\AbstractExpression', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -43,7 +43,7 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
|
|||
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']) {
|
||||
if ((string) $key === (string) $pair['key']) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -54,17 +54,12 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
|
|||
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());
|
||||
$key = new Twig_Node_Expression_Constant(++$this->index, $value->getTemplateLine());
|
||||
}
|
||||
|
||||
array_push($this->nodes, $key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('array(');
|
||||
|
@ -84,3 +79,5 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
|
|||
$compiler->raw(')');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Array', 'Twig\Node\Expression\ArrayExpression', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -12,11 +12,6 @@
|
|||
|
||||
class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
|
||||
{
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -26,3 +21,5 @@ class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_AssignName', 'Twig\Node\Expression\AssignNameExpression', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,11 +16,6 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
|
|||
parent::__construct(array('left' => $left, 'right' => $right), array(), $lineno);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -38,3 +33,5 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
|
|||
|
||||
abstract public function operator(Twig_Compiler $compiler);
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary', 'Twig\Node\Expression\Binary\AbstractBinary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Add extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('+');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Add', 'Twig\Node\Expression\Binary\AddBinary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_And extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('&&');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_And', 'Twig\Node\Expression\Binary\AndBinary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseAnd extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('&');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_BitwiseAnd', 'Twig\Node\Expression\Binary\BitwiseAndBinary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseOr extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('|');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_BitwiseOr', 'Twig\Node\Expression\Binary\BitwiseOrBinary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseXor extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('^');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_BitwiseXor', 'Twig\Node\Expression\Binary\BitwiseXorBinary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Concat extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('.');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Concat', 'Twig\Node\Expression\Binary\ConcatBinary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Div extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('/');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Div', 'Twig\Node\Expression\Binary\DivBinary', false);
|
||||
|
|
32
inc/lib/Twig/Node/Expression/Binary/EndsWith.php
Normal file
32
inc/lib/Twig/Node/Expression/Binary/EndsWith.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 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('');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_EndsWith', 'Twig\Node\Expression\Binary\EndsWithBinary', false);
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Equal extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('==');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Equal', 'Twig\Node\Expression\Binary\EqualBinary', false);
|
||||
|
|
|
@ -3,23 +3,18 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 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 A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('intval(floor(');
|
||||
$compiler->raw('(int) floor(');
|
||||
parent::compile($compiler);
|
||||
$compiler->raw('))');
|
||||
$compiler->raw(')');
|
||||
}
|
||||
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
|
@ -27,3 +22,5 @@ class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('/');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_FloorDiv', 'Twig\Node\Expression\Binary\FloorDivBinary', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Greater extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('>');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Greater', 'Twig\Node\Expression\Binary\GreaterBinary', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_GreaterEqual extends Twig_Node_Expression_Bina
|
|||
return $compiler->raw('>=');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_GreaterEqual', 'Twig\Node\Expression\Binary\GreaterEqualBinary', false);
|
||||
|
|
|
@ -3,18 +3,13 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) 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 A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -31,3 +26,5 @@ class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('in');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_In', 'Twig\Node\Expression\Binary\InBinary', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Less extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('<');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Less', 'Twig\Node\Expression\Binary\LessBinary', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_LessEqual extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('<=');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_LessEqual', 'Twig\Node\Expression\Binary\LessEqualBinary', false);
|
||||
|
|
30
inc/lib/Twig/Node/Expression/Binary/Matches.php
Normal file
30
inc/lib/Twig/Node/Expression/Binary/Matches.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 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('');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Matches', 'Twig\Node\Expression\Binary\MatchesBinary', false);
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Mod extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('%');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Mod', 'Twig\Node\Expression\Binary\ModBinary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Mul extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('*');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Mul', 'Twig\Node\Expression\Binary\MulBinary', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_NotEqual extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('!=');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_NotEqual', 'Twig\Node\Expression\Binary\NotEqualBinary', false);
|
||||
|
|
|
@ -3,18 +3,13 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) 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 A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -31,3 +26,5 @@ class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('not in');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_NotIn', 'Twig\Node\Expression\Binary\NotInBinary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Or extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('||');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Or', 'Twig\Node\Expression\Binary\OrBinary', false);
|
||||
|
|
|
@ -3,20 +3,19 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) 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 A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
return parent::compile($compiler);
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw('pow(')
|
||||
->subcompile($this->getNode('left'))
|
||||
|
@ -31,3 +30,5 @@ class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('**');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Power', 'Twig\Node\Expression\Binary\PowerBinary', false);
|
||||
|
|
|
@ -3,18 +3,13 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) 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 A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -31,3 +26,5 @@ class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('..');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Range', 'Twig\Node\Expression\Binary\RangeBinary', false);
|
||||
|
|
32
inc/lib/Twig/Node/Expression/Binary/StartsWith.php
Normal file
32
inc/lib/Twig/Node/Expression/Binary/StartsWith.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 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('');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_StartsWith', 'Twig\Node\Expression\Binary\StartsWithBinary', false);
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Sub extends Twig_Node_Expression_Binary
|
|||
return $compiler->raw('-');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Binary_Sub', 'Twig\Node\Expression\Binary\SubBinary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -17,35 +17,77 @@
|
|||
*/
|
||||
class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct(Twig_NodeInterface $name, $asString = false, $lineno, $tag = null)
|
||||
/**
|
||||
* @param Twig_Node|null $template
|
||||
*/
|
||||
public function __construct(Twig_NodeInterface $name, $template = null, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(array('name' => $name), array('as_string' => $asString, 'output' => false), $lineno, $tag);
|
||||
if (is_bool($template)) {
|
||||
@trigger_error(sprintf('The %s method "$asString" argument is deprecated since version 1.28 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
$template = null;
|
||||
}
|
||||
|
||||
$nodes = array('name' => $name);
|
||||
if (null !== $template) {
|
||||
$nodes['template'] = $template;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, array('is_defined_test' => false, 'output' => false), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
if ($this->getAttribute('as_string')) {
|
||||
$compiler->raw('(string) ');
|
||||
}
|
||||
|
||||
if ($this->getAttribute('output')) {
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write("\$this->displayBlock(")
|
||||
->subcompile($this->getNode('name'))
|
||||
->raw(", \$context, \$blocks);\n")
|
||||
;
|
||||
if ($this->getAttribute('is_defined_test')) {
|
||||
$this->compileTemplateCall($compiler, 'hasBlock');
|
||||
} else {
|
||||
$compiler
|
||||
->raw("\$this->renderBlock(")
|
||||
->subcompile($this->getNode('name'))
|
||||
->raw(", \$context, \$blocks)")
|
||||
;
|
||||
if ($this->getAttribute('output')) {
|
||||
$compiler->addDebugInfo($this);
|
||||
|
||||
$this
|
||||
->compileTemplateCall($compiler, 'displayBlock')
|
||||
->raw(";\n");
|
||||
} else {
|
||||
$this->compileTemplateCall($compiler, 'renderBlock');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function compileTemplateCall(Twig_Compiler $compiler, $method)
|
||||
{
|
||||
if (!$this->hasNode('template')) {
|
||||
$compiler->write('$this');
|
||||
} else {
|
||||
$compiler
|
||||
->write('$this->loadTemplate(')
|
||||
->subcompile($this->getNode('template'))
|
||||
->raw(', ')
|
||||
->repr($this->getTemplateName())
|
||||
->raw(', ')
|
||||
->repr($this->getTemplateLine())
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
$compiler->raw(sprintf('->%s', $method));
|
||||
$this->compileBlockArguments($compiler);
|
||||
|
||||
return $compiler;
|
||||
}
|
||||
|
||||
private function compileBlockArguments(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('(')
|
||||
->subcompile($this->getNode('name'))
|
||||
->raw(', $context');
|
||||
|
||||
if (!$this->hasNode('template')) {
|
||||
$compiler->raw(', $blocks');
|
||||
}
|
||||
|
||||
return $compiler->raw(')');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_BlockReference', 'Twig\Node\Expression\BlockReferenceExpression', false);
|
||||
|
|
|
@ -3,27 +3,36 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2012 Fabien Potencier
|
||||
* (c) 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
|
||||
{
|
||||
private $reflector;
|
||||
|
||||
protected function compileCallable(Twig_Compiler $compiler)
|
||||
{
|
||||
$callable = $this->getAttribute('callable');
|
||||
|
||||
$closingParenthesis = false;
|
||||
if ($callable) {
|
||||
if (is_string($callable)) {
|
||||
if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
|
||||
if (is_string($callable) && false === strpos($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;
|
||||
list($r, $callable) = $this->reflectCallable($callable);
|
||||
if ($r instanceof ReflectionMethod && is_string($callable[0])) {
|
||||
if ($r->isStatic()) {
|
||||
$compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
|
||||
} else {
|
||||
$compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
|
||||
}
|
||||
} elseif ($r instanceof ReflectionMethod && $callable[0] instanceof Twig_ExtensionInterface) {
|
||||
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', get_class($callable[0]), $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());
|
||||
|
@ -73,7 +82,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
|||
$first = false;
|
||||
}
|
||||
|
||||
if ($this->hasNode('arguments') && null !== $this->getNode('arguments')) {
|
||||
if ($this->hasNode('arguments')) {
|
||||
$callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
|
||||
|
||||
$arguments = $this->getArguments($callable, $this->getNode('arguments'));
|
||||
|
@ -92,6 +101,9 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
|||
|
||||
protected function getArguments($callable, $arguments)
|
||||
{
|
||||
$callType = $this->getAttribute('type');
|
||||
$callName = $this->getAttribute('name');
|
||||
|
||||
$parameters = array();
|
||||
$named = false;
|
||||
foreach ($arguments as $name => $node) {
|
||||
|
@ -99,73 +111,101 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
|||
$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".', $this->getAttribute('type'), $this->getAttribute('name')));
|
||||
throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName));
|
||||
}
|
||||
|
||||
$parameters[$name] = $node;
|
||||
}
|
||||
|
||||
if (!$named) {
|
||||
$isVariadic = $this->hasAttribute('is_variadic') && $this->getAttribute('is_variadic');
|
||||
if (!$named && !$isVariadic) {
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
if (!$callable) {
|
||||
throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name')));
|
||||
}
|
||||
|
||||
// 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');
|
||||
} 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 ($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);
|
||||
}
|
||||
|
||||
$callableParameters = $this->getCallableParameters($callable, $isVariadic);
|
||||
$arguments = array();
|
||||
$names = array();
|
||||
$missingArguments = array();
|
||||
$optionalArguments = array();
|
||||
$pos = 0;
|
||||
foreach ($definition as $param) {
|
||||
$name = $this->normalizeName($param->name);
|
||||
foreach ($callableParameters as $callableParameter) {
|
||||
$names[] = $name = $this->normalizeName($callableParameter->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, $this->getAttribute('type'), $this->getAttribute('name')));
|
||||
throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName));
|
||||
}
|
||||
|
||||
if (count($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()) {
|
||||
$arguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1);
|
||||
} elseif ($param->isOptional()) {
|
||||
break;
|
||||
} elseif ($callableParameter->isDefaultValueAvailable()) {
|
||||
$optionalArguments[] = new Twig_Node_Expression_Constant($callableParameter->getDefaultValue(), -1);
|
||||
} elseif ($callableParameter->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, $this->getAttribute('type'), $this->getAttribute('name')));
|
||||
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)) {
|
||||
throw new Twig_Error_Syntax(sprintf('Unknown argument%s "%s" for %s "%s".', count($parameters) > 1 ? 's' : '' , implode('", "', array_keys($parameters)), $this->getAttribute('type'), $this->getAttribute('name')));
|
||||
$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->getTemplateLine() : -1);
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
|
@ -175,4 +215,77 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
|||
{
|
||||
return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $name));
|
||||
}
|
||||
|
||||
private function getCallableParameters($callable, $isVariadic)
|
||||
{
|
||||
list($r) = $this->reflectCallable($callable);
|
||||
if (null === $r) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$parameters = $r->getParameters();
|
||||
if ($this->hasNode('node')) {
|
||||
array_shift($parameters);
|
||||
}
|
||||
if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
|
||||
array_shift($parameters);
|
||||
}
|
||||
if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
|
||||
array_shift($parameters);
|
||||
}
|
||||
if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
|
||||
foreach ($this->getAttribute('arguments') as $argument) {
|
||||
array_shift($parameters);
|
||||
}
|
||||
}
|
||||
if ($isVariadic) {
|
||||
$argument = end($parameters);
|
||||
if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && array() === $argument->getDefaultValue()) {
|
||||
array_pop($parameters);
|
||||
} else {
|
||||
$callableName = $r->name;
|
||||
if ($r instanceof ReflectionMethod) {
|
||||
$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, $this->getAttribute('type'), $this->getAttribute('name')));
|
||||
}
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
private function reflectCallable($callable)
|
||||
{
|
||||
if (null !== $this->reflector) {
|
||||
return $this->reflector;
|
||||
}
|
||||
|
||||
if (is_array($callable)) {
|
||||
if (!method_exists($callable[0], $callable[1])) {
|
||||
// __call()
|
||||
return array(null, array());
|
||||
}
|
||||
$r = new ReflectionMethod($callable[0], $callable[1]);
|
||||
} elseif (is_object($callable) && !$callable instanceof Closure) {
|
||||
$r = new ReflectionObject($callable);
|
||||
$r = $r->getMethod('__invoke');
|
||||
$callable = array($callable, '__invoke');
|
||||
} elseif (is_string($callable) && false !== $pos = strpos($callable, '::')) {
|
||||
$class = substr($callable, 0, $pos);
|
||||
$method = substr($callable, $pos + 2);
|
||||
if (!method_exists($class, $method)) {
|
||||
// __staticCall()
|
||||
return array(null, array());
|
||||
}
|
||||
$r = new ReflectionMethod($callable);
|
||||
$callable = array($class, $method);
|
||||
} else {
|
||||
$r = new ReflectionFunction($callable);
|
||||
}
|
||||
|
||||
return $this->reflector = array($r, $callable);
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Call', 'Twig\Node\Expression\CallExpression', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -29,3 +29,5 @@ class Twig_Node_Expression_Conditional extends Twig_Node_Expression
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Conditional', 'Twig\Node\Expression\ConditionalExpression', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -21,3 +21,5 @@ class Twig_Node_Expression_Constant extends Twig_Node_Expression
|
|||
$compiler->repr($this->getAttribute('value'));
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Constant', 'Twig\Node\Expression\ConstantExpression', false);
|
||||
|
|
|
@ -3,16 +3,20 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
@trigger_error('The Twig_Node_Expression_ExtensionReference class is deprecated since version 1.23 and will be removed in 2.0.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Represents an extension call node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated since 1.23 and will be removed in 2.0.
|
||||
*/
|
||||
class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
|
||||
{
|
||||
|
@ -21,11 +25,6 @@ class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
|
|||
parent::__construct(array(), array('name' => $name), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name')));
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -30,7 +30,12 @@ class Twig_Node_Expression_Filter extends Twig_Node_Expression_Call
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Filter', 'Twig\Node\Expression\FilterExpression', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -22,13 +22,13 @@ 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());
|
||||
$default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine());
|
||||
|
||||
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());
|
||||
$test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getTemplateLine());
|
||||
$false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getTemplateLine());
|
||||
|
||||
$node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getLine());
|
||||
$node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getTemplateLine());
|
||||
} else {
|
||||
$node = $default;
|
||||
}
|
||||
|
@ -41,3 +41,5 @@ class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter
|
|||
$compiler->subcompile($this->getNode('node'));
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Filter_Default', 'Twig\Node\Expression\Filter\DefaultFilter', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -12,7 +12,7 @@ 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);
|
||||
parent::__construct(array('arguments' => $arguments), array('name' => $name, 'is_defined_test' => false), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
|
@ -27,9 +27,19 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression_Call
|
|||
$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());
|
||||
$callable = $function->getCallable();
|
||||
if ('constant' === $name && $this->getAttribute('is_defined_test')) {
|
||||
$callable = 'twig_constant_is_defined';
|
||||
}
|
||||
|
||||
$this->setAttribute('callable', $callable);
|
||||
}
|
||||
if ($function instanceof Twig_SimpleFunction) {
|
||||
$this->setAttribute('is_variadic', $function->isVariadic());
|
||||
}
|
||||
|
||||
$this->compileCallable($compiler);
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Function', 'Twig\Node\Expression\FunctionExpression', false);
|
||||
|
|
|
@ -3,21 +3,30 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) 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_Array $arguments, $type, $lineno)
|
||||
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);
|
||||
$nodes = array('node' => $node, 'attribute' => $attribute);
|
||||
if (null !== $arguments) {
|
||||
$nodes['arguments'] = $arguments;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
if ($this->getAttribute('disable_c_ext')) {
|
||||
@trigger_error(sprintf('Using the "disable_c_ext" attribute on %s is deprecated since version 1.30 and will be removed in 2.0.', __CLASS__), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) {
|
||||
$compiler->raw('twig_template_get_attributes($this, ');
|
||||
} else {
|
||||
|
@ -32,22 +41,34 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
|
|||
|
||||
$compiler->raw(', ')->subcompile($this->getNode('attribute'));
|
||||
|
||||
if (count($this->getNode('arguments')) || Twig_Template::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
|
||||
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
|
||||
// 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 || $this->hasNode('arguments');
|
||||
|
||||
if (Twig_Template::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('type'));
|
||||
if ($needFirst) {
|
||||
if ($this->hasNode('arguments')) {
|
||||
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
|
||||
} else {
|
||||
$compiler->raw(', array()');
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
|
||||
$compiler->raw(', '.($this->getAttribute('is_defined_test') ? 'true' : 'false'));
|
||||
}
|
||||
if ($needSecond) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('type'));
|
||||
}
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check')) {
|
||||
$compiler->raw(', '.($this->getAttribute('ignore_strict_check') ? 'true' : 'false'));
|
||||
}
|
||||
if ($needThird) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('is_defined_test'));
|
||||
}
|
||||
|
||||
if ($needFourth) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('ignore_strict_check'));
|
||||
}
|
||||
|
||||
$compiler->raw(')');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_GetAttr', 'Twig\Node\Expression\GetAttrExpression', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2012 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -39,3 +39,5 @@ class Twig_Node_Expression_MethodCall extends Twig_Node_Expression
|
|||
$compiler->raw(')');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_MethodCall', 'Twig\Node\Expression\MethodCallExpression', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -12,7 +12,7 @@
|
|||
class Twig_Node_Expression_Name extends Twig_Node_Expression
|
||||
{
|
||||
protected $specialVars = array(
|
||||
'_self' => '$this',
|
||||
'_self' => '$this',
|
||||
'_context' => '$context',
|
||||
'_charset' => '$this->env->getCharset()',
|
||||
);
|
||||
|
@ -26,6 +26,8 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
|
|||
{
|
||||
$name = $this->getAttribute('name');
|
||||
|
||||
$compiler->addDebugInfo($this);
|
||||
|
||||
if ($this->getAttribute('is_defined_test')) {
|
||||
if ($this->isSpecial()) {
|
||||
$compiler->repr(true);
|
||||
|
@ -41,10 +43,20 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
|
|||
->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 (version_compare(phpversion(), '5.4.0RC1', '>=')) {
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
// use PHP 7 null coalescing operator
|
||||
$compiler
|
||||
->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('))');
|
||||
}
|
||||
} elseif (PHP_VERSION_ID >= 50400) {
|
||||
// PHP 5.4 ternary operator performance was optimized
|
||||
$compiler
|
||||
->raw('(isset($context[')
|
||||
|
@ -86,3 +98,5 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
|
|||
return !$this->isSpecial() && !$this->getAttribute('is_defined_test');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Name', 'Twig\Node\Expression\NameExpression', false);
|
||||
|
|
48
inc/lib/Twig/Node/Expression/NullCoalesce.php
Normal file
48
inc/lib/Twig/Node/Expression/NullCoalesce.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 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_NullCoalesce extends Twig_Node_Expression_Conditional
|
||||
{
|
||||
public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
|
||||
{
|
||||
$test = new Twig_Node_Expression_Binary_And(
|
||||
new Twig_Node_Expression_Test_Defined(clone $left, 'defined', new Twig_Node(), $left->getTemplateLine()),
|
||||
new Twig_Node_Expression_Unary_Not(new Twig_Node_Expression_Test_Null($left, 'null', new Twig_Node(), $left->getTemplateLine()), $left->getTemplateLine()),
|
||||
$left->getTemplateLine()
|
||||
);
|
||||
|
||||
parent::__construct($test, $left, $right, $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
/*
|
||||
* This optimizes only one case. PHP 7 also supports more complex expressions
|
||||
* that can return null. So, for instance, if log is defined, log("foo") ?? "..." works,
|
||||
* but log($a["foo"]) ?? "..." does not if $a["foo"] is not defined. More advanced
|
||||
* cases might be implemented as an optimizer node visitor, but has not been done
|
||||
* as benefits are probably not worth the added complexity.
|
||||
*/
|
||||
if (PHP_VERSION_ID >= 70000 && $this->getNode('expr2') instanceof Twig_Node_Expression_Name) {
|
||||
$this->getNode('expr2')->setAttribute('always_defined', true);
|
||||
$compiler
|
||||
->raw('((')
|
||||
->subcompile($this->getNode('expr2'))
|
||||
->raw(') ?? (')
|
||||
->subcompile($this->getNode('expr3'))
|
||||
->raw('))')
|
||||
;
|
||||
} else {
|
||||
parent::compile($compiler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_NullCoalesce', 'Twig\Node\Expression\NullCoalesceExpression', false);
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -22,26 +22,23 @@ class Twig_Node_Expression_Parent extends Twig_Node_Expression
|
|||
parent::__construct(array(), array('output' => false, 'name' => $name), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
if ($this->getAttribute('output')) {
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write("\$this->displayParentBlock(")
|
||||
->write('$this->displayParentBlock(')
|
||||
->string($this->getAttribute('name'))
|
||||
->raw(", \$context, \$blocks);\n")
|
||||
;
|
||||
} else {
|
||||
$compiler
|
||||
->raw("\$this->renderParentBlock(")
|
||||
->raw('$this->renderParentBlock(')
|
||||
->string($this->getAttribute('name'))
|
||||
->raw(", \$context, \$blocks)")
|
||||
->raw(', $context, $blocks)')
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Parent', 'Twig\Node\Expression\ParentExpression', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -24,3 +24,5 @@ class Twig_Node_Expression_TempName extends Twig_Node_Expression
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_TempName', 'Twig\Node\Expression\TempNameExpression', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -12,7 +12,12 @@ 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);
|
||||
$nodes = array('node' => $node);
|
||||
if (null !== $arguments) {
|
||||
$nodes['arguments'] = $arguments;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, array('name' => $name), $lineno);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
|
@ -26,7 +31,12 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression_Call
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Test', 'Twig\Node\Expression\TestExpression', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -44,3 +44,5 @@ class Twig_Node_Expression_Test_Constant extends Twig_Node_Expression_Test
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Test_Constant', 'Twig\Node\Expression\Test\ConstantTest', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -25,17 +25,22 @@ 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);
|
||||
} elseif ($node instanceof Twig_Node_Expression_BlockReference) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
} elseif ($node instanceof Twig_Node_Expression_Function && 'constant' === $node->getAttribute('name')) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
} elseif ($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array) {
|
||||
$node = new Twig_Node_Expression_Constant(true, $node->getTemplateLine());
|
||||
} else {
|
||||
throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine());
|
||||
throw new Twig_Error_Syntax('The "defined" test only works with simple variables.', $this->getTemplateLine());
|
||||
}
|
||||
|
||||
parent::__construct($node, $name, $arguments, $lineno);
|
||||
}
|
||||
|
||||
protected function changeIgnoreStrictCheck(Twig_Node_Expression_GetAttr $node)
|
||||
|
@ -52,3 +57,5 @@ class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test
|
|||
$compiler->subcompile($this->getNode('node'));
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Test_Defined', 'Twig\Node\Expression\Test\DefinedTest', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -13,7 +13,7 @@
|
|||
* Checks if a variable is divisible by a number.
|
||||
*
|
||||
* <pre>
|
||||
* {% if loop.index is divisibleby(3) %}
|
||||
* {% if loop.index is divisible by(3) %}
|
||||
* </pre>
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
|
@ -31,3 +31,5 @@ class Twig_Node_Expression_Test_Divisibleby extends Twig_Node_Expression_Test
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Test_Divisibleby', 'Twig\Node\Expression\Test\DivisiblebyTest', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -30,3 +30,5 @@ class Twig_Node_Expression_Test_Even extends Twig_Node_Expression_Test
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Test_Even', 'Twig\Node\Expression\Test\EvenTest', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -29,3 +29,5 @@ class Twig_Node_Expression_Test_Null extends Twig_Node_Expression_Test
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Test_Null', 'Twig\Node\Expression\Test\NullTest', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -30,3 +30,5 @@ class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Test_Odd', 'Twig\Node\Expression\Test\OddTest', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -27,3 +27,5 @@ class Twig_Node_Expression_Test_Sameas extends Twig_Node_Expression_Test
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Test_Sameas', 'Twig\Node\Expression\Test\SameasTest', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -18,13 +18,12 @@ abstract class Twig_Node_Expression_Unary extends Twig_Node_Expression
|
|||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('(');
|
||||
$compiler->raw(' ');
|
||||
$this->operator($compiler);
|
||||
$compiler
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(')')
|
||||
;
|
||||
$compiler->subcompile($this->getNode('node'));
|
||||
}
|
||||
|
||||
abstract public function operator(Twig_Compiler $compiler);
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Unary', 'Twig\Node\Expression\Unary\AbstractUnary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Neg extends Twig_Node_Expression_Unary
|
|||
$compiler->raw('-');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Unary_Neg', 'Twig\Node\Expression\Unary\NegUnary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Not extends Twig_Node_Expression_Unary
|
|||
$compiler->raw('!');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Unary_Not', 'Twig\Node\Expression\Unary\NotUnary', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Pos extends Twig_Node_Expression_Unary
|
|||
$compiler->raw('+');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Expression_Unary_Pos', 'Twig\Node\Expression\Unary\PosUnary', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -21,11 +21,6 @@ class Twig_Node_Flush extends Twig_Node
|
|||
parent::__construct(array(), array(), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -34,3 +29,5 @@ class Twig_Node_Flush extends Twig_Node
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Flush', 'Twig\Node\FlushNode', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -27,26 +27,25 @@ class Twig_Node_For extends Twig_Node
|
|||
$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);
|
||||
$nodes = array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body);
|
||||
if (null !== $else) {
|
||||
$nodes['else'] = $else;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
// the (array) cast bypasses a PHP 5.2.6 bug
|
||||
->write("\$context['_parent'] = (array) \$context;\n")
|
||||
->write("\$context['_parent'] = \$context;\n")
|
||||
->write("\$context['_seq'] = twig_ensure_traversable(")
|
||||
->subcompile($this->getNode('seq'))
|
||||
->raw(");\n")
|
||||
;
|
||||
|
||||
if (null !== $this->getNode('else')) {
|
||||
if ($this->hasNode('else')) {
|
||||
$compiler->write("\$context['_iterated'] = false;\n");
|
||||
}
|
||||
|
||||
|
@ -75,14 +74,14 @@ class Twig_Node_For extends Twig_Node
|
|||
}
|
||||
}
|
||||
|
||||
$this->loop->setAttribute('else', null !== $this->getNode('else'));
|
||||
$this->loop->setAttribute('else', $this->hasNode('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(" => ")
|
||||
->raw(' => ')
|
||||
->subcompile($this->getNode('value_target'))
|
||||
->raw(") {\n")
|
||||
->indent()
|
||||
|
@ -91,7 +90,7 @@ class Twig_Node_For extends Twig_Node
|
|||
->write("}\n")
|
||||
;
|
||||
|
||||
if (null !== $this->getNode('else')) {
|
||||
if ($this->hasNode('else')) {
|
||||
$compiler
|
||||
->write("if (!\$context['_iterated']) {\n")
|
||||
->indent()
|
||||
|
@ -110,3 +109,5 @@ class Twig_Node_For extends Twig_Node
|
|||
$compiler->write("\$context = array_intersect_key(\$context, \$_parent) + \$_parent;\n");
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_For', 'Twig\Node\ForNode', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -21,11 +21,6 @@ class Twig_Node_ForLoop extends Twig_Node
|
|||
parent::__construct(array(), array('with_loop' => false, 'ifexpr' => false, 'else' => false), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
if ($this->getAttribute('else')) {
|
||||
|
@ -53,3 +48,5 @@ class Twig_Node_ForLoop extends Twig_Node
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_ForLoop', 'Twig\Node\ForLoopNode', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -19,22 +19,22 @@ 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);
|
||||
$nodes = array('tests' => $tests);
|
||||
if (null !== $else) {
|
||||
$nodes['else'] = $else;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, array(), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
for ($i = 0; $i < count($this->getNode('tests')); $i += 2) {
|
||||
for ($i = 0, $count = count($this->getNode('tests')); $i < $count; $i += 2) {
|
||||
if ($i > 0) {
|
||||
$compiler
|
||||
->outdent()
|
||||
->write("} elseif (")
|
||||
->write('} elseif (')
|
||||
;
|
||||
} else {
|
||||
$compiler
|
||||
|
@ -50,7 +50,7 @@ class Twig_Node_If extends Twig_Node
|
|||
;
|
||||
}
|
||||
|
||||
if ($this->hasNode('else') && null !== $this->getNode('else')) {
|
||||
if ($this->hasNode('else')) {
|
||||
$compiler
|
||||
->outdent()
|
||||
->write("} else {\n")
|
||||
|
@ -64,3 +64,5 @@ class Twig_Node_If extends Twig_Node
|
|||
->write("}\n");
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_If', 'Twig\Node\IfNode', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -21,11 +21,6 @@ class Twig_Node_Import extends Twig_Node
|
|||
parent::__construct(array('expr' => $expr, 'var' => $var), array(), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -36,15 +31,21 @@ class Twig_Node_Import extends Twig_Node
|
|||
;
|
||||
|
||||
if ($this->getNode('expr') instanceof Twig_Node_Expression_Name && '_self' === $this->getNode('expr')->getAttribute('name')) {
|
||||
$compiler->raw("\$this");
|
||||
$compiler->raw('$this');
|
||||
} else {
|
||||
$compiler
|
||||
->raw('$this->env->loadTemplate(')
|
||||
->raw('$this->loadTemplate(')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(")")
|
||||
->raw(', ')
|
||||
->repr($this->getTemplateName())
|
||||
->raw(', ')
|
||||
->repr($this->getTemplateLine())
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
$compiler->raw(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Import', 'Twig\Node\ImportNode', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -19,14 +19,14 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
|
|||
{
|
||||
public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (Boolean) $only, 'ignore_missing' => (Boolean) $ignoreMissing), $lineno, $tag);
|
||||
$nodes = array('expr' => $expr);
|
||||
if (null !== $variables) {
|
||||
$nodes['variables'] = $variables;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, array('only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
|
@ -60,40 +60,31 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
|
|||
|
||||
protected function addGetTemplate(Twig_Compiler $compiler)
|
||||
{
|
||||
if ($this->getNode('expr') instanceof Twig_Node_Expression_Constant) {
|
||||
$compiler
|
||||
->write("\$this->env->loadTemplate(")
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(")")
|
||||
;
|
||||
} else {
|
||||
$compiler
|
||||
->write("\$template = \$this->env->resolveTemplate(")
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(");\n")
|
||||
->write('$template')
|
||||
;
|
||||
}
|
||||
$compiler
|
||||
->write('$this->loadTemplate(')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(', ')
|
||||
->repr($this->getTemplateName())
|
||||
->raw(', ')
|
||||
->repr($this->getTemplateLine())
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
protected function addTemplateArguments(Twig_Compiler $compiler)
|
||||
{
|
||||
if (false === $this->getAttribute('only')) {
|
||||
if (null === $this->getNode('variables')) {
|
||||
$compiler->raw('$context');
|
||||
} else {
|
||||
$compiler
|
||||
->raw('array_merge($context, ')
|
||||
->subcompile($this->getNode('variables'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
if (!$this->hasNode('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 {
|
||||
if (null === $this->getNode('variables')) {
|
||||
$compiler->raw('array()');
|
||||
} else {
|
||||
$compiler->subcompile($this->getNode('variables'));
|
||||
}
|
||||
$compiler->subcompile($this->getNode('variables'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Include', 'Twig\Node\IncludeNode', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -16,28 +16,31 @@
|
|||
*/
|
||||
class Twig_Node_Macro extends Twig_Node
|
||||
{
|
||||
const VARARGS_NAME = 'varargs';
|
||||
|
||||
public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface $arguments, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name, 'method' => 'get'.ucfirst($name)), $lineno, $tag);
|
||||
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->getTemplateLine());
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write(sprintf("public function %s(", $this->getAttribute('method')))
|
||||
->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.' = ')
|
||||
->raw('$__'.$name.'__ = ')
|
||||
->subcompile($default)
|
||||
;
|
||||
|
||||
|
@ -46,36 +49,55 @@ class Twig_Node_Macro extends Twig_Node
|
|||
}
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
if ($count) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
|
||||
$compiler->raw('...$__varargs__');
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw(")\n")
|
||||
->write("{\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
if (!count($this->getNode('arguments'))) {
|
||||
$compiler->write("\$context = \$this->env->getGlobals();\n\n");
|
||||
} else {
|
||||
$compiler
|
||||
->write("\$context = \$this->env->mergeGlobals(array(\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
foreach ($this->getNode('arguments') as $name => $default) {
|
||||
$compiler
|
||||
->write('')
|
||||
->string($name)
|
||||
->raw(' => $_'.$name)
|
||||
->raw(",\n")
|
||||
;
|
||||
}
|
||||
$compiler
|
||||
->write("\$context = \$this->env->mergeGlobals(array(\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
foreach ($this->getNode('arguments') as $name => $default) {
|
||||
$compiler
|
||||
->outdent()
|
||||
->write("));\n\n")
|
||||
->write('')
|
||||
->string($name)
|
||||
->raw(' => $__'.$name.'__')
|
||||
->raw(",\n")
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write('')
|
||||
->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")
|
||||
|
@ -87,6 +109,11 @@ class Twig_Node_Macro extends Twig_Node
|
|||
->write("ob_end_clean();\n\n")
|
||||
->write("throw \$e;\n")
|
||||
->outdent()
|
||||
->write("} catch (Throwable \$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()
|
||||
|
@ -94,3 +121,5 @@ class Twig_Node_Macro extends Twig_Node
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Macro', 'Twig\Node\MacroNode', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -13,14 +13,52 @@
|
|||
/**
|
||||
* 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)
|
||||
private $source;
|
||||
|
||||
public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $name, $source = '')
|
||||
{
|
||||
if (!$name instanceof Twig_Source) {
|
||||
@trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
$this->source = new Twig_Source($source, $name);
|
||||
} else {
|
||||
$this->source = $name;
|
||||
}
|
||||
|
||||
$nodes = array(
|
||||
'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(),
|
||||
);
|
||||
if (null !== $parent) {
|
||||
$nodes['parent'] = $parent;
|
||||
}
|
||||
|
||||
// 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), array('filename' => $filename, 'index' => null, 'embedded_templates' => $embeddedTemplates), 1);
|
||||
parent::__construct($nodes, array(
|
||||
// source to be remove in 2.0
|
||||
'source' => $this->source->getCode(),
|
||||
// filename to be remove in 2.0 (use getTemplateName() instead)
|
||||
'filename' => $this->source->getName(),
|
||||
'index' => null,
|
||||
'embedded_templates' => $embeddedTemplates,
|
||||
), 1);
|
||||
|
||||
// populate the template name of all node children
|
||||
$this->setTemplateName($this->source->getName());
|
||||
}
|
||||
|
||||
public function setIndex($index)
|
||||
|
@ -28,11 +66,6 @@ class Twig_Node_Module extends Twig_Node
|
|||
$this->setAttribute('index', $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$this->compileTemplate($compiler);
|
||||
|
@ -50,17 +83,20 @@ class Twig_Node_Module extends Twig_Node
|
|||
|
||||
$this->compileClassHeader($compiler);
|
||||
|
||||
if (count($this->getNode('blocks')) || count($this->getNode('traits')) || null === $this->getNode('parent') || $this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
|
||||
if (
|
||||
count($this->getNode('blocks'))
|
||||
|| count($this->getNode('traits'))
|
||||
|| !$this->hasNode('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->compileDisplayHeader($compiler);
|
||||
|
||||
$this->compileDisplayBody($compiler);
|
||||
|
||||
$this->compileDisplayFooter($compiler);
|
||||
$this->compileDisplay($compiler);
|
||||
|
||||
$compiler->subcompile($this->getNode('blocks'));
|
||||
|
||||
|
@ -72,28 +108,38 @@ class Twig_Node_Module extends Twig_Node
|
|||
|
||||
$this->compileDebugInfo($compiler);
|
||||
|
||||
$this->compileGetSource($compiler);
|
||||
|
||||
$this->compileGetSourceContext($compiler);
|
||||
|
||||
$this->compileClassFooter($compiler);
|
||||
}
|
||||
|
||||
protected function compileGetParent(Twig_Compiler $compiler)
|
||||
{
|
||||
if (null === $this->getNode('parent')) {
|
||||
if (!$this->hasNode('parent')) {
|
||||
return;
|
||||
}
|
||||
$parent = $this->getNode('parent');
|
||||
|
||||
$compiler
|
||||
->write("protected function doGetParent(array \$context)\n", "{\n")
|
||||
->indent()
|
||||
->write("return ")
|
||||
->addDebugInfo($parent)
|
||||
->write('return ')
|
||||
;
|
||||
|
||||
if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
|
||||
$compiler->subcompile($this->getNode('parent'));
|
||||
if ($parent instanceof Twig_Node_Expression_Constant) {
|
||||
$compiler->subcompile($parent);
|
||||
} else {
|
||||
$compiler
|
||||
->raw("\$this->env->resolveTemplate(")
|
||||
->subcompile($this->getNode('parent'))
|
||||
->raw(")")
|
||||
->raw('$this->loadTemplate(')
|
||||
->subcompile($parent)
|
||||
->raw(', ')
|
||||
->repr($this->source->getName())
|
||||
->raw(', ')
|
||||
->repr($parent->getTemplateLine())
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -104,27 +150,13 @@ class Twig_Node_Module extends Twig_Node
|
|||
;
|
||||
}
|
||||
|
||||
protected function compileDisplayBody(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->subcompile($this->getNode('body'));
|
||||
|
||||
if (null !== $this->getNode('parent')) {
|
||||
if ($this->getNode('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");
|
||||
}
|
||||
}
|
||||
|
||||
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')))
|
||||
// if the template name contains */, add a blank to avoid a PHP parse error
|
||||
->write('/* '.str_replace('*/', '* /', $this->source->getName())." */\n")
|
||||
->write('class '.$compiler->getEnvironment()->getTemplateClass($this->source->getName(), $this->getAttribute('index')))
|
||||
->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
|
||||
->write("{\n")
|
||||
->indent()
|
||||
|
@ -136,17 +168,23 @@ class Twig_Node_Module extends Twig_Node
|
|||
$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 === $this->getNode('parent')) {
|
||||
if (!$this->hasNode('parent')) {
|
||||
$compiler->write("\$this->parent = false;\n\n");
|
||||
} elseif ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
|
||||
} elseif (($parent = $this->getNode('parent')) && $parent instanceof Twig_Node_Expression_Constant) {
|
||||
$compiler
|
||||
->write("\$this->parent = \$this->env->loadTemplate(")
|
||||
->subcompile($this->getNode('parent'))
|
||||
->raw(");\n\n")
|
||||
->addDebugInfo($parent)
|
||||
->write('$this->parent = $this->loadTemplate(')
|
||||
->subcompile($parent)
|
||||
->raw(', ')
|
||||
->repr($this->source->getName())
|
||||
->raw(', ')
|
||||
->repr($parent->getTemplateLine())
|
||||
->raw(");\n")
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -170,11 +208,23 @@ class Twig_Node_Module extends Twig_Node
|
|||
|
||||
foreach ($trait->getNode('targets') as $key => $value) {
|
||||
$compiler
|
||||
->write(sprintf("\$_trait_%s_blocks[", $i))
|
||||
->subcompile($value)
|
||||
->raw(sprintf("] = \$_trait_%s_blocks[", $i))
|
||||
->write(sprintf('if (!isset($_trait_%s_blocks[', $i))
|
||||
->string($key)
|
||||
->raw(sprintf("]; unset(\$_trait_%s_blocks[", $i))
|
||||
->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")
|
||||
;
|
||||
|
@ -187,9 +237,9 @@ class Twig_Node_Module extends Twig_Node
|
|||
->indent()
|
||||
;
|
||||
|
||||
for ($i = 0; $i < $countTraits; $i++) {
|
||||
for ($i = 0; $i < $countTraits; ++$i) {
|
||||
$compiler
|
||||
->write(sprintf("\$_trait_%s_blocks".($i == $countTraits - 1 ? '' : ',')."\n", $i))
|
||||
->write(sprintf('$_trait_%s_blocks'.($i == $countTraits - 1 ? '' : ',')."\n", $i))
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -233,57 +283,37 @@ class Twig_Node_Module extends Twig_Node
|
|||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->outdent()
|
||||
->write(");\n\n")
|
||||
;
|
||||
|
||||
// macro information
|
||||
$compiler
|
||||
->write("\$this->macros = array(\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
foreach ($this->getNode('macros') as $name => $node) {
|
||||
$compiler
|
||||
->addIndentation()->repr($name)->raw(" => array(\n")
|
||||
->indent()
|
||||
->write("'method' => ")->repr($node->getAttribute('method'))->raw(",\n")
|
||||
->write("'arguments' => array(\n")
|
||||
->indent()
|
||||
;
|
||||
foreach ($node->getNode('arguments') as $argument => $value) {
|
||||
$compiler->addIndentation()->repr($argument)->raw (' => ')->subcompile($value)->raw(",\n");
|
||||
}
|
||||
$compiler
|
||||
->outdent()
|
||||
->write("),\n")
|
||||
->outdent()
|
||||
->write("),\n")
|
||||
;
|
||||
}
|
||||
$compiler
|
||||
->outdent()
|
||||
->write(");\n")
|
||||
;
|
||||
|
||||
$compiler
|
||||
->outdent()
|
||||
->subcompile($this->getNode('constructor_end'))
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
protected function compileDisplayHeader(Twig_Compiler $compiler)
|
||||
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'))
|
||||
;
|
||||
}
|
||||
|
||||
protected function compileDisplayFooter(Twig_Compiler $compiler)
|
||||
{
|
||||
if ($this->hasNode('parent')) {
|
||||
$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")
|
||||
;
|
||||
|
@ -292,6 +322,7 @@ class Twig_Node_Module extends Twig_Node
|
|||
protected function compileClassFooter(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->subcompile($this->getNode('class_end'))
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
;
|
||||
|
@ -308,7 +339,7 @@ class Twig_Node_Module extends Twig_Node
|
|||
->write("public function getTemplateName()\n", "{\n")
|
||||
->indent()
|
||||
->write('return ')
|
||||
->repr($this->getAttribute('filename'))
|
||||
->repr($this->source->getName())
|
||||
->raw(";\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
|
@ -324,7 +355,7 @@ class Twig_Node_Module extends Twig_Node
|
|||
//
|
||||
// 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'));
|
||||
$traitable = !$this->hasNode('parent') && 0 === count($this->getNode('macros'));
|
||||
if ($traitable) {
|
||||
if ($this->getNode('body') instanceof Twig_Node_Body) {
|
||||
$nodes = $this->getNode('body')->getNode(0);
|
||||
|
@ -374,6 +405,37 @@ class Twig_Node_Module extends Twig_Node
|
|||
->indent()
|
||||
->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true))))
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
protected function compileGetSource(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write("/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */\n")
|
||||
->write("public function getSource()\n", "{\n")
|
||||
->indent()
|
||||
->write("@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);\n\n")
|
||||
->write('return $this->getSourceContext()->getCode();')
|
||||
->raw("\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
protected function compileGetSourceContext(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write("public function getSourceContext()\n", "{\n")
|
||||
->indent()
|
||||
->write('return new Twig_Source(')
|
||||
->string($compiler->getEnvironment()->isDebug() ? $this->source->getCode() : '')
|
||||
->raw(', ')
|
||||
->string($this->source->getName())
|
||||
->raw(', ')
|
||||
->string($this->source->getPath())
|
||||
->raw(");\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
;
|
||||
}
|
||||
|
@ -382,22 +444,18 @@ class Twig_Node_Module extends Twig_Node
|
|||
{
|
||||
if ($node instanceof Twig_Node_Expression_Constant) {
|
||||
$compiler
|
||||
->write(sprintf("%s = \$this->env->loadTemplate(", $var))
|
||||
->write(sprintf('%s = $this->loadTemplate(', $var))
|
||||
->subcompile($node)
|
||||
->raw(', ')
|
||||
->repr($node->getTemplateName())
|
||||
->raw(', ')
|
||||
->repr($node->getTemplateLine())
|
||||
->raw(");\n")
|
||||
;
|
||||
} else {
|
||||
$compiler
|
||||
->write(sprintf("%s = ", $var))
|
||||
->subcompile($node)
|
||||
->raw(";\n")
|
||||
->write(sprintf("if (!%s", $var))
|
||||
->raw(" instanceof Twig_Template) {\n")
|
||||
->indent()
|
||||
->write(sprintf("%s = \$this->env->loadTemplate(%s);\n", $var, $var))
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
;
|
||||
throw new LogicException('Trait templates can only be constant nodes.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Module', 'Twig\Node\ModuleNode', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -22,11 +22,6 @@ class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface
|
|||
parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -37,3 +32,5 @@ class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Print', 'Twig\Node\PrintNode', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -21,16 +21,11 @@ class Twig_Node_Sandbox extends Twig_Node
|
|||
parent::__construct(array('body' => $body), array(), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write("\$sandbox = \$this->env->getExtension('sandbox');\n")
|
||||
->write("\$sandbox = \$this->env->getExtension('Twig_Extension_Sandbox');\n")
|
||||
->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n")
|
||||
->indent()
|
||||
->write("\$sandbox->enableSandbox();\n")
|
||||
|
@ -45,3 +40,5 @@ class Twig_Node_Sandbox extends Twig_Node
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Sandbox', 'Twig\Node\SandboxNode', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -21,21 +21,11 @@
|
|||
*/
|
||||
class Twig_Node_SandboxedPrint extends Twig_Node_Print
|
||||
{
|
||||
public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct($expr, $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('echo $this->env->getExtension(\'sandbox\')->ensureToStringAllowed(')
|
||||
->write('echo $this->env->getExtension(\'Twig_Extension_Sandbox\')->ensureToStringAllowed(')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(");\n")
|
||||
;
|
||||
|
@ -46,9 +36,9 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
|
|||
*
|
||||
* 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)
|
||||
protected function removeNodeFilter(Twig_Node $node)
|
||||
{
|
||||
if ($node instanceof Twig_Node_Expression_Filter) {
|
||||
return $this->removeNodeFilter($node->getNode('node'));
|
||||
|
@ -57,3 +47,5 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
|
|||
return $node;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_SandboxedPrint', 'Twig\Node\SandboxedPrintNode', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Set extends Twig_Node
|
||||
class Twig_Node_Set extends Twig_Node implements Twig_NodeCaptureInterface
|
||||
{
|
||||
public function __construct($capture, Twig_NodeInterface $names, Twig_NodeInterface $values, $lineno, $tag = null)
|
||||
{
|
||||
|
@ -30,17 +30,12 @@ class Twig_Node_Set extends Twig_Node
|
|||
|
||||
$values = $this->getNode('values');
|
||||
if ($values instanceof Twig_Node_Text) {
|
||||
$this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getLine()));
|
||||
$this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getTemplateLine()));
|
||||
$this->setAttribute('capture', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
|
@ -99,3 +94,5 @@ class Twig_Node_Set extends Twig_Node
|
|||
$compiler->raw(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Set', 'Twig\Node\SetNode', false);
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class Twig_Node_SetTemp extends Twig_Node
|
||||
{
|
||||
public function __construct($name, $lineno)
|
||||
|
@ -33,3 +36,5 @@ class Twig_Node_SetTemp extends Twig_Node
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_SetTemp', 'Twig\Node\SetTempNode', false);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -23,11 +23,6 @@ class Twig_Node_Spaceless extends Twig_Node
|
|||
parent::__construct(array('body' => $body), array(), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -38,3 +33,5 @@ class Twig_Node_Spaceless extends Twig_Node
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Spaceless', 'Twig\Node\SpacelessNode', false);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -22,11 +22,6 @@ class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface
|
|||
parent::__construct(array(), array('data' => $data), $lineno);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@ -37,3 +32,5 @@ class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_Text', 'Twig\Node\TextNode', false);
|
||||
|
|
64
inc/lib/Twig/Node/With.php
Normal file
64
inc/lib/Twig/Node/With.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a nested "with" scope.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_With extends Twig_Node
|
||||
{
|
||||
public function __construct(Twig_Node $body, Twig_Node $variables = null, $only = false, $lineno, $tag = null)
|
||||
{
|
||||
$nodes = array('body' => $body);
|
||||
if (null !== $variables) {
|
||||
$nodes['variables'] = $variables;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, array('only' => (bool) $only), $lineno, $tag);
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
|
||||
if ($this->hasNode('variables')) {
|
||||
$varsName = $compiler->getVarName();
|
||||
$compiler
|
||||
->write(sprintf('$%s = ', $varsName))
|
||||
->subcompile($this->getNode('variables'))
|
||||
->raw(";\n")
|
||||
->write(sprintf("if (!is_array(\$%s)) {\n", $varsName))
|
||||
->indent()
|
||||
->write("throw new Twig_Error_Runtime('Variables passed to the \"with\" tag must be a hash.');\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
;
|
||||
|
||||
if ($this->getAttribute('only')) {
|
||||
$compiler->write("\$context = array('_parent' => \$context);\n");
|
||||
} else {
|
||||
$compiler->write("\$context['_parent'] = \$context;\n");
|
||||
}
|
||||
|
||||
$compiler->write(sprintf("\$context = array_merge(\$context, \$%s);\n", $varsName));
|
||||
} else {
|
||||
$compiler->write("\$context['_parent'] = \$context;\n");
|
||||
}
|
||||
|
||||
$compiler
|
||||
->subcompile($this->getNode('body'))
|
||||
->write("\$context = \$context['_parent'];\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig_Node_With', 'Twig\Node\WithNode', false);
|
Loading…
Add table
Add a link
Reference in a new issue