From af75aa62950bb58dd9896955078486d48a0af43d Mon Sep 17 00:00:00 2001 From: ngaspari <33628128+ngaspari@users.noreply.github.com> Date: Tue, 30 Jan 2024 08:27:57 +0100 Subject: [PATCH 1/2] Update SearchParameter.php fix for SearchableItem with multiple items in query, which has to be inspected together, with AND operator Example: [0] => [ [customFieldValues.date] => <>2024-01-01T00:00:00.000Z;2024-01-31T00:00:00.000Z [customFieldValues.custom_field_id] => =96e09c60-6e4f-4ab8-88f1-b21281008ad1 ] --- src/RequestParameters/SearchParameter.php | 46 ++++++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/src/RequestParameters/SearchParameter.php b/src/RequestParameters/SearchParameter.php index 5ed31c0..25ed7ec 100644 --- a/src/RequestParameters/SearchParameter.php +++ b/src/RequestParameters/SearchParameter.php @@ -62,10 +62,21 @@ protected function makeQuery(Builder $builder, array $arguments, string $boolOpe $functionName = $this->getQueryFunctionName($boolOperator); if ($this->queryInitiatedByTopLevelBool($key, $value)) { - $builder->{$functionName}(function ($queryBuilder) use ($value) { - // Recursion for inner keys which are &&/|| - $this->makeQuery($queryBuilder, $value); - }); + if (is_array($value)) { + // this must be treated together (with AND operator) + // [0] => [ + // [customFieldValues.date] => <>2024-01-01T00:00:00.000Z;2024-01-31T00:00:00.000Z + // [customFieldValues.custom_field_id] => =96e09c60-6e4f-4ab8-88f1-b21281008ad1 + // ] + $this->makeSingleQueryArr($functionName, $builder, $value); + } + else { + $builder->{$functionName}(function ($queryBuilder) use ($value) { + // Recursion for inner keys which are &&/|| + $this->makeQuery($queryBuilder, $value); + }); + } + continue; } @@ -131,20 +142,43 @@ protected function makeSingleQuery(string $functionName, Builder $builder, $key, }); } + /** + * @param string $functionName + * @param Builder $builder + * @param $values + * @return void + * @throws JsonQueryBuilderException + */ + protected function makeSingleQueryArr(string $functionName, Builder $builder, $values): void + { + $builder->{$functionName}(function ($queryBuilder) use ($values, $functionName) { + foreach($values as $key => $value) { + if (is_array($value)) { + $this->makeSingleQueryArr($functionName, $queryBuilder, $value); + } + else { + $this->applyArguments($queryBuilder, $this->operatorsConfig, $key, $value, 'AND'); + } + } + }); + } + /** * @param Builder $builder * @param OperatorsConfig $operatorsConfig * @param string $column * @param string $argument + * @param string $orAnd * * @throws JsonQueryBuilderException */ - protected function applyArguments(Builder $builder, OperatorsConfig $operatorsConfig, string $column, string $argument): void + protected function applyArguments(Builder $builder, OperatorsConfig $operatorsConfig, string $column, string $argument, ?string $orAnd = 'OR'): void { + $fn = strtoupper($orAnd) == 'AND' ? 'where' : 'orWhere'; $splitArguments = $this->splitByBoolOperators($argument); foreach ($splitArguments as $splitArgument) { - $builder->orWhere(function ($builder) use ($splitArgument, $operatorsConfig, $column) { + $builder->{$fn}(function ($builder) use ($splitArgument, $operatorsConfig, $column) { foreach ($splitArgument as $argument) { $searchModel = new SearchParser($this->modelConfig, $operatorsConfig, $column, $argument); From 9173afdc965ce7108b2eab580498d3f25dfd3274 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Tue, 30 Jan 2024 07:28:05 +0000 Subject: [PATCH 2/2] Apply fixes from StyleCI --- config/asseco-json-query-builder.php | 20 +++++++++--------- src/RequestParameters/SearchParameter.php | 25 +++++++++++------------ tests/Unit/JsonQueryTest.php | 12 +++++------ 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/config/asseco-json-query-builder.php b/config/asseco-json-query-builder.php index 2351fed..c0a6ff0 100644 --- a/config/asseco-json-query-builder.php +++ b/config/asseco-json-query-builder.php @@ -25,7 +25,7 @@ /** * Registered request parameters. */ - 'request_parameters' => [ + 'request_parameters' => [ SearchParameter::class, ReturnsParameter::class, OrderByParameter::class, @@ -42,7 +42,7 @@ * Registered operators/callbacks. Operator order matters! * Callbacks having more const OPERATOR characters must come before those with less. */ - 'operators' => [ + 'operators' => [ NotBetween::class, LessThanOrEqual::class, GreaterThanOrEqual::class, @@ -57,7 +57,7 @@ * Registered types. Generic type is the default one and should be used if * no special care for type value is needed. */ - 'types' => [ + 'types' => [ GenericType::class, BooleanType::class, ], @@ -76,7 +76,7 @@ * Refined options for a single model. * Use if you want to enforce rules on a specific model without affecting globally all models. */ - 'model_options' => [ + 'model_options' => [ /** * For real usage, use real models without quotes. This is only meant to show the available options. @@ -95,13 +95,13 @@ /** * Disable search on specific columns. Searching on forbidden columns will throw an exception. */ - 'forbidden_columns' => ['column', 'column2'], + 'forbidden_columns' => ['column', 'column2'], /** * Array of columns to order by in 'column => direction' format. * 'order-by' from query string takes precedence before these values. */ - 'order_by' => [ - 'id' => 'asc', + 'order_by' => [ + 'id' => 'asc', 'created_at' => 'desc', ], /** @@ -109,11 +109,11 @@ * override these values. This acts as a 'SELECT /return only columns/' from. * By default, 'SELECT *' will be ran. */ - 'returns' => ['column', 'column2'], + 'returns' => ['column', 'column2'], /** * List of relations to load by default. These will be overridden if provided within query string. */ - 'relations' => ['rel1', 'rel2'], + 'relations' => ['rel1', 'rel2'], /** * TBD @@ -121,7 +121,7 @@ * It is possible to map such columns so that the true ORM * property stays hidden. */ - 'column_mapping' => [ + 'column_mapping' => [ 'frontend_column' => 'backend_column', ], ], diff --git a/src/RequestParameters/SearchParameter.php b/src/RequestParameters/SearchParameter.php index 25ed7ec..732a5f0 100644 --- a/src/RequestParameters/SearchParameter.php +++ b/src/RequestParameters/SearchParameter.php @@ -63,14 +63,13 @@ protected function makeQuery(Builder $builder, array $arguments, string $boolOpe if ($this->queryInitiatedByTopLevelBool($key, $value)) { if (is_array($value)) { - // this must be treated together (with AND operator) - // [0] => [ - // [customFieldValues.date] => <>2024-01-01T00:00:00.000Z;2024-01-31T00:00:00.000Z - // [customFieldValues.custom_field_id] => =96e09c60-6e4f-4ab8-88f1-b21281008ad1 - // ] + // this must be treated together (with AND operator) + // [0] => [ + // [customFieldValues.date] => <>2024-01-01T00:00:00.000Z;2024-01-31T00:00:00.000Z + // [customFieldValues.custom_field_id] => =96e09c60-6e4f-4ab8-88f1-b21281008ad1 + // ] $this->makeSingleQueryArr($functionName, $builder, $value); - } - else { + } else { $builder->{$functionName}(function ($queryBuilder) use ($value) { // Recursion for inner keys which are &&/|| $this->makeQuery($queryBuilder, $value); @@ -143,20 +142,20 @@ protected function makeSingleQuery(string $functionName, Builder $builder, $key, } /** - * @param string $functionName - * @param Builder $builder - * @param $values + * @param string $functionName + * @param Builder $builder + * @param $values * @return void + * * @throws JsonQueryBuilderException */ protected function makeSingleQueryArr(string $functionName, Builder $builder, $values): void { $builder->{$functionName}(function ($queryBuilder) use ($values, $functionName) { - foreach($values as $key => $value) { + foreach ($values as $key => $value) { if (is_array($value)) { $this->makeSingleQueryArr($functionName, $queryBuilder, $value); - } - else { + } else { $this->applyArguments($queryBuilder, $this->operatorsConfig, $key, $value, 'AND'); } } diff --git a/tests/Unit/JsonQueryTest.php b/tests/Unit/JsonQueryTest.php index 82a9b3b..3943393 100644 --- a/tests/Unit/JsonQueryTest.php +++ b/tests/Unit/JsonQueryTest.php @@ -214,7 +214,7 @@ public function groups_by_attributes() public function limits_and_offsets_results() { $input = [ - 'limit' => 5, + 'limit' => 5, 'offset' => 10, ]; @@ -267,7 +267,7 @@ public function uses_top_level_logical_operator_for_complex_recursive_queries() $input = [ 'search' => [ '&&' => [ - '||' => [ + '||' => [ 'att1' => '=1', 'att2' => '=1', ], @@ -291,15 +291,15 @@ public function can_recurse_absurdly_deep() $input = [ 'search' => [ '||' => [ - '&&' => [ + '&&' => [ [ '||' => [ [ - 'id' => '=2||=3', + 'id' => '=2||=3', 'name' => '=foo', ], [ - 'id' => '=1', + 'id' => '=1', 'name' => '=foo%&&=%bar', ], ], @@ -308,7 +308,7 @@ public function can_recurse_absurdly_deep() 'we' => '=cool', ], ], - 'love' => '<3', + 'love' => '<3', 'recursion' => '=rrr', ], ],