Skip to content

Commit

Permalink
Use fully qualified column name for filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
LIQRGV committed Jan 14, 2021
1 parent 785d39c commit df797c7
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 29 deletions.
1 change: 1 addition & 0 deletions src/RequestParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ private function getModelFromNamespaces(string $modelName, array $modelNamespace

private function applyFilter(Builder $builder, array $filters): Builder
{
/** @var FilterStruct $filterStruct */
foreach ($filters as $filterStruct) {
$builder = $filterStruct->apply($builder);
}
Expand Down
6 changes: 4 additions & 2 deletions src/Struct/FilterStruct.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,16 @@ private function _apply(Builder $object, $fieldName, $boolean, $isChild = false)
if ($this->isRelation($fieldName)) {
return $this->_applyRelation($object, $fieldName, $boolean, $isChild);
}

$completeFieldName = $object->qualifyColumn($fieldName);
if (array_key_exists($this->operator, self::$WHERE_QUERY_MAPPING)) {
$whereQuery = self::$WHERE_QUERY_MAPPING[$this->operator];
$value = explode(",", $this->value);

return $object->$whereQuery($fieldName, $value, $boolean);
return $object->$whereQuery($completeFieldName, $value, $boolean);
}

return $object->where($fieldName, $this->operator, $this->value, $boolean);
return $object->where($completeFieldName, $this->operator, $this->value, $boolean);
}

private function transformOperator($rawOperator) {
Expand Down
4 changes: 2 additions & 2 deletions tests/RequestParserLaravelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function testFilterNormalViaController()

$query = $builder->getQuery();
$this->assertEquals("mock_models", $query->from);
$this->assertEquals("x", $query->wheres[0]['column']);
$this->assertEquals("mock_models.x", $query->wheres[0]['column']);
$this->assertEquals("=", $query->wheres[0]['operator']);
$this->assertEquals([1], $builder->getBindings());
}
Expand Down Expand Up @@ -61,7 +61,7 @@ function testFilterNormalViaClosure()

$query = $builder->getQuery();
$this->assertEquals("mock_some_models", $query->from);
$this->assertEquals("x", $query->wheres[0]['column']);
$this->assertEquals("mock_some_models.x", $query->wheres[0]['column']);
$this->assertEquals("=", $query->wheres[0]['operator']);
$this->assertEquals([1], $builder->getBindings());
}
Expand Down
2 changes: 1 addition & 1 deletion tests/RequestParserLumenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function() {}

$query = $builder->getQuery();
$this->assertEquals("mock_models", $query->from);
$this->assertEquals("x", $query->wheres[0]['column']);
$this->assertEquals("mock_models.x", $query->wheres[0]['column']);
$this->assertEquals("=", $query->wheres[0]['operator']);
$this->assertEquals([1], $builder->getBindings());
}
Expand Down
6 changes: 3 additions & 3 deletions tests/RequestParserRelationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function testFilterRelationOne()

// assert relation query
$this->assertEquals("Basic", $builder->getQuery()->wheres[0]["query"]->wheres[1]["type"]);
$this->assertEquals("id", $builder->getQuery()->wheres[0]["query"]->wheres[1]["column"]);
$this->assertEquals("mock_models.id", $builder->getQuery()->wheres[0]["query"]->wheres[1]["column"]);
$this->assertEquals("=", $builder->getQuery()->wheres[0]["query"]->wheres[1]["operator"]);
$this->assertEquals("2", $builder->getQuery()->wheres[0]["query"]->wheres[1]["value"]);
$this->assertEquals("and", $builder->getQuery()->wheres[0]["query"]->wheres[1]["boolean"]);
Expand Down Expand Up @@ -99,7 +99,7 @@ function testFilterOrRelationOne()

// assert first relation query field
$this->assertEquals("Basic", $firstInnerQuery->wheres[1]["type"]);
$this->assertEquals("id", $firstInnerQuery->wheres[1]["column"]);
$this->assertEquals("mock_models.id", $firstInnerQuery->wheres[1]["column"]);
$this->assertEquals("=", $firstInnerQuery->wheres[1]["operator"]);
$this->assertEquals("2", $firstInnerQuery->wheres[1]["value"]);
$this->assertEquals("and", $firstInnerQuery->wheres[1]["boolean"]);
Expand All @@ -113,7 +113,7 @@ function testFilterOrRelationOne()

// assert second relation query field
$this->assertEquals("Basic", $secondInnerQuery->wheres[1]["type"]);
$this->assertEquals("other_attr", $secondInnerQuery->wheres[1]["column"]);
$this->assertEquals("mock_models.other_attr", $secondInnerQuery->wheres[1]["column"]);
$this->assertEquals("=", $secondInnerQuery->wheres[1]["operator"]);
$this->assertEquals("2", $secondInnerQuery->wheres[1]["value"]);
$this->assertEquals("and", $secondInnerQuery->wheres[1]["boolean"]);
Expand Down
45 changes: 24 additions & 21 deletions tests/RequestParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ function testFilterKeywordIn()

$query = $builder->getQuery();
$this->assertEquals("mock_models", $query->from);
$this->assertEquals("y", $query->wheres[0]['column']);
$this->assertEquals("mock_models.y", $query->wheres[0]['column']);
$this->assertEquals("in", strtolower($query->wheres[0]['type']));
$this->assertEquals(['2', '3', '4'], $builder->getBindings());
}
Expand Down Expand Up @@ -261,15 +261,15 @@ function testFilterWithOr()
$subquery = $query->wheres[0]['query'];

//Assert subquery components
$this->assertEquals("x", $subquery->wheres[0]['column']);
$this->assertEquals("mock_models.x", $subquery->wheres[0]['column']);
$this->assertEquals("=", strtolower($subquery->wheres[0]['operator']));

$this->assertEquals("y", $subquery->wheres[1]['column']);
$this->assertEquals("mock_models.y", $subquery->wheres[1]['column']);
$this->assertEquals("=", strtolower($subquery->wheres[1]['operator']));
$this->assertEquals("or", strtolower($subquery->wheres[1]['boolean']));

//Assert second where term of the main query
$this->assertEquals("z", $query->wheres[1]['column']);
$this->assertEquals("mock_models.z", $query->wheres[1]['column']);
$this->assertEquals("in", strtolower($query->wheres[1]['type']));

$this->assertEquals(['1', '1', '1', '2', '3'], $builder->getBindings());
Expand Down Expand Up @@ -308,14 +308,14 @@ function testFilterWithOrUsingInQueryKeyword()

$subquery1 = $query->wheres[0]['query'];

$this->assertEquals("c", $subquery1->wheres[0]['column']);
$this->assertEquals("mock_models.c", $subquery1->wheres[0]['column']);
$this->assertEquals("in", strtolower($subquery1->wheres[0]['type']));

$this->assertEquals("d", $subquery1->wheres[1]['column']);
$this->assertEquals("mock_models.d", $subquery1->wheres[1]['column']);
$this->assertEquals("in", strtolower($subquery1->wheres[1]['type']));
$this->assertEquals("or", strtolower($subquery1->wheres[1]['boolean']));

$this->assertEquals("i", $query->wheres[1]['column']);
$this->assertEquals("mock_models.i", $query->wheres[1]['column']);
$this->assertEquals("between", strtolower($query->wheres[1]['type']));

$this->assertEquals(
Expand Down Expand Up @@ -360,14 +360,14 @@ function testFilterWithOrUsingNotInQueryKeyword()

$subquery1 = $query->wheres[0]['query'];

$this->assertEquals("e", $subquery1->wheres[0]['column']);
$this->assertEquals("mock_models.e", $subquery1->wheres[0]['column']);
$this->assertEquals("NotIn", $subquery1->wheres[0]['type']);

$this->assertEquals("f", $subquery1->wheres[1]['column']);
$this->assertEquals("mock_models.f", $subquery1->wheres[1]['column']);
$this->assertEquals("NotIn", $subquery1->wheres[1]['type']);
$this->assertEquals("or", strtolower($subquery1->wheres[1]['boolean']));

$this->assertEquals("i", $query->wheres[1]['column']);
$this->assertEquals("mock_models.i", $query->wheres[1]['column']);
$this->assertEquals("between", strtolower($query->wheres[1]['type']));

$this->assertEquals(
Expand Down Expand Up @@ -412,14 +412,14 @@ function testFilterWithOrUsingBetweenQueryKeyword()

$subquery1 = $query->wheres[0]['query'];

$this->assertEquals("g", $subquery1->wheres[0]['column']);
$this->assertEquals("mock_models.g", $subquery1->wheres[0]['column']);
$this->assertEquals("between", strtolower($subquery1->wheres[0]['type']));

$this->assertEquals("h", $subquery1->wheres[1]['column']);
$this->assertEquals("mock_models.h", $subquery1->wheres[1]['column']);
$this->assertEquals("between", strtolower($subquery1->wheres[1]['type']));
$this->assertEquals("or", strtolower($subquery1->wheres[1]['boolean']));

$this->assertEquals("i", $query->wheres[1]['column']);
$this->assertEquals("mock_models.i", $query->wheres[1]['column']);
$this->assertEquals("between", strtolower($query->wheres[1]['type']));

$this->assertEquals(
Expand Down Expand Up @@ -508,6 +508,7 @@ function testFilterOnlyAllowedFilter()
{
$uri = 'some_model';
$controllerClass = MockModelController::class;
$tableName = 'mock_models';
$ignoredKey = "ignored_key";
$nameKey = "name";
$valueKey = "value";
Expand Down Expand Up @@ -542,8 +543,8 @@ function testFilterOnlyAllowedFilter()
return $where["column"] == $ignoredKey;
}));

$nameAndValueColumn = array_filter($query->wheres, function ($where) use ($nameKey, $valueKey) {
return in_array($where["column"], [$nameKey, $valueKey]);
$nameAndValueColumn = array_filter($query->wheres, function ($where) use ($tableName, $nameKey, $valueKey) {
return in_array($where["column"], [sprintf("%s.%s", $tableName, $nameKey), sprintf("%s.%s", $tableName, $valueKey)]);
});
$this->assertEquals(2, count($nameAndValueColumn));
}
Expand All @@ -552,6 +553,7 @@ function testFilterIgnoreIgnoredFilter()
{
$uri = 'some_model';
$controllerClass = MockModelController::class;
$tableName = 'mock_models';
$ignoredKey = "omnisearch";
$notIgnoredKey = "selected_value";
$query = new ParameterBag([
Expand All @@ -578,18 +580,19 @@ function testFilterIgnoreIgnoredFilter()

$query = $builder->getQuery();

$this->assertEmpty(array_filter($query->wheres, function ($where) use ($ignoredKey) {
return $where["column"] == $ignoredKey;
$this->assertEmpty(array_filter($query->wheres, function ($where) use ($tableName, $ignoredKey) {
return $where["column"] == sprintf("%s.%s", $tableName, $ignoredKey);
}));
$this->assertNotEmpty(array_filter($query->wheres, function ($where) use ($notIgnoredKey) {
return $where["column"] == $notIgnoredKey;
$this->assertNotEmpty(array_filter($query->wheres, function ($where) use ($tableName, $notIgnoredKey) {
return $where["column"] == sprintf("%s.%s", $tableName, $notIgnoredKey);
}));
}

function testFilterIgnoredFilterShouldTakePrecedenceOverAllowedFilter()
{
$uri = 'some_model';
$controllerClass = MockModelController::class;
$tableName = 'mock_models';
$ignoredKey = "ignored_key";
$nameKey = "name";
$valueKey = "value";
Expand Down Expand Up @@ -621,8 +624,8 @@ function testFilterIgnoredFilterShouldTakePrecedenceOverAllowedFilter()

$query = $builder->getQuery();

$nameAndValueColumn = array_filter($query->wheres, function ($where) use ($nameKey, $valueKey) {
return in_array($where["column"], [$nameKey, $valueKey]);
$nameAndValueColumn = array_filter($query->wheres, function ($where) use ($tableName, $nameKey, $valueKey) {
return in_array($where["column"], [sprintf("%s.%s", $tableName, $nameKey), sprintf("%s.%s", $tableName, $valueKey)]);
});
$this->assertEquals(2, count($nameAndValueColumn));
$this->assertEmpty(array_filter($query->wheres, function ($where) use ($ignoredKey) {
Expand Down

0 comments on commit df797c7

Please sign in to comment.