From 72b24f2eb614f0292c1fc2ea120074afa064ce21 Mon Sep 17 00:00:00 2001 From: Kyrch Date: Sun, 19 Apr 2026 11:32:35 -0300 Subject: [PATCH] feat(graphql): add support for IN operators in complex filtering (#1181) --- .../GraphQL/Filter/ComparisonOperator.php | 2 + .../Filter/WhereConditionsFilterCriteria.php | 37 ++++++++++++------- .../VideoScript/VideoScriptLinkField.php | 3 +- .../Wiki/Anime/AnimeThemePaginationQuery.php | 8 +--- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/app/Enums/GraphQL/Filter/ComparisonOperator.php b/app/Enums/GraphQL/Filter/ComparisonOperator.php index 77ba2c4fe..268cab82b 100644 --- a/app/Enums/GraphQL/Filter/ComparisonOperator.php +++ b/app/Enums/GraphQL/Filter/ComparisonOperator.php @@ -18,4 +18,6 @@ enum ComparisonOperator: string case GTE = '>='; case LIKE = 'like'; case NOTLIKE = 'not like'; + case IN = 'in'; + case NOTIN = 'not in'; } diff --git a/app/GraphQL/Criteria/Filter/WhereConditionsFilterCriteria.php b/app/GraphQL/Criteria/Filter/WhereConditionsFilterCriteria.php index f3bf45907..de6ecb707 100644 --- a/app/GraphQL/Criteria/Filter/WhereConditionsFilterCriteria.php +++ b/app/GraphQL/Criteria/Filter/WhereConditionsFilterCriteria.php @@ -64,20 +64,29 @@ class WhereConditionsFilterCriteria extends FilterCriteria if (filled($fieldName) && filled($value)) { $field = $this->filterableFields->get($fieldName); - match ($field->getFilter()->getClause()) { - Clause::WHERE => $builder->where( - $field->getColumn(), - ComparisonOperator::unstrictCoerce(Arr::get($where, 'operator'))->value, - Arr::first($field->getFilter()->getFilterValues(Arr::wrap($value))), - $logical->value - ), - Clause::HAVING => $builder->having( - Str::snake($field->getColumn()), - ComparisonOperator::unstrictCoerce(Arr::get($where, 'operator'))->value, - Arr::first($field->getFilter()->getFilterValues(Arr::wrap($value))), - $logical->value - ), - }; + $operator = ComparisonOperator::unstrictCoerce(Arr::get($where, 'operator')); + $value = Arr::first($field->getFilter()->getFilterValues(Arr::wrap($value))); + + if ($operator === ComparisonOperator::IN) { + $builder->whereIn($field->getColumn(), Arr::wrap($value)); + } elseif ($operator === ComparisonOperator::NOTIN) { + $builder->whereNotIn($field->getColumn(), Arr::wrap($value)); + } else { + match ($field->getFilter()->getClause()) { + Clause::WHERE => $builder->where( + $field->getColumn(), + $operator->value, + $value, + $logical->value + ), + Clause::HAVING => $builder->having( + Str::snake($field->getColumn()), + $operator->value, + $value, + $logical->value + ), + }; + } } $builder->where(function (Builder $builder) use ($where): void { diff --git a/app/GraphQL/Schema/Fields/Wiki/Video/VideoScript/VideoScriptLinkField.php b/app/GraphQL/Schema/Fields/Wiki/Video/VideoScript/VideoScriptLinkField.php index 7a18a6178..5c686647e 100644 --- a/app/GraphQL/Schema/Fields/Wiki/Video/VideoScript/VideoScriptLinkField.php +++ b/app/GraphQL/Schema/Fields/Wiki/Video/VideoScript/VideoScriptLinkField.php @@ -4,11 +4,12 @@ declare(strict_types=1); namespace App\GraphQL\Schema\Fields\Wiki\Video\VideoScript; +use App\Contracts\GraphQL\Fields\DisplayableField; use App\GraphQL\Schema\Fields\Field; use App\Models\Wiki\Video\VideoScript; use GraphQL\Type\Definition\Type; -class VideoScriptLinkField extends Field +class VideoScriptLinkField extends Field implements DisplayableField { public function __construct() { diff --git a/app/GraphQL/Schema/Queries/Models/Pagination/Wiki/Anime/AnimeThemePaginationQuery.php b/app/GraphQL/Schema/Queries/Models/Pagination/Wiki/Anime/AnimeThemePaginationQuery.php index 57e18c9e7..c0019fb6c 100644 --- a/app/GraphQL/Schema/Queries/Models/Pagination/Wiki/Anime/AnimeThemePaginationQuery.php +++ b/app/GraphQL/Schema/Queries/Models/Pagination/Wiki/Anime/AnimeThemePaginationQuery.php @@ -4,13 +4,12 @@ declare(strict_types=1); namespace App\GraphQL\Schema\Queries\Models\Pagination\Wiki\Anime; -use App\Contracts\GraphQL\Fields\DeprecatedField; use App\GraphQL\Argument\Argument; use App\GraphQL\Argument\SearchArgument; use App\GraphQL\Schema\Queries\Models\Pagination\EloquentPaginationQuery; use App\GraphQL\Schema\Types\Wiki\Anime\AnimeThemeType; -class AnimeThemePaginationQuery extends EloquentPaginationQuery implements DeprecatedField +class AnimeThemePaginationQuery extends EloquentPaginationQuery { public function name(): string { @@ -43,9 +42,4 @@ class AnimeThemePaginationQuery extends EloquentPaginationQuery implements Depre new SearchArgument(), ]; } - - public function deprecationReason(): string - { - return 'Internal use only'; - } }