diff --git a/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php b/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php index 26b456145c1c3..7dd43a58a3ecd 100644 --- a/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php +++ b/src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php @@ -29,8 +29,6 @@ class BinaryNode extends Node private static $functions = array( '**' => 'pow', '..' => 'range', - 'in' => 'in_array', - 'not in' => '!in_array', ); public function __construct(string $operator, Node $left, Node $right) @@ -57,6 +55,28 @@ public function compile(Compiler $compiler) return; } + switch ($operator) { + case 'not in': + $compiler->raw('!'); + // no break + case 'in': + $compiler + ->raw('in_array(') + ->compile($this->nodes['left']) + ->raw(', ') + ->raw('is_array(') + ->compile($this->nodes['right']) + ->raw(') ? ') + ->compile($this->nodes['right']) + ->raw(' : iterator_to_array(') + ->compile($this->nodes['right']) + ->raw(')') + ->raw(')') + ; + + return; + } + if (isset(self::$functions[$operator])) { $compiler ->raw(sprintf('%s(', self::$functions[$operator])) @@ -92,9 +112,6 @@ public function evaluate($functions, $values) if (isset(self::$functions[$operator])) { $right = $this->nodes['right']->evaluate($functions, $values); - if ('not in' === $operator) { - return !in_array($left, $right); - } $f = self::$functions[$operator]; return $f($left, $right); @@ -135,9 +152,9 @@ public function evaluate($functions, $values) case '<=': return $left <= $right; case 'not in': - return !in_array($left, $right); + return !in_array($left, is_array($right) ? $right : iterator_to_array($right)); case 'in': - return in_array($left, $right); + return in_array($left, is_array($right) ? $right : iterator_to_array($right)); case '+': return $left + $right; case '-': diff --git a/src/Symfony/Component/ExpressionLanguage/Tests/Fixtures/Collection.php b/src/Symfony/Component/ExpressionLanguage/Tests/Fixtures/Collection.php new file mode 100644 index 0000000000000..7d0d9b218726c --- /dev/null +++ b/src/Symfony/Component/ExpressionLanguage/Tests/Fixtures/Collection.php @@ -0,0 +1,11 @@ +addElement(new ConstantNode('a')); $array->addElement(new ConstantNode('b')); + $collectionValues = array('collection' => new Collection()); + return array( array(true, new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))), array(true, new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))), @@ -56,9 +60,13 @@ public function getEvaluateData() array('ab', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))), array(true, new BinaryNode('in', new ConstantNode('a'), $array)), + array(true, new BinaryNode('in', new ConstantNode('a'), new NameNode('collection')), $collectionValues), array(false, new BinaryNode('in', new ConstantNode('c'), $array)), + array(false, new BinaryNode('in', new ConstantNode('c'), new NameNode('collection')), $collectionValues), array(true, new BinaryNode('not in', new ConstantNode('c'), $array)), + array(true, new BinaryNode('not in', new ConstantNode('c'), new NameNode('collection')), $collectionValues), array(false, new BinaryNode('not in', new ConstantNode('a'), $array)), + array(false, new BinaryNode('not in', new ConstantNode('a'), new NameNode('collection')), $collectionValues), array(array(1, 2, 3), new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))), @@ -104,10 +112,10 @@ public function getCompileData() array('pow(5, 2)', new BinaryNode('**', new ConstantNode(5), new ConstantNode(2))), array('("a" . "b")', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))), - array('in_array("a", array(0 => "a", 1 => "b"))', new BinaryNode('in', new ConstantNode('a'), $array)), - array('in_array("c", array(0 => "a", 1 => "b"))', new BinaryNode('in', new ConstantNode('c'), $array)), - array('!in_array("c", array(0 => "a", 1 => "b"))', new BinaryNode('not in', new ConstantNode('c'), $array)), - array('!in_array("a", array(0 => "a", 1 => "b"))', new BinaryNode('not in', new ConstantNode('a'), $array)), + array('in_array("a", is_array(array(0 => "a", 1 => "b")) ? array(0 => "a", 1 => "b") : iterator_to_array(array(0 => "a", 1 => "b")))', new BinaryNode('in', new ConstantNode('a'), $array)), + array('in_array("c", is_array(array(0 => "a", 1 => "b")) ? array(0 => "a", 1 => "b") : iterator_to_array(array(0 => "a", 1 => "b")))', new BinaryNode('in', new ConstantNode('c'), $array)), + array('!in_array("c", is_array(array(0 => "a", 1 => "b")) ? array(0 => "a", 1 => "b") : iterator_to_array(array(0 => "a", 1 => "b")))', new BinaryNode('not in', new ConstantNode('c'), $array)), + array('!in_array("a", is_array(array(0 => "a", 1 => "b")) ? array(0 => "a", 1 => "b") : iterator_to_array(array(0 => "a", 1 => "b")))', new BinaryNode('not in', new ConstantNode('a'), $array)), array('range(1, 3)', new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))),