Skip to content

Commit f918bad

Browse files
committed
Added support for IN expressions
1 parent 01da70a commit f918bad

File tree

2 files changed

+37
-12
lines changed

2 files changed

+37
-12
lines changed

src/Filters/QueryMatchFilter.php

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class QueryMatchFilter extends AbstractFilter
2020
{
2121
public const MATCH_QUERY_OPERATORS = '
2222
@(\.(?<key>[^ =]+)|\[["\']?(?<keySquare>.*?)["\']?\])
23-
(\s*(?<operator>==|=|<>|!==|!=|>|<)\s*(?<comparisonValue>.+))?
23+
(\s*(?<operator>==|=|<>|!==|!=|>|<|in)\s*(?<comparisonValue>.+))?
2424
';
2525

2626
/**
@@ -47,20 +47,28 @@ public function filter($collection): array
4747
$comparisonValue = $matches['comparisonValue'] ?? null;
4848

4949
if (is_string(($comparisonValue))) {
50-
if (strtolower($comparisonValue) === 'false') {
51-
$comparisonValue = false;
52-
}
50+
if (strpos($comparisonValue, "[") === 0 && substr($comparisonValue, -1) === "]") {
51+
$comparisonValue = substr($comparisonValue, 1, -1);
52+
$comparisonValue = preg_replace('/^[\'"]/', '', $comparisonValue);
53+
$comparisonValue = preg_replace('/[\'"]$/', '', $comparisonValue);
54+
$comparisonValue = preg_replace('/[\'"],[ ]*[\'"]/', ',', $comparisonValue);
55+
$comparisonValue = explode(",", $comparisonValue);
56+
} else {
57+
if (strtolower($comparisonValue) === 'false') {
58+
$comparisonValue = false;
59+
}
5360

54-
if (strtolower($comparisonValue) === 'true') {
55-
$comparisonValue = true;
56-
}
61+
if (strtolower($comparisonValue) === 'true') {
62+
$comparisonValue = true;
63+
}
5764

58-
if (strtolower($comparisonValue) === 'null') {
59-
$comparisonValue = null;
60-
}
65+
if (strtolower($comparisonValue) === 'null') {
66+
$comparisonValue = null;
67+
}
6168

62-
$comparisonValue = preg_replace('/^[\'"]/', '', $comparisonValue);
63-
$comparisonValue = preg_replace('/[\'"]$/', '', $comparisonValue);
69+
$comparisonValue = preg_replace('/^[\'"]/', '', $comparisonValue);
70+
$comparisonValue = preg_replace('/[\'"]$/', '', $comparisonValue);
71+
}
6472
}
6573

6674
foreach ($collection as $value) {
@@ -86,6 +94,10 @@ public function filter($collection): array
8694
if ($operator === '<' && $value1 < $comparisonValue) {
8795
$return[] = $value;
8896
}
97+
98+
if ($operator === 'in' && is_array($comparisonValue) && in_array($value1, $comparisonValue, true)) {
99+
$return[] = $value;
100+
}
89101
}
90102
}
91103

tests/JSONPathTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,19 @@ public function testQueryMatchNotEqualsTo(): void
260260
self::assertEquals(['Sayings of the Century', 'Sword of Honour', 'Moby Dick'], [$results[0], $results[1], $results[2]]);
261261
}
262262

263+
/**
264+
* $..books[?(@.author in ["J. R. R. Tolkien", "Nigel Rees"])]
265+
* Filter books that have a title in ["...", "..."]
266+
*
267+
* @throws Exception
268+
*/
269+
public function testQueryMatchIn(): void
270+
{
271+
$result = (new JSONPath($this->exampleData(random_int(0, 1))))->find('$..books[?(@.author in ["J. R. R. Tolkien", "Nigel Rees"])].title');
272+
273+
self::assertEquals(['Sayings of the Century', 'The Lord of the Rings'], $result->getData());
274+
}
275+
263276
/**
264277
* $.store.books[*].author
265278
*

0 commit comments

Comments
 (0)