Skip to content

Commit c5c1827

Browse files
committed
Implement filter with or
1 parent b4b460d commit c5c1827

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

src/Struct/FilterStruct.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ class FilterStruct {
88
"!is" => "!=",
99
];
1010

11+
private static $LOGICAL_OR = "|";
12+
1113
private static $WHERE_QUERY_MAPPING = [
1214
"in" => "whereIn",
1315
"!in" => "whereNotIn",
@@ -19,12 +21,32 @@ class FilterStruct {
1921
public $value;
2022

2123
public function __construct($fieldName, $operator, $value) {
22-
$this->fieldName = $fieldName;
24+
if (strpos($fieldName, self::$LOGICAL_OR)) {
25+
$this->fieldName = explode(self::$LOGICAL_OR, $fieldName);
26+
} else {
27+
$this->fieldName = $fieldName;
28+
}
2329
$this->operator = $this->transformOperator($operator);
2430
$this->value = $value;
2531
}
2632

2733
public function apply($object) {
34+
if (is_array($this->fieldName)) {
35+
$me = $this;
36+
37+
$subquery = function ($query) use ($me) {
38+
$query = $query->where($me->fieldName[0], $me->operator, $me->value);
39+
40+
for ($fieldIndex = 1; $fieldIndex < count($me->fieldName); $fieldIndex++) {
41+
$query = $query->orWhere($me->fieldName[$fieldIndex], $me->operator, $me->value);
42+
}
43+
44+
return $query;
45+
};
46+
47+
return $object->where($subquery);
48+
}
49+
2850
if(array_key_exists($this->operator, self::$WHERE_QUERY_MAPPING)) {
2951
$whereQuery = self::$WHERE_QUERY_MAPPING[$this->operator];
3052

tests/RequestParserTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,53 @@ function testTargetNotModel()
200200
$requestParser = new RequestParser($request);
201201
$requestParser->getBuilder();
202202
}
203+
204+
function testFilterWithOr()
205+
{
206+
207+
//Create Request
208+
$uri = 'some_model';
209+
$controllerClass = MockModelController::class;
210+
$query = new ParameterBag([
211+
"filter" => [
212+
"x|y" => [
213+
"is" => "1"
214+
],
215+
"z" => [
216+
"in" => "1,2,3"
217+
]
218+
]
219+
]);
220+
$requestParserOptions = [
221+
'model_namespaces' => [
222+
'LIQRGV\QueryFilter\Mocks',
223+
]
224+
];
225+
226+
$request = $this->createControllerRequest($uri, $controllerClass, $query, $requestParserOptions);
227+
$requestParser = new RequestParser($request);
228+
$builder = $requestParser->getBuilder();
229+
230+
$query = $builder->getQuery();
231+
232+
$this->assertEquals("mock_models", $query->from);
233+
234+
//Assert subquery exists
235+
$this->assertArrayHasKey('query', $query->wheres[0]);
236+
$subquery = $query->wheres[0]['query'];
237+
238+
//Assert subquery components
239+
$this->assertEquals("x", $subquery->wheres[0]['column']);
240+
$this->assertEquals("=", strtolower($subquery->wheres[0]['operator']));
241+
242+
$this->assertEquals("y", $subquery->wheres[1]['column']);
243+
$this->assertEquals("=", strtolower($subquery->wheres[1]['operator']));
244+
$this->assertEquals("or", strtolower($subquery->wheres[1]['boolean']));
245+
246+
//Assert second where term of the main query
247+
$this->assertEquals("z", $query->wheres[1]['column']);
248+
$this->assertEquals("in", strtolower($query->wheres[1]['type']));
249+
250+
$this->assertEquals(['1', '1', '1', '2', '3'], $builder->getBindings());
251+
}
203252
}

0 commit comments

Comments
 (0)