Skip to content

Commit

Permalink
fix: nested filters validation
Browse files Browse the repository at this point in the history
  • Loading branch information
alexzarbn committed Jul 16, 2022
1 parent 08c0505 commit aa0e4dc
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 29 deletions.
34 changes: 17 additions & 17 deletions config/orion.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
return [
'namespaces' => [
'models' => 'App\\Models\\',
'controllers' => 'App\\Http\\Controllers\\'
'controllers' => 'App\\Http\\Controllers\\',
],
'auth' => [
'guard' => 'api'
'guard' => 'api',
],
'specs' => [
'info' => [
Expand All @@ -27,26 +27,26 @@
'servers' => [
['url' => env('APP_URL').'/api', 'description' => 'Default Environment'],
],
'tags' => []
'tags' => [],
],
'transactions' => [
'enabled' => false,
],
'search' => [
'case_sensitive' => true, // TODO: set to "false" by default in 3.0 release
/*
|--------------------------------------------------------------------------
| Max Nested Depth
|--------------------------------------------------------------------------
|
| This value is the maximum depth of nested filters
| you will most likely need this to be maximum at 1 but
| you can increase this number if necessary. Please
| be aware that the depth generate dynamic rules and can slow
| your application if someone sends a request with thousands of nested
| filters.
|
*/
'max_nested_depth' => 1
/*
|--------------------------------------------------------------------------
| Max Nested Depth
|--------------------------------------------------------------------------
|
| This value is the maximum depth of nested filters.
| You will most likely need this to be maximum at 1, but
| you can increase this number, if necessary. Please
| be aware that the depth generate dynamic rules and can slow
| your application if someone sends a request with thousands of nested
| filters.
|
*/
'max_nested_depth' => 1,
],
];
40 changes: 28 additions & 12 deletions src/Drivers/Standard/ParamsValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,32 @@ public function validateScopes(Request $request): void

public function validateFilters(Request $request): void
{
$max_depth = floor($this->getArrayDepth($request->all()['filters']) / 2);
$config_max_nested_depth = config('orion.search.max_nested_depth', 1);
$maxDepth = floor($this->getArrayDepth($request->all()['filters']) / 2);
$configMaxNestedDepth = config('orion.search.max_nested_depth', 1);

abort_if($max_depth > $config_max_nested_depth, 422, __('Max nested depth :depth is exceeded', ['depth' => $config_max_nested_depth]));
abort_if(
$maxDepth > $configMaxNestedDepth,
422,
__('Max nested depth :depth is exceeded', ['depth' => $configMaxNestedDepth])
);

Validator::make(
$request->all(),
array_merge([
'filters' => ['sometimes', 'array'],
], $this->getNestedRules('filters', $max_depth))
], $this->getNestedRules('filters', $maxDepth))
)->validate();
}

protected function getNestedRules($prefix, $max_depth, $rules = [], $current_depth = 1) {
/**
* @param string $prefix
* @param int $maxDepth
* @param array $rules
* @param int $currentDepth
* @return array
*/
protected function getNestedRules(string $prefix, int $maxDepth, array $rules = [], int $currentDepth = 1): array
{
$rules = array_merge($rules, [
$prefix.'.*.type' => ['sometimes', 'in:and,or'],
$prefix.'.*.field' => [
Expand All @@ -73,28 +85,32 @@ protected function getNestedRules($prefix, $max_depth, $rules = [], $current_dep
'in:<,<=,>,>=,=,!=,like,not like,ilike,not ilike,in,not in,all in,any in',
],
$prefix.'.*.value' => ['nullable'],
$prefix.'.*.nested' => ['sometimes', 'array', "prohibits:{$prefix}.*.operator,{$prefix}.*.value,{$prefix}.*.field"],
$prefix.'.*.nested' => ['sometimes', 'array',],
]);

if ($max_depth >= $current_depth) {
$rules = array_merge($rules, $this->getNestedRules("{$prefix}.*.nested", $max_depth, $rules, ++$current_depth));
if ($maxDepth >= $currentDepth) {
$rules = array_merge(
$rules,
$this->getNestedRules("{$prefix}.*.nested", $maxDepth, $rules, ++$currentDepth)
);
}

return $rules;
}

protected function getArrayDepth($array) {
$max_depth = 0;
protected function getArrayDepth($array): int
{
$maxDepth = 0;

foreach ($array as $value) {
if (is_array($value)) {
$depth = $this->getArrayDepth($value) + 1;

$max_depth = max($depth, $max_depth);
$maxDepth = max($depth, $maxDepth);
}
}

return $max_depth;
return $maxDepth;
}

public function validateSort(Request $request): void
Expand Down

0 comments on commit aa0e4dc

Please sign in to comment.