diff --git a/src/Enum/Relation.php b/src/Enum/Relation.php index b3fd844..f86cbf2 100644 --- a/src/Enum/Relation.php +++ b/src/Enum/Relation.php @@ -49,4 +49,14 @@ class Relation * "Contains" unary comparator */ const CONTAINS = 7; + + /** + * "In" unary comparator + */ + const IN = 8; + + /** + * "Not In" unary comparator + */ + const NOT_IN = 9; } diff --git a/src/IteratorFilter.php b/src/IteratorFilter.php index c1d172e..7092027 100644 --- a/src/IteratorFilter.php +++ b/src/IteratorFilter.php @@ -114,6 +114,14 @@ private function evalString(Row $singleRow) $result[$pos] = $result[$pos] && (strpos(is_null($valueparam) ? "" : $valueparam, $value) === 0); break; + case Relation::IN: + $result[$pos] = $result[$pos] && in_array($valueparam, $value); + break; + + case Relation::NOT_IN: + $result[$pos] = $result[$pos] && !in_array($valueparam, $value); + break; + default: // Relation::CONTAINS: $result[$pos] = $result[$pos] && (strpos(is_null($valueparam) ? "" : $valueparam, $value) !== false); break; @@ -129,7 +137,7 @@ private function evalString(Row $singleRow) /** * @param string $name Field name * @param int $relation Relation enum - * @param string $value Field string value + * @param string|array $value Field string value * @return IteratorFilter * @desc Add a single string comparison to filter. */ diff --git a/src/IteratorFilterFormatter.php b/src/IteratorFilterFormatter.php index 5f0572f..ccab474 100644 --- a/src/IteratorFilterFormatter.php +++ b/src/IteratorFilterFormatter.php @@ -10,7 +10,7 @@ abstract class IteratorFilterFormatter * * @param string $name * @param string $relation - * @param string $value + * @param string|array $value * @param array $param * @return string */ diff --git a/src/IteratorFilterXPathFormatter.php b/src/IteratorFilterXPathFormatter.php index b5c8553..c7c575b 100644 --- a/src/IteratorFilterXPathFormatter.php +++ b/src/IteratorFilterXPathFormatter.php @@ -28,7 +28,9 @@ public function getRelation($name, $relation, $value, &$param) { $str = is_numeric($value) ? "" : "'"; $field = "field[@name='" . $name . "'] "; - $value = " $str$value$str "; + if (is_string($value)) { + $value = " $str$value$str "; + } switch ($relation) { case Relation::EQUAL: @@ -59,6 +61,12 @@ public function getRelation($name, $relation, $value, &$param) $return = " starts-with($field, $value) "; break; + case Relation::IN: + throw new \InvalidArgumentException('XPath does not support IN'); + + case Relation::NOT_IN: + throw new \InvalidArgumentException('XPath does not support NOT IN'); + default: // Relation::CONTAINS: $return = " contains($field, $value) "; break; diff --git a/tests/IteratorFilterAnydatasetTest.php b/tests/IteratorFilterAnydatasetTest.php new file mode 100644 index 0000000..97e8447 --- /dev/null +++ b/tests/IteratorFilterAnydatasetTest.php @@ -0,0 +1,129 @@ +object = new IteratorFilter(); + } + + public function testMatch() + { + + $collection = [ + $row1 = new Row( + [ + 'id' => 1, + 'field' => 'value1', + 'field2' => 'value2', + 'val' => 50, + ] + ), + $row2 = new Row( + [ + 'id' => 2, + 'field' => 'other1', + 'field2' => 'other2', + 'val' => 80, + ] + ), + $row3 = new Row( + [ + 'id' => 3, + 'field' => 'last1', + 'field2' => 'last2', + 'val' => 30, + ] + ), + $row4 = new Row( + [ + 'id' => 4, + 'field' => 'xy', + 'field2' => 'zy', + 'val' => 10, + ] + ), + ]; + + $this->assertEquals($collection, $this->object->match($collection)); + + $this->object->addRelation('field2', Relation::EQUAL, 'other2'); + $this->assertEquals([$row2], $this->object->match($collection)); + + $this->object->addRelationOr('field', Relation::EQUAL, 'last1'); + $this->assertEquals([$row2, $row3], $this->object->match($collection)); + + + //------------------------ + + $this->object = new IteratorFilter(); + $this->object->addRelation('field', Relation::EQUAL, 'last1'); + $this->object->addRelation('field2', Relation::EQUAL, 'last2'); + $this->assertEquals([$row3], $this->object->match($collection)); + + // Test Greater Than + $this->object = new IteratorFilter(); + $this->object->addRelation('val', Relation::GREATER_THAN, 50); + $this->assertEquals([$row2], $this->object->match($collection)); + + // Test Less Than + $this->object = new IteratorFilter(); + $this->object->addRelation('val', Relation::LESS_THAN, 50); + $this->assertEquals([$row3, $row4], $this->object->match($collection)); + + // Test Greater or Equal Than + $this->object = new IteratorFilter(); + $this->object->addRelation('val', Relation::GREATER_OR_EQUAL_THAN, 50); + $this->assertEquals([$row1, $row2], $this->object->match($collection)); + + // Test Less or Equal Than + $this->object = new IteratorFilter(); + $this->object->addRelation('val', Relation::LESS_OR_EQUAL_THAN, 50); + $this->assertEquals([$row1, $row3, $row4], $this->object->match($collection)); + + // Test Not Equal + $this->object = new IteratorFilter(); + $this->object->addRelation('val', Relation::NOT_EQUAL, 50); + $this->assertEquals([$row2, $row3, $row4], $this->object->match($collection)); + + // Test Starts With + $this->object = new IteratorFilter(); + $this->object->addRelation('field', Relation::STARTS_WITH, 'la'); + $this->assertEquals([$row3], $this->object->match($collection)); + + // Test Contains + $this->object = new IteratorFilter(); + $this->object->addRelation('field', Relation::CONTAINS, '1'); + $this->assertEquals([$row1, $row2, $row3], $this->object->match($collection)); + + // Test In + $this->object = new IteratorFilter(); + $this->object->addRelation('val', Relation::IN, [10, 30, 50]); + $this->assertEquals([$row1, $row3, $row4], $this->object->match($collection)); + + // Test Not In + $this->object = new IteratorFilter(); + $this->object->addRelation('val', Relation::NOT_IN, [10, 30, 50]); + $this->assertEquals([$row2], $this->object->match($collection)); + } + + +} diff --git a/tests/IteratorFilterTest.php b/tests/IteratorFilterXPathTest.php similarity index 67% rename from tests/IteratorFilterTest.php rename to tests/IteratorFilterXPathTest.php index ba953ff..27c4928 100644 --- a/tests/IteratorFilterTest.php +++ b/tests/IteratorFilterXPathTest.php @@ -8,7 +8,7 @@ use ByJG\AnyDataset\Core\Enum\Relation; use PHPUnit\Framework\TestCase; -class IteratorFilterTest extends TestCase +class IteratorFilterXPathTest extends TestCase { /** @@ -51,47 +51,6 @@ public function testGetXPath() ); } - public function testMatch() - { - - $collection = [ - $row1 = new Row( - [ - 'field' => 'value1', - 'field2' => 'value2' - ] - ), - $row2 = new Row( - [ - 'field' => 'other1', - 'field2' => 'other2' - ] - ), - $row3 = new Row( - [ - 'field' => 'last1', - 'field2' => 'last2' - ] - ) - ]; - - $this->assertEquals($collection, $this->object->match($collection)); - - $this->object->addRelation('field2', Relation::EQUAL, 'other2'); - $this->assertEquals([ $row2], $this->object->match($collection)); - - $this->object->addRelationOr('field', Relation::EQUAL, 'last1'); - $this->assertEquals([ $row2, $row3], $this->object->match($collection)); - - - //------------------------ - - $this->object = new IteratorFilter(); - $this->object->addRelation('field', Relation::EQUAL, 'last1'); - $this->object->addRelation('field2', Relation::EQUAL, 'last2'); - $this->assertEquals([ $row3], $this->object->match($collection)); - } - public function testAddRelationOr() { $this->object->addRelation('field', Relation::EQUAL, 'test'); @@ -114,4 +73,18 @@ public function testGroup() $this->object->format(new IteratorFilterXPathFormatter()) ); } + + public function testIn() + { + $this->expectException(\InvalidArgumentException::class); + $this->object->addRelation('field', Relation::IN, ['test', 'test2']); + $this->object->format(new IteratorFilterXPathFormatter()); + } + + public function testNotIn() + { + $this->expectException(\InvalidArgumentException::class); + $this->object->addRelation('field', Relation::NOT_IN, ['test', 'test2']); + $this->object->format(new IteratorFilterXPathFormatter()); + } }