mirror of
https://github.com/AnimeThemes/animethemes-server.git
synced 2026-07-11 01:24:46 +02:00
feat(graphql): relation filter (#1060)
This commit is contained in:
@@ -10,11 +10,13 @@ use App\Enums\GraphQL\ComparisonOperator;
|
||||
use App\Enums\GraphQL\LogicalOperator;
|
||||
use App\GraphQL\Filter\Filter;
|
||||
use App\GraphQL\Schema\Enums\FilterableColumns;
|
||||
use App\GraphQL\Schema\Fields\Base\CountField;
|
||||
use App\GraphQL\Schema\Fields\Field;
|
||||
use App\GraphQL\Schema\Types\EloquentType;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class WhereConditionsFilterCriteria extends FilterCriteria
|
||||
{
|
||||
@@ -62,12 +64,22 @@ class WhereConditionsFilterCriteria extends FilterCriteria
|
||||
if (filled($fieldName) && filled($value)) {
|
||||
$field = $this->filterableFields->get($fieldName);
|
||||
|
||||
$builder->where(
|
||||
$field->getColumn(),
|
||||
ComparisonOperator::unstrictCoerce(Arr::get($where, 'operator'))->value,
|
||||
Arr::first($field->getFilter()->getFilterValues(Arr::wrap($value))),
|
||||
$logical->value
|
||||
);
|
||||
if ($field instanceof CountField) {
|
||||
$builder->withCount(Str::replace('Count', '', $field->getName()));
|
||||
$builder->having(
|
||||
Str::snake($field->getColumn()),
|
||||
ComparisonOperator::unstrictCoerce(Arr::get($where, 'operator'))->value,
|
||||
Arr::first($field->getFilter()->getFilterValues(Arr::wrap($value))),
|
||||
$logical->value
|
||||
);
|
||||
} else {
|
||||
$builder->where(
|
||||
$field->getColumn(),
|
||||
ComparisonOperator::unstrictCoerce(Arr::get($where, 'operator'))->value,
|
||||
Arr::first($field->getFilter()->getFilterValues(Arr::wrap($value))),
|
||||
$logical->value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$builder->where(function (Builder $builder) use ($where): void {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\GraphQL\Filter;
|
||||
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class RelationFilter extends Filter
|
||||
{
|
||||
public function getBaseType(): Type
|
||||
{
|
||||
return Type::int();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert filter values if needed. By default, no conversion is needed.
|
||||
*/
|
||||
protected function convertFilterValues(array $filterValues): array
|
||||
{
|
||||
return Arr::map(
|
||||
$filterValues,
|
||||
fn (string $filterValue): ?int => filter_var($filterValue, FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules for the filter.
|
||||
*/
|
||||
protected function getRules(): array
|
||||
{
|
||||
return [
|
||||
'required',
|
||||
'integer',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,15 @@ declare(strict_types=1);
|
||||
namespace App\GraphQL\Schema\Fields\Base;
|
||||
|
||||
use App\Contracts\GraphQL\Fields\DisplayableField;
|
||||
use App\Contracts\GraphQL\Fields\FilterableField;
|
||||
use App\Contracts\GraphQL\Fields\SortableField;
|
||||
use App\Enums\GraphQL\SortType;
|
||||
use App\GraphQL\Filter\RelationFilter;
|
||||
use App\GraphQL\Schema\Fields\Field;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
|
||||
class CountField extends Field implements DisplayableField, SortableField
|
||||
class CountField extends Field implements DisplayableField, FilterableField, SortableField
|
||||
{
|
||||
public function __construct(
|
||||
protected string $relation,
|
||||
@@ -45,6 +47,11 @@ class CountField extends Field implements DisplayableField, SortableField
|
||||
return $this->relation;
|
||||
}
|
||||
|
||||
public function getFilter(): RelationFilter
|
||||
{
|
||||
return new RelationFilter($this->getName(), $this->getColumn());
|
||||
}
|
||||
|
||||
public function resolve($root, array $args, $context, ResolveInfo $resolveInfo): mixed
|
||||
{
|
||||
return $root->hasAttribute($attribute = "{$this->relation}_count")
|
||||
|
||||
Reference in New Issue
Block a user