Skip to content

Commit 89ed316

Browse files
committed
Implement in, not in and between on or filter
1 parent a59f34e commit 89ed316

File tree

2 files changed

+173
-19
lines changed

2 files changed

+173
-19
lines changed

src/Struct/FilterStruct.php

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,41 +21,40 @@ class FilterStruct {
2121
public $value;
2222

2323
public function __construct($fieldName, $operator, $value) {
24-
if (strpos($fieldName, self::$LOGICAL_OR)) {
25-
$this->fieldName = explode(self::$LOGICAL_OR, $fieldName);
26-
} else {
27-
$this->fieldName = $fieldName;
28-
}
24+
$this->fieldName = $fieldName;
2925
$this->operator = $this->transformOperator($operator);
3026
$this->value = $value;
3127
}
3228

3329
public function apply($object) {
34-
if (is_array($this->fieldName)) {
35-
$subquery = function ($query) {
36-
for ($fieldIndex = 0; $fieldIndex < count($this->fieldName); $fieldIndex++) {
37-
$query = $query->orWhere($this->fieldName[$fieldIndex], $this->operator, $this->value);
30+
if (strpos($this->fieldName, self::$LOGICAL_OR)) {
31+
$fieldNames = explode(self::$LOGICAL_OR, $this->fieldName);
32+
$fieldNameCount = count($fieldNames);
33+
$subquery = function ($query) use ($fieldNames, $fieldNameCount) {
34+
for ($fieldIndex = 0; $fieldIndex < $fieldNameCount; $fieldIndex++) {
35+
$query = $this->_apply($query, $fieldNames[$fieldIndex], 'or');
3836
}
3937
return $query;
4038
};
4139
return $object->where($subquery);
4240
}
4341

44-
if(array_key_exists($this->operator, self::$WHERE_QUERY_MAPPING)) {
45-
$whereQuery = self::$WHERE_QUERY_MAPPING[$this->operator];
42+
return $this->_apply($object, $this->fieldName, 'and');
43+
}
4644

47-
if (is_string($this->value)) {
48-
$this->value = explode(",", $this->value);
49-
}
45+
private function _apply($object, $fieldName, $boolean) {
46+
if (array_key_exists($this->operator, self::$WHERE_QUERY_MAPPING)) {
47+
$whereQuery = self::$WHERE_QUERY_MAPPING[$this->operator];
48+
$value = explode(",", $this->value);
5049

51-
return $object->$whereQuery($this->fieldName, $this->value);
50+
return $object->$whereQuery($fieldName, $value, $boolean);
5251
}
5352

54-
return $object->where($this->fieldName, $this->operator, $this->value);
53+
return $object->where($fieldName, $this->operator, $this->value, $boolean);
5554
}
5655

5756
private function transformOperator($rawOperator) {
58-
if(array_key_exists($rawOperator, self::$OPERATOR_MAPPING)) {
57+
if (array_key_exists($rawOperator, self::$OPERATOR_MAPPING)) {
5958
return self::$OPERATOR_MAPPING[$rawOperator];
6059
}
6160

tests/RequestParserTest.php

Lines changed: 157 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,12 @@ function testTargetNotModel()
203203

204204
function testFilterWithOr()
205205
{
206-
207206
//Create Request
208207
$uri = 'some_model';
209208
$controllerClass = MockModelController::class;
210209
$query = new ParameterBag([
211210
"filter" => [
212-
"x|y" => [
211+
"x|y" => [
213212
"is" => "1"
214213
],
215214
"z" => [
@@ -249,4 +248,160 @@ function testFilterWithOr()
249248

250249
$this->assertEquals(['1', '1', '1', '2', '3'], $builder->getBindings());
251250
}
251+
252+
function testFilterWithOrUsingInQueryKeyword()
253+
{
254+
$uri = 'some_model';
255+
$controllerClass = MockModelController::class;
256+
$query = new ParameterBag([
257+
"filter" => [
258+
"c|d" => [
259+
"in" => "1,2,3"
260+
],
261+
"i" => [
262+
"between" => "9,10"
263+
]
264+
]
265+
]);
266+
$requestParserOptions = [
267+
'model_namespaces' => [
268+
'LIQRGV\QueryFilter\Mocks',
269+
]
270+
];
271+
272+
$request = $this->createControllerRequest($uri, $controllerClass, $query, $requestParserOptions);
273+
$requestParser = new RequestParser($request);
274+
$builder = $requestParser->getBuilder();
275+
276+
$query = $builder->getQuery();
277+
278+
$this->assertEquals("mock_models", $query->from);
279+
280+
$this->assertArrayHasKey('query', $query->wheres[0]);
281+
$this->assertEquals('Nested', $query->wheres[0]['type']);
282+
283+
$subquery1 = $query->wheres[0]['query'];
284+
285+
$this->assertEquals("c", $subquery1->wheres[0]['column']);
286+
$this->assertEquals("in", strtolower($subquery1->wheres[0]['type']));
287+
288+
$this->assertEquals("d", $subquery1->wheres[1]['column']);
289+
$this->assertEquals("in", strtolower($subquery1->wheres[1]['type']));
290+
$this->assertEquals("or", strtolower($subquery1->wheres[1]['boolean']));
291+
292+
$this->assertEquals("i", $query->wheres[1]['column']);
293+
$this->assertEquals("between", strtolower($query->wheres[1]['type']));
294+
295+
$this->assertEquals(
296+
[
297+
'1', '2', '3', '1', '2', '3',
298+
'9', '10'
299+
],
300+
$builder->getBindings()
301+
);
302+
}
303+
304+
function testFilterWithOrUsingNotInQueryKeyword()
305+
{
306+
$uri = 'some_model';
307+
$controllerClass = MockModelController::class;
308+
$query = new ParameterBag([
309+
"filter" => [
310+
"e|f" => [
311+
"!in" => "4,5,6"
312+
],
313+
"i" => [
314+
"between" => "9,10"
315+
]
316+
]
317+
]);
318+
$requestParserOptions = [
319+
'model_namespaces' => [
320+
'LIQRGV\QueryFilter\Mocks',
321+
]
322+
];
323+
324+
$request = $this->createControllerRequest($uri, $controllerClass, $query, $requestParserOptions);
325+
$requestParser = new RequestParser($request);
326+
$builder = $requestParser->getBuilder();
327+
328+
$query = $builder->getQuery();
329+
330+
$this->assertEquals("mock_models", $query->from);
331+
332+
$this->assertArrayHasKey('query', $query->wheres[0]);
333+
$this->assertEquals('Nested', $query->wheres[0]['type']);
334+
335+
$subquery1 = $query->wheres[0]['query'];
336+
337+
$this->assertEquals("e", $subquery1->wheres[0]['column']);
338+
$this->assertEquals("NotIn", $subquery1->wheres[0]['type']);
339+
340+
$this->assertEquals("f", $subquery1->wheres[1]['column']);
341+
$this->assertEquals("NotIn", $subquery1->wheres[1]['type']);
342+
$this->assertEquals("or", strtolower($subquery1->wheres[1]['boolean']));
343+
344+
$this->assertEquals("i", $query->wheres[1]['column']);
345+
$this->assertEquals("between", strtolower($query->wheres[1]['type']));
346+
347+
$this->assertEquals(
348+
[
349+
'4', '5', '6', '4', '5', '6',
350+
'9', '10'
351+
],
352+
$builder->getBindings()
353+
);
354+
}
355+
356+
function testFilterWithOrUsingBetweenQueryKeyword()
357+
{
358+
$uri = 'some_model';
359+
$controllerClass = MockModelController::class;
360+
$query = new ParameterBag([
361+
"filter" => [
362+
"g|h" => [
363+
"between" => "7,8"
364+
],
365+
"i" => [
366+
"between" => "9,10"
367+
]
368+
]
369+
]);
370+
$requestParserOptions = [
371+
'model_namespaces' => [
372+
'LIQRGV\QueryFilter\Mocks',
373+
]
374+
];
375+
376+
$request = $this->createControllerRequest($uri, $controllerClass, $query, $requestParserOptions);
377+
$requestParser = new RequestParser($request);
378+
$builder = $requestParser->getBuilder();
379+
380+
$query = $builder->getQuery();
381+
382+
$this->assertEquals("mock_models", $query->from);
383+
384+
$this->assertArrayHasKey('query', $query->wheres[0]);
385+
$this->assertEquals('Nested', $query->wheres[0]['type']);
386+
387+
$subquery1 = $query->wheres[0]['query'];
388+
389+
$this->assertEquals("g", $subquery1->wheres[0]['column']);
390+
$this->assertEquals("between", strtolower($subquery1->wheres[0]['type']));
391+
392+
$this->assertEquals("h", $subquery1->wheres[1]['column']);
393+
$this->assertEquals("between", strtolower($subquery1->wheres[1]['type']));
394+
$this->assertEquals("or", strtolower($subquery1->wheres[1]['boolean']));
395+
396+
$this->assertEquals("i", $query->wheres[1]['column']);
397+
$this->assertEquals("between", strtolower($query->wheres[1]['type']));
398+
399+
$this->assertEquals(
400+
[
401+
'7', '8', '7', '8',
402+
'9', '10'
403+
],
404+
$builder->getBindings()
405+
);
406+
}
252407
}

0 commit comments

Comments
 (0)