Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update SearchParameter.php #49

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions config/asseco-json-query-builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
/**
* Registered request parameters.
*/
'request_parameters' => [
'request_parameters' => [
SearchParameter::class,
ReturnsParameter::class,
OrderByParameter::class,
Expand All @@ -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,
Expand All @@ -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,
],
Expand All @@ -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.
Expand All @@ -95,33 +95,33 @@
/**
* 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',
],
/**
* List of columns to return. Return values forwarded within the request will
* 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
* Some column names may be different on frontend than on backend.
* It is possible to map such columns so that the true ORM
* property stays hidden.
*/
'column_mapping' => [
'column_mapping' => [
'frontend_column' => 'backend_column',
],
],
Expand Down
45 changes: 39 additions & 6 deletions src/RequestParameters/SearchParameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,20 @@ 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;
}

Expand Down Expand Up @@ -131,20 +141,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);

Expand Down
12 changes: 6 additions & 6 deletions tests/Unit/JsonQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public function groups_by_attributes()
public function limits_and_offsets_results()
{
$input = [
'limit' => 5,
'limit' => 5,
'offset' => 10,
];

Expand Down Expand Up @@ -267,7 +267,7 @@ public function uses_top_level_logical_operator_for_complex_recursive_queries()
$input = [
'search' => [
'&&' => [
'||' => [
'||' => [
'att1' => '=1',
'att2' => '=1',
],
Expand All @@ -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',
],
],
Expand All @@ -308,7 +308,7 @@ public function can_recurse_absurdly_deep()
'we' => '=cool',
],
],
'love' => '<3',
'love' => '<3',
'recursion' => '=rrr',
],
],
Expand Down
Loading