8000 [ExpressionLanguage] Make `in` and `not in` handle Traversables · symfony/symfony@c26549d · GitHub
[go: up one dir, main page]

Skip to content

Commit c26549d

Browse files
committed
[ExpressionLanguage] Make in and not in handle Traversables
1 parent b286950 commit c26549d

File tree

3 files changed

+48
-12
lines changed

3 files changed

+48
-12
lines changed

src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ class BinaryNode extends Node
2929
private static $functions = array(
3030
'**' => 'pow',
3131
'..' => 'range',
32-
'in' => 'in_array',
33-
'not in' => '!in_array',
3432
);
3533

3634
public function __construct(string $operator, Node $left, Node $right)
@@ -57,6 +55,28 @@ public function compile(Compiler $compiler)
5755
return;
5856
}
5957

58+
switch ($operator) {
59+
case 'not in':
60+
$compiler->raw('!');
61+
// no break
62+
case 'in':
63+
$compiler
64+
->raw('in_array(')
65+
->compile($this->nodes['left'])
66+
->raw(', ')
67+
->raw('is_array(')
68+
->compile($this->nodes['right'])
69+
->raw(') ? ')
70+
->compile($this->nodes['right'])
71+
->raw(' : iterator_to_array(')
72+
->compile($this->nodes['right'])
73+
->raw(')')
74+
->raw(')')
75+
;
76+
77+
return;
78+
}
79+
6080
if (isset(self::$functions[$operator])) {
6181
$compiler
6282
->raw(sprintf('%s(', self::$functions[$operator]))
@@ -92,9 +112,6 @@ public function evaluate($functions, $values)
92112
if (isset(self::$functions[$operator])) {
93113
$right = $this->nodes['right']->evaluate($functions, $values);
94114

95-
if ('not in' === $operator) {
96-
return !in_array($left, $right);
97-
}
98115
$f = self::$functions[$operator];
99116

100117
return $f($left, $right);
@@ -135,9 +152,9 @@ public function evaluate($functions, $values)
135152
case '<=':
136153
return $left <= $right;
137154
case 'not in':
138-
return !in_array($left, $right);
155+
return !in_array($left, is_array($right) ? $right : iterator_to_array($right));
139156
case 'in':
140-
return in_array($left, $right);
157+
return in_array($left, is_array($right) ? $right : iterator_to_array($right));
141158
case '+':
142159
return $left + $right;
143160
case '-':
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symfony\Component\ExpressionLanguage\Tests\Fixtures;
4+
5+
class Collection implements \IteratorAggregate
6+
{
7+
public function getIterator()
8+
{
9+
return new \ArrayIterator(array('a', 'b'));
10+
}
11+
}

src/Symfony/Component/ExpressionLanguage/Tests/Node/BinaryNodeTest.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111

1212
namespace Symfony\Component\ExpressionLanguage\Tests\Node;
1313

14-
use Symfony\Component\ExpressionLanguage\Node\BinaryNode;
1514
use Symfony\Component\ExpressionLanguage\Node\ArrayNode;
15+
use Symfony\Component\ExpressionLanguage\Node\BinaryNode;
1616
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;
17+
use Symfony\Component\ExpressionLanguage\Node\NameNode;
18+
use Symfony\Component\ExpressionLanguage\Tests\Fixtures\Collection;
1719

1820
class BinaryNodeTest extends AbstractNodeTest
1921
{
@@ -23,6 +25,8 @@ public function getEvaluateData()
2325
$array->addElement(new ConstantNode('a'));
2426
$array->addElement(new ConstantNode('b'));
2527

28+
$collectionValues = array('collection' => new Collection());
29+
2630
return array(
2731
array(true, new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))),
2832
array(true, new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))),
@@ -56,9 +60,13 @@ public function getEvaluateData()
5660
array('ab', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))),
5761

5862
array(true, new BinaryNode('in', new ConstantNode('a'), $array)),
63+
array(true, new BinaryNode('in', new ConstantNode('a'), new NameNode('collection')), $collectionValues),
5964
array(false, new BinaryNode('in', new ConstantNode('c'), $array)),
65+
array(false, new BinaryNode('in', new ConstantNode('c'), new NameNode('collection')), $collectionValues),
6066
array(true, new BinaryNode('not in', new ConstantNode('c'), $array)),
67+
array(true, new BinaryNode('not in', new ConstantNode('c'), new NameNode('collection')), $collectionValues),
6168
array(false, new BinaryNode('not in', new ConstantNode('a'), $array)),
69+
array(false, new BinaryNode('not in', new ConstantNode('a'), new NameNode('collection')), $collectionValues),
6270

6371
array(array(1, 2, 3), new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))),
6472

@@ -104,10 +112,10 @@ public function getCompileData()
104112
array('pow(5, 2)', new BinaryNode('**', new ConstantNode(5), new ConstantNode(2))),
105113
array('("a" . "b")', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))),
106114

107-
array('in_array("a", array(0 => "a", 1 => "b"))', new BinaryNode('in', new ConstantNode('a'), $array)),
108-
array('in_array("c", array(0 => "a", 1 => "b"))', new BinaryNode('in', new ConstantNode('c'), $array)),
109-
array('!in_array("c", array(0 => "a", 1 => "b"))', new BinaryNode('not in', new ConstantNode('c'), $array)),
110-
array('!in_array("a", array(0 => "a", 1 => "b"))', new BinaryNode('not in', new ConstantNode('a'), $array)),
115+
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)),
116+
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)),
117+
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)),
118+
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)),
111119

112120
array('range(1, 3)', new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))),
113121

0 commit comments

Comments
 (0)
0