mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-14 11:27:00 +00:00
made operators configurable
This commit is contained in:
@@ -30,6 +30,8 @@ class Twig_Environment
|
||||
protected $runtimeInitialized;
|
||||
protected $loadedTemplates;
|
||||
protected $strictVariables;
|
||||
protected $unaryOperators;
|
||||
protected $binaryOperators;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -414,6 +416,44 @@ class Twig_Environment
|
||||
return $this->tests;
|
||||
}
|
||||
|
||||
public function getUnaryOperators()
|
||||
{
|
||||
if (null === $this->unaryOperators) {
|
||||
$this->initOperators();
|
||||
}
|
||||
|
||||
return $this->unaryOperators;
|
||||
}
|
||||
|
||||
public function getBinaryOperators()
|
||||
{
|
||||
if (null === $this->binaryOperators) {
|
||||
$this->initOperators();
|
||||
}
|
||||
|
||||
return $this->binaryOperators;
|
||||
}
|
||||
|
||||
protected function initOperators()
|
||||
{
|
||||
$this->unaryOperators = array();
|
||||
$this->binaryOperators = array();
|
||||
foreach ($this->getExtensions() as $extension) {
|
||||
$operators = $extension->getOperators();
|
||||
|
||||
if (!$operators) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (2 !== count($operators)) {
|
||||
throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension)));
|
||||
}
|
||||
|
||||
$this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
|
||||
$this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function writeCacheFile($file, $content)
|
||||
{
|
||||
$tmpFile = tempnam(dirname($file), basename($file));
|
||||
|
||||
@@ -30,47 +30,11 @@ class Twig_ExpressionParser
|
||||
protected $unaryOperators;
|
||||
protected $binaryOperators;
|
||||
|
||||
public function __construct(Twig_Parser $parser)
|
||||
public function __construct(Twig_Parser $parser, array $unaryOperators, array $binaryOperators)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
$this->unaryOperators = $this->getUnaryOperators();
|
||||
$this->binaryOperators = $this->getBinaryOperators();
|
||||
}
|
||||
|
||||
public function getUnaryOperators()
|
||||
{
|
||||
return array(
|
||||
'not' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'),
|
||||
'-' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Neg'),
|
||||
'+' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Pos'),
|
||||
);
|
||||
}
|
||||
|
||||
public function getBinaryOperators()
|
||||
{
|
||||
return array(
|
||||
'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => self::OPERATOR_LEFT),
|
||||
'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => self::OPERATOR_LEFT),
|
||||
'==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => self::OPERATOR_LEFT),
|
||||
'!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => self::OPERATOR_LEFT),
|
||||
'<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => self::OPERATOR_LEFT),
|
||||
'>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => self::OPERATOR_LEFT),
|
||||
'>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => self::OPERATOR_LEFT),
|
||||
'<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => self::OPERATOR_LEFT),
|
||||
'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => self::OPERATOR_LEFT),
|
||||
'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => self::OPERATOR_LEFT),
|
||||
'+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => self::OPERATOR_LEFT),
|
||||
'-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => self::OPERATOR_LEFT),
|
||||
'~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => self::OPERATOR_LEFT),
|
||||
'*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => self::OPERATOR_LEFT),
|
||||
'/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => self::OPERATOR_LEFT),
|
||||
'//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => self::OPERATOR_LEFT),
|
||||
'%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => self::OPERATOR_LEFT),
|
||||
'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => self::OPERATOR_LEFT),
|
||||
'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => self::OPERATOR_LEFT),
|
||||
'..' => array('precedence' => 110, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => self::OPERATOR_LEFT),
|
||||
'**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => self::OPERATOR_RIGHT),
|
||||
);
|
||||
$this->unaryOperators = $unaryOperators;
|
||||
$this->binaryOperators = $binaryOperators;
|
||||
}
|
||||
|
||||
public function parseExpression($precedence = 0)
|
||||
@@ -82,7 +46,7 @@ class Twig_ExpressionParser
|
||||
$this->parser->getStream()->next();
|
||||
|
||||
if (isset($op['callable'])) {
|
||||
$expr = call_user_func($op['callable'], $expr);
|
||||
$expr = call_user_func($op['callable'], $this->parser, $expr);
|
||||
} else {
|
||||
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
|
||||
$class = $op['class'];
|
||||
@@ -250,23 +214,6 @@ class Twig_ExpressionParser
|
||||
return $node;
|
||||
}
|
||||
|
||||
public function parseNotTestExpression($node)
|
||||
{
|
||||
return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
|
||||
}
|
||||
|
||||
public function parseTestExpression($node)
|
||||
{
|
||||
$stream = $this->parser->getStream();
|
||||
$name = $stream->expect(Twig_Token::NAME_TYPE);
|
||||
$arguments = null;
|
||||
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
|
||||
$arguments = $this->parseArguments($node);
|
||||
}
|
||||
|
||||
return new Twig_Node_Expression_Test($node, $name->getValue(), $arguments, $this->parser->getCurrentToken()->getLine());
|
||||
}
|
||||
|
||||
public function parseSubscriptExpression($node)
|
||||
{
|
||||
$token = $this->parser->getStream()->next();
|
||||
|
||||
@@ -60,4 +60,14 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of operators to add to the existing list.
|
||||
*
|
||||
* @return array An array of operators
|
||||
*/
|
||||
public function getOperators()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +102,62 @@ class Twig_Extension_Core extends Twig_Extension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of operators to add to the existing list.
|
||||
*
|
||||
* @return array An array of operators
|
||||
*/
|
||||
public function getOperators()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'not' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'),
|
||||
'-' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Neg'),
|
||||
'+' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Pos'),
|
||||
),
|
||||
array(
|
||||
'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'..' => array('precedence' => 110, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||
'**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function parseNotTestExpression($parser, $node)
|
||||
{
|
||||
return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine());
|
||||
}
|
||||
|
||||
public function parseTestExpression($parser, $node)
|
||||
{
|
||||
$stream = $parser->getStream();
|
||||
$name = $stream->expect(Twig_Token::NAME_TYPE);
|
||||
$arguments = null;
|
||||
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
|
||||
$arguments = $parser->getExpressionParser()->parseArguments($node);
|
||||
}
|
||||
|
||||
return new Twig_Node_Expression_Test($node, $name->getValue(), $arguments, $parser->getCurrentToken()->getLine());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the extension.
|
||||
*
|
||||
|
||||
@@ -54,6 +54,13 @@ interface Twig_ExtensionInterface
|
||||
*/
|
||||
public function getTests();
|
||||
|
||||
/**
|
||||
* Returns a list of operators to add to the existing list.
|
||||
*
|
||||
* @return array An array of operators
|
||||
*/
|
||||
public function getOperators();
|
||||
|
||||
/**
|
||||
* Returns the name of the extension.
|
||||
*
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ class Twig_Parser implements Twig_ParserInterface
|
||||
$this->visitors = $this->env->getNodeVisitors();
|
||||
|
||||
if (null === $this->expressionParser) {
|
||||
$this->expressionParser = new Twig_ExpressionParser($this);
|
||||
$this->expressionParser = new Twig_ExpressionParser($this, $this->env->getUnaryOperators(), $this->env->getBinaryOperators());
|
||||
}
|
||||
|
||||
$this->stream = $stream;
|
||||
|
||||
Reference in New Issue
Block a user