$end = $this->parseExpression();
- $filters = new Twig_Node(array(new Twig_Node_Expression_Constant('range', $lineno), new Twig_Node(array($end))));
+ $name = new Twig_Node_Expression_Constant('range', $lineno);
+ $arguments = new Twig_Node(array($end));
- return new Twig_Node_Expression_Filter($node, $filters, $lineno);
+ return new Twig_Node_Expression_Filter($node, $name, $arguments, $lineno);
}
public function parseSubscriptExpression($node)
public function parseFilterExpression($node)
{
- $lineno = $this->parser->getCurrentToken()->getLine();
-
$this->parser->getStream()->next();
- return new Twig_Node_Expression_Filter($node, $this->parseFilterExpressionRaw(), $lineno);
+ return $this->parseFilterExpressionRaw($node);
}
- public function parseFilterExpressionRaw()
+ public function parseFilterExpressionRaw($node, $tag = null)
{
- $filters = array();
+ $lineno = $this->parser->getCurrentToken()->getLine();
+
while (true) {
$token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE);
- $filters[] = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
+ $name = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
if (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '(')) {
- $filters[] = new Twig_Node();
+ $arguments = new Twig_Node();
} else {
- $filters[] = $this->parseArguments();
+ $arguments = $this->parseArguments();
}
+ $node = new Twig_Node_Expression_Filter($node, $name, $arguments, $token->getLine(), $tag);
+
if (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '|')) {
break;
}
$this->parser->getStream()->next();
}
- return new Twig_Node($filters);
+ return $node;
}
public function parseArguments()
*/
class Twig_Node_Expression_Filter extends Twig_Node_Expression
{
- public function __construct(Twig_NodeInterface $node, Twig_NodeInterface $filters, $lineno, $tag = null)
+ public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filter_name, Twig_NodeInterface $arguments, $lineno, $tag = null)
{
- parent::__construct(array('node' => $node, 'filters' => $filters), array(), $lineno, $tag);
+ parent::__construct(array('node' => $node, 'filter' => $filter_name, 'arguments' => $arguments), array(), $lineno, $tag);
}
public function compile($compiler)
{
$filterMap = $compiler->getEnvironment()->getFilters();
- $postponed = array();
- for ($i = count($this->getNode('filters')) - 1; $i >= 0; $i -= 2) {
- $name = $this->getNode('filters')->getNode($i - 1)->getAttribute('value');
- $attrs = $this->getNode('filters')->getNode($i);
- if (!isset($filterMap[$name])) {
- throw new Twig_Error_Syntax(sprintf('The filter "%s" does not exist', $name), $this->getLine());
- } else {
- $compiler->raw($filterMap[$name]->compile().($filterMap[$name]->needsEnvironment() ? '($this->env, ' : '('));
- }
- $postponed[] = $attrs;
+ $name = $this->getNode('filter')->getAttribute('value');
+ $attrs = $this->getNode('arguments');
+
+ if (!isset($filterMap[$name])) {
+ throw new Twig_Error_Syntax(sprintf('The filter "%s" does not exist', $name), $this->getLine());
+ } else {
+ $compiler->raw($filterMap[$name]->compile().($filterMap[$name]->needsEnvironment() ? '($this->env, ' : '('));
}
$this->getNode('node')->compile($compiler);
- foreach (array_reverse($postponed) as $attributes) {
- foreach ($attributes as $node) {
- $compiler
- ->raw(', ')
- ->subcompile($node)
+ foreach ($attrs as $node) {
+ $compiler
+ ->raw(', ')
+ ->subcompile($node)
;
- }
- $compiler->raw(')');
- }
- }
-
- public function prependFilter(Twig_Node_Expression_Constant $name, Twig_Node $end)
- {
- $filters = array($name, $end);
- foreach ($this->getNode('filters') as $node) {
- $filters[] = $node;
- }
-
- $this->setNode('filters', new Twig_Node($filters, array(), $this->getNode('filters')->getLine()));
- }
-
- public function appendFilter(Twig_Node_Expression_Constant $name, Twig_Node $end)
- {
- $filters = array();
- foreach ($this->getNode('filters') as $node) {
- $filters[] = $node;
- }
-
- $filters[] = $name;
- $filters[] = $end;
-
- $this->setNode('filters', new Twig_Node($filters, array(), $this->getNode('filters')->getLine()));
- }
-
- public function appendFilters(Twig_NodeInterface $filters)
- {
- for ($i = 0; $i < count($filters); $i += 2) {
- $this->appendFilter($filters->getNode($i), $filters->getNode($i + 1));
- }
- }
-
- public function hasFilter($name)
- {
- for ($i = 0; $i < count($this->getNode('filters')); $i += 2) {
- if ($name == $this->getNode('filters')->getNode($i)->getAttribute('value')) {
- return true;
- }
}
- return false;
+ $compiler->raw(')');
}
}
return $node;
}
- // escape
- if ($expression instanceof Twig_Node_Expression_Filter) {
- $filter = $this->getEscaperFilter($type, $expression->getLine());
- $expression->appendFilter($filter[0], $filter[1]);
-
- return $node;
- }
-
if ($node instanceof Twig_Node_Print) {
return new Twig_Node_Print(
- new Twig_Node_Expression_Filter($expression, new Twig_Node($this->getEscaperFilter($type, $node->getLine())), $node->getLine()),
+ $this->getEscaperFilter($type, $expression),
$node->getLine()
);
}
- return new Twig_Node_Expression_Filter($node, new Twig_Node($this->getEscaperFilter($type, $node->getLine())), $node->getLine());
+ return $this->getEscaperFilter($type, $node);
}
protected function needEscaping(Twig_Environment $env)
return false;
}
- protected function getEscaperFilter($type, $line)
+ protected function getEscaperFilter($type, Twig_NodeInterface $node)
{
- return array(new Twig_Node_Expression_Constant('escape', $line), new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line))));
+ $line = $node->getLine();
+ $name = new Twig_Node_Expression_Constant('escape', $line);
+ $args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line)));
+ return new Twig_Node_Expression_Filter($node, $name, $args, $line);
}
}
$safe = $this->intersectSafe($this->getSafe($node->getNode('expr2')), $this->getSafe($node->getNode('expr3')));
$this->setSafe($node, $safe);
} elseif ($node instanceof Twig_Node_Expression_Filter) {
- // filter expression is safe when the last filter is safe
+ // filter expression is safe when the filter is safe
$filterMap = $env->getFilters();
- $filters = $node->getNode('filters');
- $i = count($filters) - 2;
- $name = $filters->getNode($i)->getAttribute('value');
- $args = $filters->getNode($i+1);
+ $name = $node->getNode('filter')->getAttribute('value');
+ $args = $node->getNode('arguments');
if (isset($filterMap[$name])) {
$this->setSafe($node, $filterMap[$name]->getSafe($args));
} else {
// look for filters
if ($node instanceof Twig_Node_Expression_Filter) {
- for ($i = 0; $i < count($node->getNode('filters')); $i += 2) {
- $this->filters[] = $node->getNode('filters')->getNode($i)->getAttribute('value');
- }
+ $this->filters[] = $node->getNode('filter')->getAttribute('value');
}
// look for simple print statements ({{ article }})
{
return new Twig_Node_Expression_Filter(
$node,
- new Twig_Node(array(new Twig_Node_Expression_Constant('raw', $line), new Twig_Node())),
+ new Twig_Node_Expression_Constant('raw', $line),
+ new Twig_Node(),
$line
);
}
*/
public function parse(Twig_Token $token)
{
- $filters = $this->parser->getExpressionParser()->parseFilterExpressionRaw();
+ $name = '_tmp'.rand(10000, 99999);
+ $node = new Twig_Node_Expression_Name($name, $token->getLine());
+
+ $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($node, $this->getTag());
$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
$body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- $name = '_tmp'.rand(10000, 99999);
$ref = new Twig_Node_BlockReference($name, $token->getLine(), $this->getTag());
$block = new Twig_Node_Block($name, $body, $token->getLine());
$this->parser->setBlock($name, $block);
$set = new Twig_Node_Set(true, new Twig_Node(array(new Twig_Node_Expression_AssignName($name, $token->getLine()))), new Twig_Node(array($ref)), $token->getLine(), $this->getTag());
- $filter = new Twig_Node_Expression_Filter(new Twig_Node_Expression_Name($name, $token->getLine()), $filters, $token->getLine(), $this->getTag());
$filter = new Twig_Node_Print($filter, $token->getLine(), $this->getTag());
return new Twig_Node(array($set, $filter));
public function testConstructor()
{
$expr = new Twig_Node_Expression_Constant('foo', 0);
- $filters = new Twig_Node(array(
- new Twig_Node_Expression_Constant('upper', 0),
- new Twig_Node(),
- ), array(), 0);
- $node = new Twig_Node_Expression_Filter($expr, $filters, 0);
+ $name = new Twig_Node_Expression_Constant('upper', 0);
+ $args = new Twig_Node();
+ $node = new Twig_Node_Expression_Filter($expr, $name, $args, 0);
$this->assertEquals($expr, $node->getNode('node'));
- $this->assertEquals($filters, $node->getNode('filters'));
- }
-
- /**
- * @covers Twig_Node_Expression_Filter::hasFilter
- */
- public function testHasFilter()
- {
- $expr = new Twig_Node_Expression_Constant('foo', 0);
- $filters = new Twig_Node(array(
- new Twig_Node_Expression_Constant('upper', 0),
- new Twig_Node(),
- ), array(), 0);
- $node = new Twig_Node_Expression_Filter($expr, $filters, 0);
-
- $this->assertTrue($node->hasFilter('upper'));
- $this->assertFalse($node->hasFilter('lower'));
- }
-
- /**
- * @covers Twig_Node_Expression_Filter::prependFilter
- */
- public function testPrependFilter()
- {
- $expr = new Twig_Node_Expression_Constant('foo', 0);
- $filters = new Twig_Node(array(
- new Twig_Node_Expression_Constant('upper', 0),
- new Twig_Node(),
- ), array(), 0);
- $node = new Twig_Node_Expression_Filter($expr, $filters, 0);
-
- $a = new Twig_Node_Expression_Constant('lower', 0);
- $b = new Twig_Node_Expression_Constant('foobar', 0);
- $node->prependFilter($a, $b);
-
- $filters = new Twig_Node(array(
- $a,
- $b,
- new Twig_Node_Expression_Constant('upper', 0),
- new Twig_Node(),
- ), array(), 0);
-
- $this->assertEquals($filters, $node->getNode('filters'));
- }
-
- /**
- * @covers Twig_Node_Expression_Filter::appendFilter
- */
- public function testAppendFilter()
- {
- $expr = new Twig_Node_Expression_Constant('foo', 0);
- $filters = new Twig_Node(array(
- new Twig_Node_Expression_Constant('upper', 0),
- new Twig_Node(),
- ), array(), 0);
- $node = new Twig_Node_Expression_Filter($expr, $filters, 0);
-
- $a = new Twig_Node_Expression_Constant('lower', 0);
- $b = new Twig_Node_Expression_Constant('foobar', 0);
- $node->appendFilter($a, $b);
-
- $filters = new Twig_Node(array(
- new Twig_Node_Expression_Constant('upper', 0),
- new Twig_Node(),
- $a,
- $b,
- ), array(), 0);
-
- $this->assertEquals($filters, $node->getNode('filters'));
- }
-
- /**
- * @covers Twig_Node_Expression_Filter::appendFilters
- */
- public function testAppendFilters()
- {
- $expr = new Twig_Node_Expression_Constant('foo', 0);
- $filters = new Twig_Node(array(
- new Twig_Node_Expression_Constant('upper', 0),
- new Twig_Node(),
- ), array(), 0);
- $node = new Twig_Node_Expression_Filter($expr, $filters, 0);
-
- $others = new Twig_Node(array(
- $a = new Twig_Node_Expression_Constant('lower', 0),
- $b = new Twig_Node_Expression_Constant('foobar', 0),
- ), array(), 0);
- $node->appendFilters($others);
-
- $filters = new Twig_Node(array(
- new Twig_Node_Expression_Constant('upper', 0),
- new Twig_Node(),
- $a,
- $b,
- ), array(), 0);
-
- $this->assertEquals($filters, $node->getNode('filters'));
+ $this->assertEquals($name, $node->getNode('filter'));
+ $this->assertEquals($args, $node->getNode('arguments'));
}
/**
parent::testCompile($node, $source, $environment);
$expr = new Twig_Node_Expression_Constant('foo', 0);
- $filters = new Twig_Node(array(
- new Twig_Node_Expression_Constant('foobar', 0),
- new Twig_Node(array(new Twig_Node_Expression_Constant('bar', 0), new Twig_Node_Expression_Constant('foobar', 0))),
- ), array(), 0);
- $node = new Twig_Node_Expression_Filter($expr, $filters, 0);
+ $node = $this->createFilter($expr, 'foobar', array(new Twig_Node_Expression_Constant('bar', 0), new Twig_Node_Expression_Constant('foobar', 0)));
$tests[] = array($node, '$this->resolveMissingFilter("foobar", array("foo", "bar", "foobar"))');
$tests = array();
$expr = new Twig_Node_Expression_Constant('foo', 0);
- $filters = new Twig_Node(array(
- new Twig_Node_Expression_Constant('upper', 0),
- new Twig_Node(),
- new Twig_Node_Expression_Constant('lower', 0),
- new Twig_Node(array(new Twig_Node_Expression_Constant('bar', 0), new Twig_Node_Expression_Constant('foobar', 0))),
- ), array(), 0);
- $node = new Twig_Node_Expression_Filter($expr, $filters, 0);
+ $node = $this->createFilter($expr, 'upper');
+ $node = $this->createFilter($node, 'lower', array(new Twig_Node_Expression_Constant('bar', 0), new Twig_Node_Expression_Constant('foobar', 0)));
if (function_exists('mb_get_info')) {
$tests[] = array($node, 'twig_lower_filter($this->env, twig_upper_filter($this->env, "foo"), "bar", "foobar")');
return $tests;
}
+
+ protected function createFilter($node, $name, array $arguments = array())
+ {
+ $name = new Twig_Node_Expression_Constant($name, 0);
+ $arguments = new Twig_Node($arguments);
+ return new Twig_Node_Expression_Filter($node, $name, $arguments, 0);
+ }
}
$tests[] = array($node, 'echo strtr(ngettext("Hey %name%, I have one apple", "Hey %name%, I have %count% apples", abs(12)), array("%name%" => (isset($context[\'name\']) ? $context[\'name\'] : null), "%name%" => (isset($context[\'name\']) ? $context[\'name\'] : null), "%count%" => abs(12), ));');
// with escaper extension set to on
- $filters = new Twig_Node(array(
- new Twig_Node_Expression_Constant('escape', 0),
- new Twig_Node(),
- ), array(), 0);
-
$body = new Twig_Node(array(
new Twig_Node_Text('J\'ai ', 0),
- new Twig_Node_Print(new Twig_Node_Expression_Filter(new Twig_Node_Expression_Name('foo', 0), $filters, 0), 0),
+ new Twig_Node_Print(new Twig_Node_Expression_Filter(new Twig_Node_Expression_Name('foo', 0), new Twig_Node_Expression_Constant('escape', 0), new Twig_Node(), 0), 0),
new Twig_Node_Text(' pommes', 0),
), array(), 0);