feat(graphql): migrate to lighthousephp (#1183)

This commit is contained in:
Kyrch
2026-04-22 15:35:23 -03:00
committed by GitHub
parent 0404625001
commit 7fff5465c9
472 changed files with 6254 additions and 16067 deletions
-96
View File
@@ -1,96 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Actions\GraphQL;
use App\Concerns\Actions\GraphQL\ConstrainsEagerLoads;
use App\Concerns\Actions\GraphQL\FieldSelection;
use App\Concerns\Actions\GraphQL\PaginatesModels;
use App\Concerns\Actions\GraphQL\SortsModels;
use App\Contracts\GraphQL\EnumSort;
use App\GraphQL\Argument\SortArgument;
use App\GraphQL\Criteria\Sort\RelationSortCriteria;
use App\GraphQL\Schema\Types\BaseType;
use App\Rules\GraphQL\Argument\FirstArgumentRule;
use App\Scout\Criteria;
use App\Scout\Search;
use GraphQL\Type\Definition\ResolveInfo;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use UnitEnum;
class IndexAction
{
use ConstrainsEagerLoads;
use FieldSelection;
use PaginatesModels;
use SortsModels;
public function index(Builder $builder, array $args, BaseType $type, ResolveInfo $resolveInfo): Paginator
{
$this->withAggregates($builder, $args, $this->getSelection($resolveInfo), $type);
$this->filter($builder, $args, $type);
$this->sort($builder, $args);
$this->constrainEagerLoads($builder, $resolveInfo, $type);
return $this->paginate($builder, $args);
}
public function search(Builder $builder, array $args, BaseType $type, ResolveInfo $resolveInfo): Paginator
{
$criteria = new Criteria(Arr::get($args, 'search'));
$searchBuilder = Search::getSearch($builder->getModel(), $criteria);
$eloquentCallback = function (Builder $builder) use ($args, $type, $resolveInfo): void {
$this->withAggregates($builder, $args, $this->getSelection($resolveInfo), $type);
$this->filter($builder, $args, $type);
$this->sort($builder, $args);
$this->constrainEagerLoads($builder, $resolveInfo, $type);
};
// Note: First for searching must not be too high.
$first = min(100, Arr::get($args, 'first'));
$page = Arr::get($args, 'page', 1);
Validator::make(['first' => $first], [
'first' => ['required', 'integer', 'min:1', new FirstArgumentRule()],
])->validate();
/** @var array<int, UnitEnum&EnumSort> $sorts */
$sorts = Arr::get($args, SortArgument::ARGUMENT, []);
$sortsRaw = [];
foreach ($sorts as $sort) {
$criterion = $sort->getSortCriteria();
$column = $criterion->getColumn();
$direction = $criterion->getDirection();
$isString = $criterion->isStringField();
if ($criterion instanceof RelationSortCriteria) {
$sortsRaw[$column] = [
'direction' => $direction->value,
'isString' => $isString,
'relation' => $criterion->getRelation(),
];
} else {
$sortsRaw[$column] = [
'direction' => $direction,
'isString' => $isString,
];
}
}
return $searchBuilder->search($eloquentCallback, $first, $page, $sortsRaw);
}
}
-29
View File
@@ -1,29 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Actions\GraphQL;
use App\Concerns\Actions\GraphQL\ConstrainsEagerLoads;
use App\Concerns\Actions\GraphQL\FiltersModels;
use App\GraphQL\Schema\Types\BaseType;
use GraphQL\Type\Definition\ResolveInfo;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class ShowAction
{
use ConstrainsEagerLoads;
use FiltersModels;
public function show(Builder $builder, array $args, BaseType $type, ResolveInfo $resolveInfo): Model
{
$this->withAggregates($builder, $args, $this->getSelection($resolveInfo), $type);
$this->filter($builder, $args, $type);
$this->constrainEagerLoads($builder, $resolveInfo, $type);
return $builder->firstOrFail();
}
}
@@ -1,41 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Concerns\Actions\GraphQL;
use App\GraphQL\Schema\Fields\Base\Aggregate\AggregateField;
use App\GraphQL\Schema\Fields\Field;
use App\GraphQL\Schema\Types\BaseType;
use App\GraphQL\Schema\Unions\BaseUnion;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
trait AggregatesFields
{
public function withAggregates(Builder $builder, array $args, array $selection, BaseType|BaseUnion $type): Builder
{
if ($type instanceof BaseUnion) {
return $builder;
}
collect($type->fieldClasses())
->filter(fn (Field $field): bool => $field instanceof AggregateField && $field->shouldAggregate($args, $selection, $type))
->each(fn (AggregateField $selectedAggregate): Builder => $selectedAggregate->with($builder));
return $builder;
}
public function loadAggregates(Model $model, array $args, array $selection, BaseType|BaseUnion $type): Model
{
if ($type instanceof BaseUnion) {
return $model;
}
collect($type->fieldClasses())
->filter(fn (Field $field): bool => $field instanceof AggregateField && $field->shouldAggregate($args, $selection, $type))
->each(fn (AggregateField $selectedAggregate): Model => $selectedAggregate->load($model));
return $model;
}
}
@@ -1,164 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Concerns\Actions\GraphQL;
use App\GraphQL\Schema\Fields\Relations\BelongsToManyRelation;
use App\GraphQL\Schema\Fields\Relations\Relation;
use App\GraphQL\Schema\Types\BaseType;
use App\GraphQL\Schema\Types\EdgeType;
use App\GraphQL\Schema\Types\EloquentType;
use App\GraphQL\Schema\Unions\BaseUnion;
use GraphQL\Type\Definition\ResolveInfo;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\Relation as EloquentRelation;
use Illuminate\Support\Arr;
trait ConstrainsEagerLoads
{
use AggregatesFields;
use FieldSelection;
use FiltersModels;
use SortsModels;
/**
* Apply eager loads with filters and sorting.
*/
protected function constrainEagerLoads(Builder $query, ResolveInfo $resolveInfo, BaseType $type, string $fieldName = 'data'): void
{
$this->processEagerLoadForType($query, $this->getSelection($resolveInfo, $fieldName), $type);
}
/**
* Process recursively the relations available for the given type.
*/
private function processEagerLoadForType(Builder $builder, array $selection, BaseType|BaseUnion $type): void
{
$eagerLoadRelations = [];
/** @var array<int, Relation> $relations */
$relations = collect($type->relations())
->filter(fn (Relation $relation) => Arr::has($selection, $relation->name()))
->all();
foreach ($relations as $relation) {
$name = $relation->name();
$relationSelection = Arr::get($selection, "{$name}.{$name}");
$relationType = $relation->baseType();
$eagerLoadRelations[$relation->getRelationName()] = function (EloquentRelation $eloquentRelation) use ($relationSelection, $relationType, $relation): void {
match (true) {
$eloquentRelation instanceof MorphTo => $this->processMorphToRelation($relationSelection, $relationType, $eloquentRelation),
$relationType instanceof BaseUnion => $this->processUnion($relationSelection, $relationType, $eloquentRelation),
default => $this->processGenericRelation($relationSelection, $relationType, $eloquentRelation, $relation),
};
};
}
$builder->with($eagerLoadRelations);
}
/**
* MorphTo relationships have to be handled differently since they can have multiple types.
*/
private function processMorphToRelation(array $selection, BaseUnion $union, MorphTo $relation): void
{
$unions = Arr::get($selection, 'unions');
/** @var array<int, EloquentType> $types */
$types = collect($union->baseTypes())
->filter(fn (BaseType $type): bool => $type instanceof EloquentType)
->filter(fn (EloquentType $type) => Arr::has($unions, $type->name()))
->all();
$morphConstrains = [];
foreach ($types as $type) {
$typeSelection = Arr::get($unions, "{$type->name()}.selectionSet", []);
$morphConstrains[$type->model()] = function (Builder $query) use ($typeSelection, $type): void {
$this->processEagerLoadForType($query, $typeSelection, $type);
};
}
$relation->constrain($morphConstrains);
}
/**
* Process a union relation by applying the eager loads for each type in the union.
*/
private function processUnion(array $selection, BaseUnion $union, EloquentRelation $relation): void
{
$unions = Arr::get($selection, 'selectionSet.data.data.unions', []);
$types = collect($union->baseTypes())
->filter(fn (BaseType $type) => Arr::has($unions, $type->name()))
->all();
foreach ($types as $type) {
$typeSelection = Arr::get($unions, "{$type->name()}.selectionSet", []);
$this->processEagerLoadForType($relation->getQuery(), $typeSelection, $type);
}
}
/**
* Process a generic relation by applying filters, sorting and eager loads.
*/
private function processGenericRelation(array $selection, BaseType $type, EloquentRelation $relation, Relation $graphqlRelation): void
{
$builder = $relation->getQuery();
$args = Arr::get($selection, 'args');
$this->withAggregates($builder, $args, Arr::get($selection, 'selectionSet'), $type);
$this->filter($builder, $args, $type);
$this->sort($builder, $args);
$fields = Arr::get($selection, 'selectionSet.data.data.selectionSet')
?? Arr::get($selection, 'selectionSet.edges.edges.selectionSet.node.node.selectionSet')
?? Arr::get($selection, 'selectionSet.nodes.nodes.selectionSet')
?? Arr::get($selection, 'selectionSet', []);
$edgeSelection = Arr::get($selection, 'selectionSet.edges.edges.selectionSet');
if ($edgeSelection && $graphqlRelation instanceof BelongsToManyRelation) {
$this->processPivotRelation($edgeSelection, $graphqlRelation->getEdgeType(), $relation);
}
$this->processEagerLoadForType($builder, $fields, $type);
}
/**
* Process a pivot relation for a pivot model.
*/
private function processPivotRelation(array $edgeSelection, EdgeType $edgeType, EloquentRelation $relation): void
{
if (! $relation instanceof BelongsToMany) {
return;
}
$pivotRelations = collect($edgeType->relations())
->filter(fn (Relation $rel) => Arr::has($edgeSelection, $rel->name()))
->all();
foreach ($pivotRelations as $graphRelation) {
$name = $graphRelation->name();
$relationSelection = Arr::get($edgeSelection, "{$name}.{$name}");
$relationType = $graphRelation->baseType();
$eloquentName = $graphRelation->getRelationName();
$accessor = $relation->getPivotAccessor();
$relation->with("{$accessor}.{$eloquentName}", function (EloquentRelation $query) use ($relationSelection, $relationType, $graphRelation): void {
$this->processGenericRelation($relationSelection, $relationType, $query, $graphRelation);
});
}
}
}
@@ -1,20 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Concerns\Actions\GraphQL;
use App\GraphQL\ResolveInfo as GraphQLResolveInfo;
use GraphQL\Type\Definition\ResolveInfo;
use Illuminate\Support\Arr;
trait FieldSelection
{
protected function getSelection(ResolveInfo $resolveInfo, string $fieldName = 'data'): array
{
$resolveInfo = new GraphQLResolveInfo($resolveInfo);
return Arr::get($resolveInfo->getFieldSelectionWithAliases(100), "{$fieldName}.{$fieldName}.selectionSet")
?? $resolveInfo->getFieldSelectionWithAliases(100);
}
}
@@ -1,29 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Concerns\Actions\GraphQL;
use App\GraphQL\Criteria\Filter\FilterCriteria;
use App\GraphQL\Schema\Types\BaseType;
use App\GraphQL\Schema\Unions\BaseUnion;
use Illuminate\Database\Eloquent\Builder;
trait FiltersModels
{
public function filter(Builder $builder, array $args, BaseType|BaseUnion $type): Builder
{
// union not supported yet
if ($type instanceof BaseUnion) {
return $builder;
}
$criteria = FilterCriteria::parse($type, $args);
foreach ($criteria as $criterion) {
$criterion->filter($builder);
}
return $builder;
}
}
@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Concerns\Actions\GraphQL;
use App\Rules\GraphQL\Argument\FirstArgumentRule;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
trait PaginatesModels
{
public function paginate(Builder $builder, array $args): Paginator
{
$first = Arr::get($args, 'first');
$page = Arr::get($args, 'page');
Validator::make(['first' => $first], [
'first' => ['required', 'integer', 'min:1', new FirstArgumentRule()],
])->validate();
return $builder->paginate($first, page: $page);
}
}
@@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Concerns\Actions\GraphQL;
use App\Contracts\GraphQL\EnumSort;
use App\GraphQL\Argument\SortArgument;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
trait SortsModels
{
public function sort(Builder $builder, array $args): Builder
{
/** @var EnumSort[] $sorts */
$sorts = Arr::get($args, SortArgument::ARGUMENT, []);
foreach ($sorts as $sort) {
$sort->getSortCriteria()->sort($builder);
}
return $builder;
}
}
@@ -1,84 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Concerns\GraphQL;
use App\Contracts\GraphQL\Fields\BindableField;
use App\Contracts\GraphQL\Fields\CreatableField;
use App\Contracts\GraphQL\Fields\RequiredOnCreation;
use App\Contracts\GraphQL\Fields\RequiredOnUpdate;
use App\Contracts\GraphQL\Fields\UpdatableField;
use App\GraphQL\Argument\Argument;
use App\GraphQL\Argument\BindableArgument;
use App\GraphQL\Schema\Fields\Field;
trait ResolvesArguments
{
/**
* Resolve the args.
*
* @return array<string, array<string, mixed>>
*/
public function args(): array
{
return collect($this->arguments())
->mapWithKeys(fn (Argument $argument): array => [
$argument->getName() => [
'name' => $argument->getName(),
'type' => $argument->getType(),
...(is_null($argument->getDefaultValue()) ? [] : ['defaultValue' => $argument->getDefaultValue()]),
],
])
->all();
}
/**
* Resolve the fields into arguments that are used for mutations of type create.
*
* @param Field[] $fields
* @return Argument[]
*/
protected function resolveCreateMutationArguments(array $fields): array
{
return collect($fields)
->filter(fn (Field $field): bool => $field instanceof CreatableField)
->map(
fn (Field $field): Argument => new Argument($field->name(), $field->baseType())
->required($field instanceof RequiredOnCreation)
)
->flatten()
->all();
}
/**
* Resolve the fields into arguments that are used for mutations of type update.
*
* @param Field[] $fields
* @return Argument[]
*/
protected function resolveUpdateMutationArguments(array $fields): array
{
return collect($fields)
->filter(fn (Field $field): bool => $field instanceof UpdatableField)
->map(
fn (Field $field): Argument => new Argument($field->name(), $field->baseType())
->required($field instanceof RequiredOnUpdate)
)
->flatten()
->all();
}
/**
* @param Field[] $fields
* @return BindableArgument[]
*/
protected function resolveBindArguments(array $fields, bool $shouldRequire = true): array
{
return collect($fields)
->filter(fn (Field $field): bool => $field instanceof BindableField)
->map(fn (Field&BindableField $field): BindableArgument => new BindableArgument($field, $shouldRequire))
->all();
}
}
+18
View File
@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace App\Concerns\GraphQL;
use Illuminate\Pipeline\Pipeline;
trait RunMiddlewares
{
protected function runHttpMiddleware(array $middleware = []): void
{
resolve(Pipeline::class)
->send(request())
->through($middleware)
->thenReturn();
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace App\Concerns\GraphQL;
use Illuminate\Support\Facades\Validator;
use Nuwave\Lighthouse\Execution\ResolveInfo;
use Nuwave\Lighthouse\Validation\Validator as LighthouseValidator;
trait ValidateArgs
{
/**
* @param class-string<LighthouseValidator> $validator
*/
protected function validated(string $validator, ResolveInfo $resolveInfo): array
{
$validator = new $validator;
$validator->setArgs($resolveInfo->argumentSet);
return Validator::make(
$resolveInfo->argumentSet->toArray(),
$validator->rules(),
$validator->messages(),
$validator->attributes()
)->validated();
}
}
@@ -1,36 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Console\Commands\GraphQL;
use App\Console\Commands\BaseCommand;
use GraphQL\Utils\SchemaPrinter;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Support\Facades\Validator as ValidatorFacade;
use Rebing\GraphQL\Support\Facades\GraphQL;
#[Signature('graphql:print-schema {schema=v1}')]
#[Description('Print the GraphQL schema into SDL')]
class GraphQLPrintSchemaCommand extends BaseCommand
{
public function handle(): int
{
$schemaName = $this->argument('schema');
$schema = GraphQL::schema($schemaName);
$sdl = SchemaPrinter::doPrint($schema);
$this->line($sdl);
return 0;
}
protected function validator(): Validator
{
return ValidatorFacade::make($this->options(), []);
}
}
@@ -2,11 +2,11 @@
declare(strict_types=1);
namespace App\Contracts\GraphQL\Fields;
namespace App\Contracts\GraphQL;
use App\GraphQL\Filter\Filter;
interface FilterableField
interface EnumFilterableColumns
{
public function getFilter(): Filter;
}
+1 -3
View File
@@ -4,11 +4,9 @@ declare(strict_types=1);
namespace App\Contracts\GraphQL;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\SortCriteria;
interface EnumSort
{
public function getSortCriteria(): SortCriteria;
public function shouldQualifyColumn(): bool;
}
@@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Contracts\GraphQL\Fields;
use Illuminate\Database\Eloquent\Model;
interface BindableField
{
/**
* The resolver to cast the model.
*/
public function bindResolver(array $args): ?Model;
}
@@ -1,13 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Contracts\GraphQL\Fields;
interface CreatableField
{
/**
* @param array<string, mixed> $args
*/
public function getCreationRules(array $args): array;
}
@@ -1,10 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Contracts\GraphQL\Fields;
interface DeprecatedField
{
public function deprecationReason(): string;
}
@@ -1,10 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Contracts\GraphQL\Fields;
interface DisplayableField
{
public function canBeDisplayed(): bool;
}
@@ -1,7 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Contracts\GraphQL\Fields;
interface RequiredOnCreation {}
@@ -1,7 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Contracts\GraphQL\Fields;
interface RequiredOnUpdate {}
@@ -1,13 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Contracts\GraphQL\Fields;
interface UpdatableField
{
/**
* @param array<string, mixed> $args
*/
public function getUpdateRules(array $args): array;
}
@@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Field;
enum AggregateFunction: string
{
case AVG = 'avg';
case COUNT = 'count';
case EXISTS = 'exists';
case MAX = 'max';
case MIN = 'min';
case SUM = 'sum';
}
@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Admin;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Admin\Announcement;
enum AnnouncementFilterableColumns implements EnumFilterableColumns
{
case ID;
case CONTENT;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Announcement::ATTRIBUTE_ID),
self::CONTENT => new StringFilter($this->name, Announcement::ATTRIBUTE_CONTENT),
self::CREATED_AT => new TimestampFilter($this->name, Announcement::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Announcement::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Admin;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Admin\Dump;
enum DumpFilterableColumns implements EnumFilterableColumns
{
case ID;
case PATH;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Dump::ATTRIBUTE_ID),
self::PATH => new StringFilter($this->name, Dump::ATTRIBUTE_PATH),
self::CREATED_AT => new TimestampFilter($this->name, Dump::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Dump::ATTRIBUTE_UPDATED_AT),
};
}
}
-11
View File
@@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter;
enum Clause
{
case WHERE;
case HAVING;
}
@@ -1,23 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter;
use App\Concerns\Enums\CoercesInstances;
enum ComparisonOperator: string
{
use CoercesInstances;
case EQ = '=';
case NE = '<>';
case LT = '<';
case GT = '>';
case LTE = '<=';
case GTE = '>=';
case LIKE = 'like';
case NOTLIKE = 'not like';
case IN = 'in';
case NOTIN = 'not in';
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Document;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Document\Page;
enum PageFilterableColumns implements EnumFilterableColumns
{
case ID;
case NAME;
case SLUG;
case BODY;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Page::ATTRIBUTE_ID),
self::NAME => new StringFilter($this->name, Page::ATTRIBUTE_NAME),
self::SLUG => new StringFilter($this->name, Page::ATTRIBUTE_SLUG),
self::BODY => new StringFilter($this->name, Page::ATTRIBUTE_BODY),
self::CREATED_AT => new TimestampFilter($this->name, Page::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Page::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\List;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\Enums\Models\List\ExternalProfileSite;
use App\Enums\Models\List\ExternalProfileVisibility;
use App\GraphQL\Filter\EnumFilter;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\List\ExternalProfile;
enum ExternalProfileFilterableColumns implements EnumFilterableColumns
{
case ID;
case NAME;
case SITE;
case VISIBILITY;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, ExternalProfile::ATTRIBUTE_ID),
self::NAME => new StringFilter($this->name, ExternalProfile::ATTRIBUTE_NAME),
self::SITE => new EnumFilter($this->name, ExternalProfileSite::class, ExternalProfile::ATTRIBUTE_SITE),
self::VISIBILITY => new EnumFilter($this->name, ExternalProfileVisibility::class, ExternalProfile::ATTRIBUTE_VISIBILITY),
self::CREATED_AT => new TimestampFilter($this->name, ExternalProfile::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, ExternalProfile::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\List\Playlist;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\List\Playlist\PlaylistTrack;
enum PlaylistTrackFilterableColumns implements EnumFilterableColumns
{
case ID;
case POSITION;
case ENTRY_ID;
case VIDEO_ID;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, PlaylistTrack::ATTRIBUTE_ID),
self::POSITION => new IntFilter($this->name, PlaylistTrack::ATTRIBUTE_POSITION),
self::ENTRY_ID => new IntFilter($this->name, PlaylistTrack::ATTRIBUTE_ENTRY),
self::VIDEO_ID => new IntFilter($this->name, PlaylistTrack::ATTRIBUTE_VIDEO),
self::CREATED_AT => new TimestampFilter($this->name, PlaylistTrack::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, PlaylistTrack::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\List;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\Enums\Models\List\PlaylistVisibility;
use App\GraphQL\Filter\EnumFilter;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\List\Playlist;
enum PlaylistFilterableColumns implements EnumFilterableColumns
{
case ID;
case NAME;
case VISIBILITY;
case DESCRIPTION;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Playlist::ATTRIBUTE_ID),
self::NAME => new StringFilter($this->name, Playlist::ATTRIBUTE_NAME),
self::VISIBILITY => new EnumFilter($this->name, PlaylistVisibility::class, Playlist::ATTRIBUTE_VISIBILITY),
self::DESCRIPTION => new StringFilter($this->name, Playlist::ATTRIBUTE_DESCRIPTION),
self::CREATED_AT => new TimestampFilter($this->name, Playlist::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Playlist::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter;
use App\Concerns\Enums\CoercesInstances;
enum LogicalOperator: string
{
use CoercesInstances;
case AND = 'and';
case OR = 'or';
}
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki\Anime;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\Enums\Models\Wiki\ThemeType;
use App\GraphQL\Filter\EnumFilter;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Anime\AnimeTheme;
enum AnimeThemeFilterableColumns implements EnumFilterableColumns
{
case ID;
case TYPE;
case SEQUENCE;
case SLUG;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, AnimeTheme::ATTRIBUTE_ID),
self::TYPE => new EnumFilter($this->name, ThemeType::class, AnimeTheme::ATTRIBUTE_TYPE),
self::SEQUENCE => new IntFilter($this->name, AnimeTheme::ATTRIBUTE_SEQUENCE),
self::SLUG => new StringFilter($this->name, AnimeTheme::ATTRIBUTE_SLUG),
self::CREATED_AT => new TimestampFilter($this->name, AnimeTheme::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, AnimeTheme::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki\Anime\Theme;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\BooleanFilter;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
enum AnimeThemeEntryFilterableColumns implements EnumFilterableColumns
{
case ID;
case EPISODES;
case NOTES;
case NSFW;
case SPOILER;
case VERSION;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, AnimeThemeEntry::ATTRIBUTE_ID),
self::EPISODES => new StringFilter($this->name, AnimeThemeEntry::ATTRIBUTE_EPISODES),
self::NOTES => new StringFilter($this->name, AnimeThemeEntry::ATTRIBUTE_NOTES),
self::NSFW => new BooleanFilter($this->name, AnimeThemeEntry::ATTRIBUTE_NSFW),
self::SPOILER => new BooleanFilter($this->name, AnimeThemeEntry::ATTRIBUTE_SPOILER),
self::VERSION => new IntFilter($this->name, AnimeThemeEntry::ATTRIBUTE_VERSION),
self::CREATED_AT => new TimestampFilter($this->name, AnimeThemeEntry::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, AnimeThemeEntry::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\Enums\Models\Wiki\AnimeFormat;
use App\Enums\Models\Wiki\AnimeMediaFormat;
use App\Enums\Models\Wiki\AnimeSeason;
use App\GraphQL\Filter\EnumFilter;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Anime;
enum AnimeFilterableColumns implements EnumFilterableColumns
{
case ID;
case NAME;
case MEDIA_FORMAT;
case FORMAT;
case SEASON;
case SYNOPSIS;
case YEAR;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Anime::ATTRIBUTE_ID),
self::NAME => new StringFilter($this->name, Anime::ATTRIBUTE_NAME),
self::MEDIA_FORMAT => new EnumFilter($this->name, AnimeMediaFormat::class, Anime::ATTRIBUTE_MEDIA_FORMAT),
self::FORMAT => new EnumFilter($this->name, AnimeFormat::class, Anime::ATTRIBUTE_FORMAT),
self::SEASON => new EnumFilter($this->name, AnimeSeason::class, Anime::ATTRIBUTE_SEASON),
self::YEAR => new IntFilter($this->name, Anime::ATTRIBUTE_YEAR),
self::SYNOPSIS => new StringFilter($this->name, Anime::ATTRIBUTE_SYNOPSIS),
self::CREATED_AT => new TimestampFilter($this->name, Anime::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Anime::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Artist;
enum ArtistFilterableColumns implements EnumFilterableColumns
{
case ID;
case NAME;
case SLUG;
case INFORMATION;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Artist::ATTRIBUTE_ID),
self::NAME => new StringFilter($this->name, Artist::ATTRIBUTE_NAME),
self::SLUG => new StringFilter($this->name, Artist::ATTRIBUTE_SLUG),
self::INFORMATION => new StringFilter($this->name, Artist::ATTRIBUTE_INFORMATION),
self::CREATED_AT => new TimestampFilter($this->name, Artist::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Artist::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Audio;
enum AudioFilterableColumns implements EnumFilterableColumns
{
case ID;
case BASENAME;
case FILENAME;
case MIMETYPE;
case SIZE;
case PATH;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Audio::ATTRIBUTE_ID),
self::BASENAME => new StringFilter($this->name, Audio::ATTRIBUTE_BASENAME),
self::FILENAME => new StringFilter($this->name, Audio::ATTRIBUTE_FILENAME),
self::MIMETYPE => new StringFilter($this->name, Audio::ATTRIBUTE_MIMETYPE),
self::SIZE => new IntFilter($this->name, Audio::ATTRIBUTE_SIZE),
self::PATH => new StringFilter($this->name, Audio::ATTRIBUTE_PATH),
self::CREATED_AT => new TimestampFilter($this->name, Audio::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Audio::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\Enums\Models\Wiki\ResourceSite;
use App\GraphQL\Filter\EnumFilter;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\ExternalResource;
enum ExternalResourceFilterableColumns implements EnumFilterableColumns
{
case ID;
case EXTERNAL_ID;
case LINK;
case SITE;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, ExternalResource::ATTRIBUTE_ID),
self::EXTERNAL_ID => new IntFilter($this->name, ExternalResource::ATTRIBUTE_EXTERNAL_ID),
self::LINK => new StringFilter($this->name, ExternalResource::ATTRIBUTE_LINK),
self::SITE => new EnumFilter($this->name, ResourceSite::class, ExternalResource::ATTRIBUTE_SITE),
self::CREATED_AT => new TimestampFilter($this->name, ExternalResource::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, ExternalResource::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\Enums\Models\Wiki\ImageFacet;
use App\GraphQL\Filter\EnumFilter;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Image;
enum ImageFilterableColumns implements EnumFilterableColumns
{
case ID;
case FACET;
case PATH;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Image::ATTRIBUTE_ID),
self::FACET => new EnumFilter($this->name, ImageFacet::class, Image::ATTRIBUTE_FACET),
self::PATH => new StringFilter($this->name, Image::ATTRIBUTE_PATH),
self::CREATED_AT => new TimestampFilter($this->name, Image::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Image::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Series;
enum SeriesFilterableColumns implements EnumFilterableColumns
{
case ID;
case NAME;
case SLUG;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Series::ATTRIBUTE_ID),
self::NAME => new StringFilter($this->name, Series::ATTRIBUTE_NAME),
self::SLUG => new StringFilter($this->name, Series::ATTRIBUTE_SLUG),
self::CREATED_AT => new TimestampFilter($this->name, Series::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Series::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki\Song;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Song\Performance;
enum PerformanceFilterableColumns implements EnumFilterableColumns
{
case ID;
case ALIAS;
case AS;
case MEMBER_ALIAS;
case MEMBER_AS;
case RELEVANCE;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Performance::ATTRIBUTE_ID),
self::ALIAS => new StringFilter($this->name, Performance::ATTRIBUTE_ALIAS),
self::AS => new StringFilter($this->name, Performance::ATTRIBUTE_AS),
self::MEMBER_ALIAS => new StringFilter($this->name, Performance::ATTRIBUTE_MEMBER_ALIAS),
self::MEMBER_AS => new StringFilter($this->name, Performance::ATTRIBUTE_MEMBER_AS),
self::RELEVANCE => new IntFilter($this->name, Performance::ATTRIBUTE_RELEVANCE),
self::CREATED_AT => new TimestampFilter($this->name, Performance::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Performance::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Song;
enum SongFilterableColumns implements EnumFilterableColumns
{
case ID;
case TITLE;
case TITLE_NATIVE;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Song::ATTRIBUTE_ID),
self::TITLE => new StringFilter($this->name, Song::ATTRIBUTE_TITLE),
self::TITLE_NATIVE => new StringFilter($this->name, Song::ATTRIBUTE_TITLE_NATIVE),
self::CREATED_AT => new TimestampFilter($this->name, Song::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Song::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Studio;
enum StudioFilterableColumns implements EnumFilterableColumns
{
case ID;
case NAME;
case SLUG;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Studio::ATTRIBUTE_ID),
self::NAME => new StringFilter($this->name, Studio::ATTRIBUTE_NAME),
self::SLUG => new StringFilter($this->name, Studio::ATTRIBUTE_SLUG),
self::CREATED_AT => new TimestampFilter($this->name, Studio::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Studio::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\Enums\Models\Wiki\SynonymType;
use App\GraphQL\Filter\EnumFilter;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Synonym;
enum SynonymFilterableColumns implements EnumFilterableColumns
{
case ID;
case TEXT;
case TYPE;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Synonym::ATTRIBUTE_ID),
self::TEXT => new StringFilter($this->name, Synonym::ATTRIBUTE_TEXT),
self::TYPE => new EnumFilter($this->name, SynonymType::class, Synonym::ATTRIBUTE_TYPE),
self::CREATED_AT => new TimestampFilter($this->name, Synonym::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Synonym::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Group;
enum ThemeGroupFilterableColumns implements EnumFilterableColumns
{
case ID;
case NAME;
case SLUG;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Group::ATTRIBUTE_ID),
self::NAME => new StringFilter($this->name, Group::ATTRIBUTE_NAME),
self::SLUG => new StringFilter($this->name, Group::ATTRIBUTE_SLUG),
self::CREATED_AT => new TimestampFilter($this->name, Group::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Group::ATTRIBUTE_UPDATED_AT),
};
}
}
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Filter\Wiki;
use App\Contracts\GraphQL\EnumFilterableColumns;
use App\Enums\Models\Wiki\VideoOverlap;
use App\Enums\Models\Wiki\VideoSource;
use App\GraphQL\Filter\BooleanFilter;
use App\GraphQL\Filter\EnumFilter;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Filter\TimestampFilter;
use App\Models\Wiki\Video;
enum VideoFilterableColumns implements EnumFilterableColumns
{
case ID;
case BASENAME;
case FILENAME;
case LYRICS;
case MIMETYPE;
case NC;
case OVERLAP;
case PATH;
case RESOLUTION;
case SIZE;
case SOURCE;
case SUBBED;
case UNCEN;
case CREATED_AT;
case UPDATED_AT;
public function getFilter(): Filter
{
return match ($this) {
self::ID => new IntFilter($this->name, Video::ATTRIBUTE_ID),
self::BASENAME => new StringFilter($this->name, Video::ATTRIBUTE_BASENAME),
self::FILENAME => new StringFilter($this->name, Video::ATTRIBUTE_FILENAME),
self::LYRICS => new BooleanFilter($this->name, Video::ATTRIBUTE_LYRICS),
self::MIMETYPE => new StringFilter($this->name, Video::ATTRIBUTE_MIMETYPE),
self::NC => new BooleanFilter($this->name, Video::ATTRIBUTE_NC),
self::OVERLAP => new EnumFilter($this->name, VideoOverlap::class, Video::ATTRIBUTE_OVERLAP),
self::PATH => new StringFilter($this->name, Video::ATTRIBUTE_PATH),
self::RESOLUTION => new IntFilter($this->name, Video::ATTRIBUTE_RESOLUTION),
self::SIZE => new IntFilter($this->name, Video::ATTRIBUTE_SIZE),
self::SOURCE => new EnumFilter($this->name, VideoSource::class, Video::ATTRIBUTE_SOURCE),
self::SUBBED => new BooleanFilter($this->name, Video::ATTRIBUTE_SUBBED),
self::UNCEN => new BooleanFilter($this->name, Video::ATTRIBUTE_UNCEN),
self::CREATED_AT => new TimestampFilter($this->name, Video::ATTRIBUTE_CREATED_AT),
self::UPDATED_AT => new TimestampFilter($this->name, Video::ATTRIBUTE_UPDATED_AT),
};
}
}
-13
View File
@@ -1,13 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL;
enum PaginationType
{
case NONE;
case SIMPLE;
case PAGINATION;
case CONNECTION;
}
-15
View File
@@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL;
enum RelationType
{
case BELONGS_TO;
case BELONGS_TO_MANY;
case HAS_MANY;
case HAS_ONE;
case MORPH_MANY;
case MORPH_TO;
}
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Admin;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Admin\Announcement;
enum AnnouncementSort implements EnumSort
@@ -24,18 +24,13 @@ enum AnnouncementSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Announcement::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Announcement::ATTRIBUTE_ID, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, Announcement::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Announcement::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Announcement::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Announcement::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Announcement::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Announcement::ATTRIBUTE_ID, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Announcement::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Announcement::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Announcement::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Announcement::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+10 -15
View File
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Admin;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Admin\Dump;
enum DumpSort implements EnumSort
@@ -24,18 +24,13 @@ enum DumpSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Dump::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Dump::ATTRIBUTE_ID, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, Dump::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Dump::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Dump::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Dump::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Dump::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Dump::ATTRIBUTE_ID, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Dump::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Dump::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Dump::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Dump::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Sort\Auth;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Auth\Permission;
enum PermissionSort implements EnumSort
{
case ID;
case ID_DESC;
case NAME;
case NAME_DESC;
case CREATED_AT;
case CREATED_AT_DESC;
case UPDATED_AT;
case UPDATED_AT_DESC;
case RANDOM;
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
}
+44
View File
@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Sort\Auth;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Auth\Role;
enum RoleSort implements EnumSort
{
case ID;
case ID_DESC;
case NAME;
case NAME_DESC;
case PRIORITY;
case PRIORITY_DESC;
case CREATED_AT;
case CREATED_AT_DESC;
case UPDATED_AT;
case UPDATED_AT_DESC;
case RANDOM;
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this->name, Role::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Role::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Role::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this->name, Role::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::PRIORITY => new FieldSortCriteria($this->name, Role::ATTRIBUTE_PRIORITY),
self::PRIORITY_DESC => new FieldSortCriteria($this->name, Role::ATTRIBUTE_PRIORITY, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Role::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Role::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Role::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Role::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
}
+14 -19
View File
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Document;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Document\Page;
enum PageSort implements EnumSort
@@ -28,22 +28,17 @@ enum PageSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Page::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Page::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this, Page::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this, Page::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::SLUG => new FieldSortCriteria($this, Page::ATTRIBUTE_SLUG, isStringField: true),
self::SLUG_DESC => new FieldSortCriteria($this, Page::ATTRIBUTE_SLUG, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this, Page::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Page::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Page::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Page::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Page::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Page::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::SLUG => new FieldSortCriteria($this->name, Page::ATTRIBUTE_SLUG, isStringField: true),
self::SLUG_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_SLUG, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this->name, Page::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Page::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\List\Playlist;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\List\Playlist\PlaylistTrack;
enum PlaylistTrackSort implements EnumSort
@@ -26,20 +26,15 @@ enum PlaylistTrackSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, PlaylistTrack::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, PlaylistTrack::ATTRIBUTE_ID, SortDirection::DESC),
self::POSITION => new FieldSortCriteria($this, PlaylistTrack::ATTRIBUTE_POSITION),
self::POSITION_DESC => new FieldSortCriteria($this, PlaylistTrack::ATTRIBUTE_POSITION, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, PlaylistTrack::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, PlaylistTrack::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, PlaylistTrack::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, PlaylistTrack::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, PlaylistTrack::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, PlaylistTrack::ATTRIBUTE_ID, SortDirection::DESC),
self::POSITION => new FieldSortCriteria($this->name, PlaylistTrack::ATTRIBUTE_POSITION),
self::POSITION_DESC => new FieldSortCriteria($this->name, PlaylistTrack::ATTRIBUTE_POSITION, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, PlaylistTrack::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, PlaylistTrack::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, PlaylistTrack::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, PlaylistTrack::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+18 -27
View File
@@ -5,10 +5,12 @@ declare(strict_types=1);
namespace App\Enums\GraphQL\Sort\List;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\QualifyColumn;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\Enums\Http\Api\Field\AggregateFunction;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\List\Playlist;
enum PlaylistSort implements EnumSort
@@ -30,30 +32,19 @@ enum PlaylistSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Playlist::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Playlist::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this, Playlist::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this, Playlist::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::LIKES_COUNT => new FieldSortCriteria($this, 'like_aggregate_sum_value'),
self::LIKES_COUNT_DESC => new FieldSortCriteria($this, 'like_aggregate_sum_value', SortDirection::DESC),
self::TRACKS_COUNT => new FieldSortCriteria($this, 'tracksCount'),
self::TRACKS_COUNT_DESC => new FieldSortCriteria($this, 'tracksCount', SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, Playlist::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Playlist::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Playlist::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Playlist::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
};
}
public function shouldQualifyColumn(): bool
{
return match ($this) {
self::LIKES_COUNT,
self::LIKES_COUNT_DESC,
self::TRACKS_COUNT,
self::TRACKS_COUNT_DESC => false,
default => true,
self::ID => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::LIKES_COUNT => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', qualifyColumn: QualifyColumn::NO),
self::LIKES_COUNT_DESC => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', SortDirection::DESC, qualifyColumn: QualifyColumn::NO),
self::TRACKS_COUNT => new FieldSortCriteria($this->name, 'tracks_count', qualifyColumn: QualifyColumn::NO)->setAggregateRelation(Playlist::RELATION_TRACKS, AggregateFunction::COUNT),
self::TRACKS_COUNT_DESC => new FieldSortCriteria($this->name, 'tracks_count', SortDirection::DESC, qualifyColumn: QualifyColumn::NO)->setAggregateRelation(Playlist::RELATION_TRACKS, AggregateFunction::COUNT),
self::CREATED_AT => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
}
@@ -6,10 +6,10 @@ namespace App\Enums\GraphQL\Sort\Pivot;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\PivotSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\PivotSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Artist;
use App\Pivots\Wiki\ArtistMember;
@@ -34,26 +34,21 @@ enum ArtistMemberSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Artist::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Artist::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this, Artist::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this, Artist::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::MEMBER_ALIAS => new PivotSortCriteria($this, ArtistMember::ATTRIBUTE_ALIAS, isStringField: true),
self::MEMBER_ALIAS_DESC => new PivotSortCriteria($this, ArtistMember::ATTRIBUTE_ALIAS, SortDirection::DESC, isStringField: true),
self::MEMBER_AS => new PivotSortCriteria($this, ArtistMember::ATTRIBUTE_AS, isStringField: true),
self::MEMBER_AS_DESC => new PivotSortCriteria($this, ArtistMember::ATTRIBUTE_AS, SortDirection::DESC, isStringField: true),
self::MEMBER_RELEVANCE => new PivotSortCriteria($this, ArtistMember::ATTRIBUTE_RELEVANCE),
self::MEMBER_RELEVANCE_DESC => new PivotSortCriteria($this, ArtistMember::ATTRIBUTE_RELEVANCE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, Artist::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Artist::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Artist::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Artist::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::MEMBER_ALIAS => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_ALIAS, isStringField: true),
self::MEMBER_ALIAS_DESC => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_ALIAS, SortDirection::DESC, isStringField: true),
self::MEMBER_AS => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_AS, isStringField: true),
self::MEMBER_AS_DESC => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_AS, SortDirection::DESC, isStringField: true),
self::MEMBER_RELEVANCE => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_RELEVANCE),
self::MEMBER_RELEVANCE_DESC => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_RELEVANCE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+13 -18
View File
@@ -6,10 +6,10 @@ namespace App\Enums\GraphQL\Sort\Pivot;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\PivotSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\PivotSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Image;
use App\Pivots\Morph\Imageable;
@@ -28,20 +28,15 @@ enum ImageableSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Image::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Image::ATTRIBUTE_ID, SortDirection::DESC),
self::DEPTH => new PivotSortCriteria($this, Imageable::ATTRIBUTE_DEPTH),
self::DEPTH_DESC => new PivotSortCriteria($this, Imageable::ATTRIBUTE_DEPTH, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, Image::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Image::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Image::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Image::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Image::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Image::ATTRIBUTE_ID, SortDirection::DESC),
self::DEPTH => new PivotSortCriteria($this->name, Imageable::ATTRIBUTE_DEPTH),
self::DEPTH_DESC => new PivotSortCriteria($this->name, Imageable::ATTRIBUTE_DEPTH, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Image::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Image::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Image::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Image::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -5,10 +5,12 @@ declare(strict_types=1);
namespace App\Enums\GraphQL\Sort\Wiki\Anime\AnimeTheme;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\QualifyColumn;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\Enums\Http\Api\Field\AggregateFunction;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
enum AnimeThemeEntrySort implements EnumSort
@@ -32,32 +34,21 @@ enum AnimeThemeEntrySort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, AnimeThemeEntry::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, AnimeThemeEntry::ATTRIBUTE_ID, SortDirection::DESC),
self::EPISODES => new FieldSortCriteria($this, AnimeThemeEntry::ATTRIBUTE_EPISODES),
self::EPISODES_DESC => new FieldSortCriteria($this, AnimeThemeEntry::ATTRIBUTE_EPISODES, SortDirection::DESC),
self::VERSION => new FieldSortCriteria($this, AnimeThemeEntry::ATTRIBUTE_VERSION),
self::VERSION_DESC => new FieldSortCriteria($this, AnimeThemeEntry::ATTRIBUTE_VERSION, SortDirection::DESC),
self::LIKES_COUNT => new FieldSortCriteria($this, 'like_aggregate_sum_value'),
self::LIKES_COUNT_DESC => new FieldSortCriteria($this, 'like_aggregate_sum_value', SortDirection::DESC),
self::TRACKS_COUNT => new FieldSortCriteria($this, 'tracks_count'),
self::TRACKS_COUNT_DESC => new FieldSortCriteria($this, 'tracks_count', SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, AnimeThemeEntry::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, AnimeThemeEntry::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, AnimeThemeEntry::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, AnimeThemeEntry::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
};
}
public function shouldQualifyColumn(): bool
{
return match ($this) {
self::LIKES_COUNT,
self::LIKES_COUNT_DESC,
self::TRACKS_COUNT,
self::TRACKS_COUNT_DESC => false,
default => true,
self::ID => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_ID, SortDirection::DESC),
self::EPISODES => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_EPISODES),
self::EPISODES_DESC => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_EPISODES, SortDirection::DESC),
self::VERSION => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_VERSION),
self::VERSION_DESC => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_VERSION, SortDirection::DESC),
self::LIKES_COUNT => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', qualifyColumn: QualifyColumn::NO),
self::LIKES_COUNT_DESC => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', SortDirection::DESC, qualifyColumn: QualifyColumn::NO),
self::TRACKS_COUNT => new FieldSortCriteria($this->name, 'tracks_count', qualifyColumn: QualifyColumn::NO)->setAggregateRelation(AnimeThemeEntry::RELATION_TRACKS, AggregateFunction::COUNT),
self::TRACKS_COUNT_DESC => new FieldSortCriteria($this->name, 'tracks_count', SortDirection::DESC, qualifyColumn: QualifyColumn::NO)->setAggregateRelation(AnimeThemeEntry::RELATION_TRACKS, AggregateFunction::COUNT),
self::CREATED_AT => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
}
@@ -6,10 +6,10 @@ namespace App\Enums\GraphQL\Sort\Wiki\Anime;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\RelationSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\RelationSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Anime\AnimeTheme;
use App\Models\Wiki\Song;
@@ -32,24 +32,19 @@ enum AnimeThemeSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, AnimeTheme::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, AnimeTheme::ATTRIBUTE_ID, SortDirection::DESC),
self::SEQUENCE => new FieldSortCriteria($this, AnimeTheme::ATTRIBUTE_SEQUENCE),
self::SEQUENCE_DESC => new FieldSortCriteria($this, AnimeTheme::ATTRIBUTE_SEQUENCE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, AnimeTheme::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, AnimeTheme::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, AnimeTheme::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, AnimeTheme::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::SONG_TITLE => new RelationSortCriteria($this, Song::ATTRIBUTE_TITLE, AnimeTheme::RELATION_SONG, isStringField: true),
self::SONG_TITLE_DESC => new RelationSortCriteria($this, Song::ATTRIBUTE_TITLE, AnimeTheme::RELATION_SONG, SortDirection::DESC, isStringField: true),
self::SONG_TITLE_NATIVE => new RelationSortCriteria($this, Song::ATTRIBUTE_TITLE_NATIVE, AnimeTheme::RELATION_SONG, isStringField: true),
self::SONG_TITLE_NATIVE_DESC => new RelationSortCriteria($this, Song::ATTRIBUTE_TITLE_NATIVE, AnimeTheme::RELATION_SONG, SortDirection::DESC, isStringField: true),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_ID, SortDirection::DESC),
self::SEQUENCE => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_SEQUENCE),
self::SEQUENCE_DESC => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_SEQUENCE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::SONG_TITLE => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE, AnimeTheme::RELATION_SONG, isStringField: true),
self::SONG_TITLE_DESC => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE, AnimeTheme::RELATION_SONG, SortDirection::DESC, isStringField: true),
self::SONG_TITLE_NATIVE => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE, AnimeTheme::RELATION_SONG, isStringField: true),
self::SONG_TITLE_NATIVE_DESC => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE, AnimeTheme::RELATION_SONG, SortDirection::DESC, isStringField: true),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+14 -19
View File
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Wiki;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Anime;
enum AnimeSort implements EnumSort
@@ -28,22 +28,17 @@ enum AnimeSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Anime::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Anime::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this, Anime::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this, Anime::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::YEAR => new FieldSortCriteria($this, Anime::ATTRIBUTE_YEAR),
self::YEAR_DESC => new FieldSortCriteria($this, Anime::ATTRIBUTE_YEAR, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, Anime::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Anime::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Anime::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Anime::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::YEAR => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_YEAR),
self::YEAR_DESC => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_YEAR, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+12 -17
View File
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Wiki;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Artist;
enum ArtistSort implements EnumSort
@@ -26,20 +26,15 @@ enum ArtistSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Artist::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Artist::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this, Artist::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this, Artist::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this, Artist::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Artist::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Artist::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Artist::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+16 -21
View File
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Wiki;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Audio;
enum AudioSort implements EnumSort
@@ -30,24 +30,19 @@ enum AudioSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Audio::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Audio::ATTRIBUTE_ID, SortDirection::DESC),
self::BASENAME => new FieldSortCriteria($this, Audio::ATTRIBUTE_BASENAME, isStringField: true),
self::BASENAME_DESC => new FieldSortCriteria($this, Audio::ATTRIBUTE_BASENAME, SortDirection::DESC, isStringField: true),
self::FILENAME => new FieldSortCriteria($this, Audio::ATTRIBUTE_FILENAME, isStringField: true),
self::FILENAME_DESC => new FieldSortCriteria($this, Audio::ATTRIBUTE_FILENAME, SortDirection::DESC, isStringField: true),
self::SIZE => new FieldSortCriteria($this, Audio::ATTRIBUTE_SIZE),
self::SIZE_DESC => new FieldSortCriteria($this, Audio::ATTRIBUTE_SIZE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, Audio::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Audio::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Audio::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Audio::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_ID, SortDirection::DESC),
self::BASENAME => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_BASENAME, isStringField: true),
self::BASENAME_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_BASENAME, SortDirection::DESC, isStringField: true),
self::FILENAME => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_FILENAME, isStringField: true),
self::FILENAME_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_FILENAME, SortDirection::DESC, isStringField: true),
self::SIZE => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_SIZE),
self::SIZE_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_SIZE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Sort\Wiki;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\ExternalResource;
enum ExternalResourceSort implements EnumSort
{
case ID;
case ID_DESC;
case SITE;
case SITE_DESC;
case EXTERNAL_ID;
case EXTERNAL_ID_DESC;
case LINK;
case LINK_DESC;
case CREATED_AT;
case CREATED_AT_DESC;
case UPDATED_AT;
case UPDATED_AT_DESC;
case RANDOM;
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_ID, SortDirection::ASC),
self::ID_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_ID, SortDirection::DESC),
self::SITE => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_SITE),
self::SITE_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_SITE, SortDirection::DESC),
self::EXTERNAL_ID => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_EXTERNAL_ID),
self::EXTERNAL_ID_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_EXTERNAL_ID, SortDirection::DESC),
self::LINK => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_LINK, isStringField: true),
self::LINK_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_LINK, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
}
+10 -15
View File
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Wiki;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Image;
enum ImageSort implements EnumSort
@@ -24,18 +24,13 @@ enum ImageSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Image::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Image::ATTRIBUTE_ID, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, Image::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Image::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Image::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Image::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Image::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Image::ATTRIBUTE_ID, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Image::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Image::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Image::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Image::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+12 -17
View File
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Wiki;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Series;
enum SeriesSort implements EnumSort
@@ -26,20 +26,15 @@ enum SeriesSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Series::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Series::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this, Series::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this, Series::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this, Series::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Series::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Series::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Series::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Series::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Series::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Series::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this->name, Series::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this->name, Series::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Series::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Series::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Series::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Wiki\Song;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Song\Performance;
enum PerformanceSort implements EnumSort
@@ -34,28 +34,23 @@ enum PerformanceSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Performance::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Performance::ATTRIBUTE_ID, SortDirection::DESC),
self::ALIAS => new FieldSortCriteria($this, Performance::ATTRIBUTE_ALIAS, isStringField: true),
self::ALIAS_DESC => new FieldSortCriteria($this, Performance::ATTRIBUTE_ALIAS, SortDirection::DESC, isStringField: true),
self::AS => new FieldSortCriteria($this, Performance::ATTRIBUTE_AS, isStringField: true),
self::AS_DESC => new FieldSortCriteria($this, Performance::ATTRIBUTE_AS, SortDirection::DESC, isStringField: true),
self::MEMBER_ALIAS => new FieldSortCriteria($this, Performance::ATTRIBUTE_MEMBER_ALIAS, isStringField: true),
self::MEMBER_ALIAS_DESC => new FieldSortCriteria($this, Performance::ATTRIBUTE_MEMBER_ALIAS, SortDirection::DESC, isStringField: true),
self::MEMBER_AS => new FieldSortCriteria($this, Performance::ATTRIBUTE_MEMBER_AS, isStringField: true),
self::MEMBER_AS_DESC => new FieldSortCriteria($this, Performance::ATTRIBUTE_MEMBER_AS, SortDirection::DESC, isStringField: true),
self::RELEVANCE => new FieldSortCriteria($this, Performance::ATTRIBUTE_RELEVANCE),
self::RELEVANCE_DESC => new FieldSortCriteria($this, Performance::ATTRIBUTE_RELEVANCE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, Performance::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Performance::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Performance::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Performance::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ID, SortDirection::DESC),
self::ALIAS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ALIAS, isStringField: true),
self::ALIAS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ALIAS, SortDirection::DESC, isStringField: true),
self::AS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_AS, isStringField: true),
self::AS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_AS, SortDirection::DESC, isStringField: true),
self::MEMBER_ALIAS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_ALIAS, isStringField: true),
self::MEMBER_ALIAS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_ALIAS, SortDirection::DESC, isStringField: true),
self::MEMBER_AS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_AS, isStringField: true),
self::MEMBER_AS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_AS, SortDirection::DESC, isStringField: true),
self::RELEVANCE => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_RELEVANCE),
self::RELEVANCE_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_RELEVANCE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+14 -19
View File
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Wiki;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Song;
enum SongSort implements EnumSort
@@ -28,22 +28,17 @@ enum SongSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Song::ATTRIBUTE_ID, SortDirection::ASC),
self::ID_DESC => new FieldSortCriteria($this, Song::ATTRIBUTE_ID, SortDirection::DESC),
self::TITLE => new FieldSortCriteria($this, Song::ATTRIBUTE_TITLE, isStringField: true),
self::TITLE_DESC => new FieldSortCriteria($this, Song::ATTRIBUTE_TITLE, SortDirection::DESC, isStringField: true),
self::TITLE_NATIVE => new FieldSortCriteria($this, Song::ATTRIBUTE_TITLE_NATIVE, isStringField: true),
self::TITLE_NATIVE_DESC => new FieldSortCriteria($this, Song::ATTRIBUTE_TITLE_NATIVE, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this, Song::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Song::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Song::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Song::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Song::ATTRIBUTE_ID, SortDirection::ASC),
self::ID_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_ID, SortDirection::DESC),
self::TITLE => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE, isStringField: true),
self::TITLE_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE, SortDirection::DESC, isStringField: true),
self::TITLE_NATIVE => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE, isStringField: true),
self::TITLE_NATIVE_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this->name, Song::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Song::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+12 -17
View File
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Wiki;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Studio;
enum StudioSort implements EnumSort
@@ -26,20 +26,15 @@ enum StudioSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Studio::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Studio::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this, Studio::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this, Studio::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this, Studio::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Studio::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Studio::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Studio::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+12 -17
View File
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Wiki;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Synonym;
enum SynonymSort implements EnumSort
@@ -26,20 +26,15 @@ enum SynonymSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Synonym::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Synonym::ATTRIBUTE_ID, SortDirection::DESC),
self::TEXT => new FieldSortCriteria($this, Synonym::ATTRIBUTE_TEXT, isStringField: true),
self::TEXT_DESC => new FieldSortCriteria($this, Synonym::ATTRIBUTE_TEXT, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this, Synonym::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Synonym::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Synonym::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Synonym::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_ID, SortDirection::DESC),
self::TEXT => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_TEXT, isStringField: true),
self::TEXT_DESC => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_TEXT, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Sort\Wiki;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Group;
enum ThemeGroupSort implements EnumSort
{
case ID;
case ID_DESC;
case NAME;
case NAME_DESC;
case SLUG;
case SLUG_DESC;
case CREATED_AT;
case CREATED_AT_DESC;
case UPDATED_AT;
case UPDATED_AT_DESC;
case RANDOM;
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this->name, Group::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Group::ATTRIBUTE_NAME, isStringField: true),
self::NAME_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true),
self::SLUG => new FieldSortCriteria($this->name, Group::ATTRIBUTE_SLUG, isStringField: true),
self::SLUG_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_SLUG, SortDirection::DESC, isStringField: true),
self::CREATED_AT => new FieldSortCriteria($this->name, Group::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Group::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
}
+18 -23
View File
@@ -6,9 +6,9 @@ namespace App\Enums\GraphQL\Sort\Wiki;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RandomSortCriteria;
use App\GraphQL\Sort\SortCriteria;
use App\Models\Wiki\Video;
enum VideoSort implements EnumSort
@@ -32,26 +32,21 @@ enum VideoSort implements EnumSort
public function getSortCriteria(): SortCriteria
{
return match ($this) {
self::ID => new FieldSortCriteria($this, Video::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this, Video::ATTRIBUTE_ID, SortDirection::DESC),
self::BASENAME => new FieldSortCriteria($this, Video::ATTRIBUTE_BASENAME, isStringField: true),
self::BASENAME_DESC => new FieldSortCriteria($this, Video::ATTRIBUTE_BASENAME, SortDirection::DESC, isStringField: true),
self::FILENAME => new FieldSortCriteria($this, Video::ATTRIBUTE_FILENAME, isStringField: true),
self::FILENAME_DESC => new FieldSortCriteria($this, Video::ATTRIBUTE_FILENAME, SortDirection::DESC, isStringField: true),
self::RESOLUTION => new FieldSortCriteria($this, Video::ATTRIBUTE_RESOLUTION),
self::RESOLUTION_DESC => new FieldSortCriteria($this, Video::ATTRIBUTE_RESOLUTION, SortDirection::DESC),
self::SIZE => new FieldSortCriteria($this, Video::ATTRIBUTE_SIZE),
self::SIZE_DESC => new FieldSortCriteria($this, Video::ATTRIBUTE_SIZE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this, Video::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this, Video::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this, Video::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this, Video::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this, ''),
self::ID => new FieldSortCriteria($this->name, Video::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_ID, SortDirection::DESC),
self::BASENAME => new FieldSortCriteria($this->name, Video::ATTRIBUTE_BASENAME, isStringField: true),
self::BASENAME_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_BASENAME, SortDirection::DESC, isStringField: true),
self::FILENAME => new FieldSortCriteria($this->name, Video::ATTRIBUTE_FILENAME, isStringField: true),
self::FILENAME_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_FILENAME, SortDirection::DESC, isStringField: true),
self::RESOLUTION => new FieldSortCriteria($this->name, Video::ATTRIBUTE_RESOLUTION),
self::RESOLUTION_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_RESOLUTION, SortDirection::DESC),
self::SIZE => new FieldSortCriteria($this->name, Video::ATTRIBUTE_SIZE),
self::SIZE_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_SIZE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Video::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Video::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -1,18 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Exceptions\GraphQL;
use GraphQL\Error\Error;
/**
* Thrown when query is not allowed.
*/
class ClientForbiddenException extends Error
{
public function isClientSafe(): bool
{
return true;
}
}
-64
View File
@@ -1,64 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Argument;
use GraphQL\Type\Definition\Type;
class Argument
{
protected bool $required = false;
protected mixed $defaultValue = null;
public function __construct(
protected string $name,
public Type|string $returnType,
) {}
/**
* Mark the argument as required.
*/
public function required(bool $condition = true): static
{
$this->required = $condition;
return $this;
}
/**
* Append a default value to the argument.
*/
public function withDefaultValue(mixed $value): static
{
$this->defaultValue = $value;
return $this;
}
/**
* Get the name of the argument.
*/
public function getName(): string
{
return $this->name;
}
/**
* Get the default value.
*/
public function getDefaultValue(): mixed
{
return $this->defaultValue;
}
/**
* Get the type of the argument.
*/
public function getType(): Type
{
return $this->required
? Type::nonNull($this->returnType)
: $this->returnType;
}
}
-20
View File
@@ -1,20 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Argument;
use App\Contracts\GraphQL\Fields\BindableField;
use App\GraphQL\Schema\Fields\Field;
class BindableArgument extends Argument
{
public function __construct(
Field&BindableField $field,
bool $shouldRequire = true,
) {
parent::__construct($field->name(), $field->baseType());
$this->required($shouldRequire);
}
}
-27
View File
@@ -1,27 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Argument;
use App\Enums\Http\Api\Filter\ComparisonOperator;
use GraphQL\Type\Definition\Type;
class FilterArgument extends Argument
{
protected bool $required = false;
protected mixed $defaultValue = null;
public function __construct(
protected string $name,
public Type|string $returnType,
protected ComparisonOperator $operator,
) {
parent::__construct($name, $returnType);
}
public function getComparisonOperator(): ComparisonOperator
{
return $this->operator;
}
}
-26
View File
@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Argument;
use GraphQL\Type\Definition\Type;
use Illuminate\Support\Facades\Config;
class FirstArgument extends Argument
{
public function __construct(bool $isRelation = false)
{
parent::__construct('first', Type::int());
$this->required();
// Default count set to unlimited for relations for everyone
// and set to config value for pagination queries.
$this->withDefaultValue(
$isRelation
? Config::get('graphql.pagination_values.relation.default_count')
: Config::get('graphql.pagination_values.default_count')
);
}
}
-15
View File
@@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Argument;
use GraphQL\Type\Definition\Type;
class PageArgument extends Argument
{
public function __construct()
{
parent::__construct('page', Type::int());
}
}
-15
View File
@@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Argument;
use GraphQL\Type\Definition\Type;
class SearchArgument extends Argument
{
public function __construct()
{
parent::__construct('search', Type::string());
}
}
-26
View File
@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Argument;
use App\Contracts\GraphQL\EnumSort;
use App\GraphQL\Schema\Types\BaseType;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use UnitEnum;
class SortArgument extends Argument
{
final public const string ARGUMENT = 'sort';
/**
* @param class-string<UnitEnum&EnumSort> $sortEnum
*/
public function __construct(protected BaseType $type, ?string $sortEnum = null)
{
$enum = $sortEnum ?? $type->getEnumSortClass();
parent::__construct(self::ARGUMENT, Type::listOf(Type::nonNull(GraphQL::type(class_basename($enum)))));
}
}
@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Builders;
use App\Enums\Models\Wiki\ResourceSite;
use App\Models\Wiki\Anime;
use App\Models\Wiki\ExternalResource;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\Enum;
class FindAnimeByExternalSiteBuilder
{
/**
* @param array<string, mixed> $args
*/
public function __invoke(Builder $builder, null $_, null $root, $args): Builder
{
Validator::make($args, [
'site' => ['required', new Enum(ResourceSite::class)],
'id' => ['required_without:link', 'max:100'],
'link' => ['required_without:id'],
])->validate();
$site = Arr::get($args, 'site');
$externalId = Arr::get($args, 'id');
$link = Arr::get($args, 'link');
$builder->whereRelation(Anime::RELATION_RESOURCES, function (Builder $query) use ($site, $externalId, $link): void {
$query->where(ExternalResource::ATTRIBUTE_SITE, $site->value);
if (is_array($externalId)) {
$query->whereIn(ExternalResource::ATTRIBUTE_EXTERNAL_ID, $externalId);
}
if (is_string($link)) {
$query->where(ExternalResource::ATTRIBUTE_LINK, $link);
}
});
return $builder;
}
}
@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Builders\List;
use App\Enums\Models\List\ExternalProfileVisibility;
use App\Models\List\ExternalProfile;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
class ExternalProfilePaginationBuilder
{
/**
* @param array<string, mixed> $args
*/
public function __invoke(Builder $builder, null $_, null $root, $args): Builder
{
$builder->where(ExternalProfile::ATTRIBUTE_VISIBILITY, ExternalProfileVisibility::PUBLIC->value);
if ($user = Auth::user()) {
return $builder->orWhereBelongsTo($user, ExternalProfile::RELATION_USER);
}
return $builder;
}
}
@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Builders\List;
use App\Enums\Models\List\PlaylistVisibility;
use App\Models\List\Playlist;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
class PlaylistPaginationBuilder
{
/**
* @param array<string, mixed> $args
*/
public function __invoke(Builder $builder, null $_, null $root, $args): Builder
{
$builder->where(Playlist::ATTRIBUTE_VISIBILITY, PlaylistVisibility::PUBLIC->value);
if ($user = Auth::user()) {
return $builder->orWhereBelongsTo($user, Playlist::RELATION_USER);
}
return $builder;
}
}
@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Builders\List;
use App\Models\List\Playlist;
use App\Models\List\Playlist\PlaylistTrack;
use ArrayAccess;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
class PlaylistTrackBuilder
{
/**
* @param array<string, mixed> $args
*/
public function __invoke(Builder $builder, null $_, null $root, ArrayAccess|array $args): Builder
{
$playlist = Arr::string($args, 'playlist');
$builder->whereRelation(PlaylistTrack::RELATION_PLAYLIST, Playlist::ATTRIBUTE_HASHID, $playlist);
return $builder;
}
}
@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Builders\List;
use App\Models\List\Playlist;
use App\Models\List\Playlist\PlaylistTrack;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
class PlaylistTrackPaginationBuilder
{
/**
* @param array<string, mixed> $args
*/
public function __invoke(Builder $builder, null $_, null $root, $args): Builder
{
/** @var Playlist $playlist */
$playlist = Arr::get($args, 'playlist');
$builder->where(PlaylistTrack::ATTRIBUTE_PLAYLIST, $playlist->getKey());
return $builder;
}
}
@@ -1,106 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Criteria\Filter;
use App\Contracts\GraphQL\Fields\FilterableField;
use App\GraphQL\Argument\Argument;
use App\GraphQL\Argument\FilterArgument;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\WhereConditionsFilter;
use App\GraphQL\Schema\Fields\Field;
use App\GraphQL\Schema\Types\BaseType;
use App\GraphQL\Schema\Types\EloquentType;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
abstract class FilterCriteria
{
public function __construct(
protected Filter $filter,
protected $value,
) {}
/**
* @return Collection<int, Filter>
*/
public static function getFilters(BaseType $baseType): Collection
{
$fields = $baseType->fieldClasses();
return collect($fields)
->filter(fn (Field $field): bool => $field instanceof FilterableField)
->map(fn (Field&FilterableField $field): Filter => $field->getFilter())
->flatten()
->when(
$baseType instanceof EloquentType,
/** @phpstan-ignore-next-line */
fn (Collection $collection) => $collection->push(new WhereConditionsFilter($baseType))
);
}
/**
* Parse filter criteria from arguments.
*
* @param array<string, mixed> $args
* @return FilterCriteria[]
*/
public static function parse(BaseType $type, array $args): array
{
$filters = static::getFilters($type);
$criteria = [];
foreach ($args as $arg => $value) {
$match = $filters
->map(function (Filter $filter) use ($arg): ?array {
$argument = collect($filter->getArguments())
->first(fn (Argument $argument): bool => $argument->getName() === $arg);
return $argument ? [$filter, $argument] : null;
})
->filter()
->first();
[$filter, $argument] = $match;
if ($filter instanceof Filter && Str::endsWith($arg, '_in')) {
$criteria[] = new WhereInFilterCriteria($filter, $value, Str::endsWith($arg, '_not_in'));
continue;
}
if ($filter instanceof WhereConditionsFilter && $type instanceof EloquentType && $type->hasFilterableColumns()) {
$criteria[] = new WhereConditionsFilterCriteria($filter, $value, $type);
continue;
}
if ($filter instanceof Filter && $argument instanceof FilterArgument) {
$criteria[] = new WhereFilterCriteria($filter, $value, $argument);
continue;
}
}
return $criteria;
}
/**
* Get the filter values.
*/
public function getFilterValues(): array
{
$value = $this->value;
if ($value instanceof Collection) {
return $value->all();
}
return Arr::wrap($value);
}
/**
* Apply the filtering to the current Eloquent builder.
*/
abstract public function filter(Builder $builder): Builder;
}
@@ -1,106 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Criteria\Filter;
use App\Concerns\Actions\GraphQL\FiltersModels;
use App\Contracts\GraphQL\Fields\FilterableField;
use App\Enums\GraphQL\Filter\Clause;
use App\Enums\GraphQL\Filter\ComparisonOperator;
use App\Enums\GraphQL\Filter\LogicalOperator;
use App\GraphQL\Filter\Filter;
use App\GraphQL\Schema\Enums\FilterableColumns;
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
{
use FiltersModels {
filter as filterModels;
}
/**
* @var Collection<string, Field&FilterableField>
*/
protected Collection $filterableFields;
public function __construct(
protected Filter $filter,
protected $value,
protected EloquentType $type,
) {
parent::__construct($filter, $value);
}
/**
* Apply the filtering to the current Eloquent builder.
*/
public function filter(Builder $builder): Builder
{
$this->filterableFields = new FilterableColumns($this->type)->getValues();
foreach ($this->value as $where) {
$this->filterWhereCondition($builder, $where, LogicalOperator::AND);
}
return $builder;
}
/**
* Apply recursively every where condition.
*
* @param array<string, mixed> $where
*/
private function filterWhereCondition(Builder $builder, array $where, LogicalOperator $logical): Builder
{
$fieldName = Arr::get($where, 'field');
$value = Arr::get($where, 'value');
if (filled($fieldName) && filled($value)) {
$field = $this->filterableFields->get($fieldName);
$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 {
foreach (Arr::array($where, 'AND', []) as $whereCondition) {
$this->filterWhereCondition($builder, $whereCondition, LogicalOperator::AND);
}
});
$builder->where(function (Builder $builder) use ($where): void {
foreach (Arr::array($where, 'OR', []) as $whereCondition) {
$this->filterWhereCondition($builder, $whereCondition, LogicalOperator::OR);
}
});
return $builder;
}
}
@@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Criteria\Filter;
use App\GraphQL\Argument\FilterArgument;
use App\GraphQL\Filter\Filter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
class WhereFilterCriteria extends FilterCriteria
{
public function __construct(
protected Filter $filter,
protected $value,
protected FilterArgument $argument,
) {
parent::__construct($filter, $value);
}
/**
* Apply the filtering to the current Eloquent builder.
*/
public function filter(Builder $builder): Builder
{
return $builder->where(
$builder->qualifyColumn($this->filter->getColumn()),
$this->argument->getComparisonOperator()->value,
Arr::first($this->filter->getFilterValues($this->getFilterValues())),
);
}
}
@@ -1,30 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Criteria\Filter;
use App\GraphQL\Filter\Filter;
use Illuminate\Database\Eloquent\Builder;
class WhereInFilterCriteria extends FilterCriteria
{
public function __construct(
protected Filter $filter,
protected $value,
protected bool $not = false,
) {
parent::__construct($filter, $value);
}
/**
* Apply the filtering to the current Eloquent builder.
*/
public function filter(Builder $builder): Builder
{
return $builder->{$this->not ? 'whereNotIn' : 'whereIn'}(
$builder->qualifyColumn($this->filter->getColumn()),
$this->filter->getFilterValues($this->getFilterValues())
);
}
}
@@ -0,0 +1,167 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Directives;
use GraphQL\Deferred;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Nuwave\Lighthouse\Exceptions\DefinitionException;
use Nuwave\Lighthouse\Execution\BatchLoader\BatchLoaderRegistry;
use Nuwave\Lighthouse\Execution\BatchLoader\RelationBatchLoader;
use Nuwave\Lighthouse\Execution\ModelsLoader\AggregateModelsLoader;
use Nuwave\Lighthouse\Execution\ResolveInfo;
use Nuwave\Lighthouse\Schema\Directives\AggregateDirective;
use Nuwave\Lighthouse\Schema\Values\FieldValue;
use Nuwave\Lighthouse\Support\Contracts\FieldManipulator;
use Nuwave\Lighthouse\Support\Contracts\FieldResolver;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;
class AggregateCustomDirective extends AggregateDirective implements FieldManipulator, FieldResolver
{
public static function definition(): string
{
return /** @lang GraphQL */ <<<'GRAPHQL'
"""
Returns an aggregate of a column in a given relationship or model.
"""
directive @aggregateCustom(
"""
The column to aggregate.
"""
column: String!
"""
The aggregate function to compute.
"""
function: AggregateFunction!
"""
The relationship with the column to aggregate.
Mutually exclusive with `model` and `builder`.
"""
relation: String
"""
The model with the column to aggregate.
Mutually exclusive with `relation` and `builder`.
"""
model: String
"""
Point to a function that provides a Query Builder instance.
Consists of two parts: a class name and a method name, seperated by an `@` symbol.
If you pass only a class name, the method name defaults to `__invoke`.
Mutually exclusive with `relation` and `model`.
"""
builder: String
"""
Apply scopes to the underlying query.
"""
scopes: [String!]
) on FIELD_DEFINITION
"""
Options for the `function` argument of `@aggregate`.
"""
enum AggregateFunction {
"""
Return the average value.
"""
AVG
"""
Return the sum.
"""
SUM
"""
Return the minimum.
"""
MIN
"""
Return the maximum.
"""
MAX
"""
Return the boolean value of the relation existence.
"""
EXISTS
}
GRAPHQL;
}
public function resolveField(FieldValue $fieldValue): callable
{
$modelArg = $this->directiveArgValue('model');
if (is_string($modelArg)) {
return function (mixed $root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) use ($modelArg) {
$builder = $this->namespaceModelClass($modelArg)::query();
$this->makeBuilderDecorator($root, $args, $context, $resolveInfo)($builder);
return $builder->{$this->function()}($this->column());
};
}
$relation = $this->directiveArgValue('relation');
if (is_string($relation)) {
return function (Model $parent, array $args, GraphQLContext $context, ResolveInfo $resolveInfo): Deferred {
$relationBatchLoader = BatchLoaderRegistry::instance(
[...$this->qualifyPath($args, $resolveInfo), $this->function(), $this->column()],
fn (): RelationBatchLoader => new RelationBatchLoader(
new AggregateModelsLoader(
$this->relation(),
$this->column(),
$this->function(),
$this->makeBuilderDecorator($parent, $args, $context, $resolveInfo),
),
),
);
$deferred = $relationBatchLoader->load($parent);
return new Deferred(function () use ($deferred) {
$result = $deferred->result;
return $result ?? 0;
});
};
}
$modelArg = $this->directiveArgValue('model');
if (is_string($modelArg)) {
return function (mixed $root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) use ($modelArg) {
$query = $this->namespaceModelClass($modelArg)::query();
$this->makeBuilderDecorator($root, $args, $context, $resolveInfo)($query);
return $query->{$this->function()}($this->column());
};
}
if ($this->directiveHasArgument('builder')) {
$builderResolver = $this->getResolverFromArgument('builder');
return function (mixed $root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) use ($builderResolver) {
$builder = $builderResolver($root, $args, $context, $resolveInfo);
assert(
$builder instanceof QueryBuilder || $builder instanceof EloquentBuilder,
"The method referenced by the builder argument of the @{$this->name()} directive on {$this->nodeName()} must return a Builder.",
);
$this->makeBuilderDecorator($root, $args, $context, $resolveInfo)($builder);
return $builder->{$this->function()}($this->column());
};
}
throw new DefinitionException("One of the arguments `model`, `relation` or `builder` must be assigned to the '{$this->name()}' directive on '{$this->nodeName()}'.");
}
}
@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Directives;
use Nuwave\Lighthouse\Support\Contracts\FieldManipulator;
class BelongsToManyCustomDirective extends RelationCustomDirective implements FieldManipulator
{
public static function definition(): string
{
return /** @lang GraphQL */ <<<'GRAPHQL'
"""
Resolves a field through the Eloquent `BelongsToMany` relationship.
"""
directive @belongsToManyCustom(
"""
Specify the relationship method name in the model class,
if it is named different from the field in the schema.
"""
relation: String
"""
Apply scopes to the underlying query.
"""
scopes: [String!]
"""
Allows to resolve the relation as a paginated list.
"""
type: BelongsToManyType
"""
Allow clients to query paginated lists without specifying the amount of items.
Overrules the `pagination.default_count` setting from `lighthouse.php`.
Setting this to `null` means clients have to explicitly ask for the count.
"""
defaultCount: Int
"""
Limit the maximum amount of items that clients can request from paginated lists.
Overrules the `pagination.max_count` setting from `lighthouse.php`.
Setting this to `null` means the count is unrestricted.
"""
maxCount: Int
"""
Specify a custom type that implements the Edge interface
to extend edge object.
Only applies when using Relay style "connection" pagination.
"""
edgeType: String
) on FIELD_DEFINITION
"""
Options for the `type` argument of `@belongsToMany`.
"""
enum BelongsToManyType {
"""
Offset-based pagination, similar to the Laravel default.
"""
PAGINATOR
"""
Offset-based pagination like the Laravel "Simple Pagination", which does not count the total number of records.
"""
SIMPLE
"""
Cursor-based pagination, compatible with the Relay specification.
"""
CONNECTION
}
GRAPHQL;
}
}
@@ -0,0 +1,170 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Directives;
use GraphQL\Error\Error;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Gate;
use Nuwave\Lighthouse\Auth\BaseCanDirective;
use Nuwave\Lighthouse\Exceptions\ClientSafeModelNotFoundException;
use Nuwave\Lighthouse\Exceptions\DefinitionException;
use Nuwave\Lighthouse\Execution\ResolveInfo;
use Nuwave\Lighthouse\Schema\AST\ASTHelper;
use Nuwave\Lighthouse\SoftDeletes\ForceDeleteDirective;
use Nuwave\Lighthouse\SoftDeletes\RestoreDirective;
use Nuwave\Lighthouse\SoftDeletes\TrashedDirective;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;
use Nuwave\Lighthouse\Support\Utils;
class CanFindMultipleDirective extends BaseCanDirective
{
public static function definition(): string
{
$commonArguments = BaseCanDirective::commonArguments();
$commonTypes = BaseCanDirective::commonTypes();
return /** @lang GraphQL */ <<<GRAPHQL
{$commonTypes}
"""
Check a Laravel Policy to ensure the current user is authorized to access a field.
Query for specific model instances to check the policy against, using primary key(s) from specified argument.
"""
directive @canFindMultiple(
{$commonArguments}
"""
Specify the name of the field arguments that contains its columns[index].
You may pass the string in dot notation to use nested inputs.
"""
find: [String!]!
"""
Specify the class name of the model to use.
"""
models: [String!]!
"""
Specify the name of the columns that reference the find argument.
"""
columns: [String!]!
"""
Should the query fail when the models of `find` were not found?
"""
findOrFail: Boolean! = true
"""
Apply scopes to the underlying query.
"""
scopes: [String!]
) repeatable on FIELD_DEFINITION
GRAPHQL;
}
protected function authorizeRequest(mixed $root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo, callable $resolver, callable $authorize): mixed
{
$ability = $this->directiveArgValue('ability');
Gate::authorize($ability, [ASTHelper::modelName($this->definitionNode), ...$this->modelsToCheck($root, $args, $context, $resolveInfo)]);
return null;
}
/**
* @param array<string, mixed> $args
* @return iterable<Model|class-string<Model>>
*/
protected function modelsToCheck(mixed $root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo): iterable
{
$findList = $this->directiveArgValue('find');
$findValues = [];
foreach ($findList as $find) {
$findValues[] = Arr::get($args, $find) ?? throw self::missingKeyToFindModel($find);
}
$models = [];
foreach ($this->getModelClasses() as $modelClass) {
$queryBuilder = $modelClass::query();
$argumentSetDirectives = $resolveInfo->argumentSet->directives;
$directivesContainsForceDelete = $argumentSetDirectives->contains(
Utils::instanceofMatcher(ForceDeleteDirective::class),
);
if ($directivesContainsForceDelete) {
/** @see \Illuminate\Database\Eloquent\SoftDeletes */
// @phpstan-ignore-next-line because it involves mixins
$queryBuilder->withTrashed();
}
$directivesContainsRestore = $argumentSetDirectives->contains(
Utils::instanceofMatcher(RestoreDirective::class),
);
if ($directivesContainsRestore) {
/** @see \Illuminate\Database\Eloquent\SoftDeletes */
// @phpstan-ignore-next-line because it involves mixins
$queryBuilder->onlyTrashed();
}
try {
$enhancedBuilder = $resolveInfo->enhanceBuilder(
$queryBuilder,
$this->directiveArgValue('scopes', []),
$root,
$args,
$context,
$resolveInfo,
Utils::instanceofMatcher(TrashedDirective::class),
);
assert($enhancedBuilder instanceof EloquentBuilder);
foreach ($findValues as $index => $findValue) {
if ($findValue instanceof Model) {
$models[] = $findValue;
} else {
$models[] = $this->directiveArgValue('findOrFail', false)
? $enhancedBuilder->where($this->directiveArgValue('columns')[$index], $findValue)->firstOrFail()
: $enhancedBuilder->where($this->directiveArgValue('columns')[$index], $findValue)->first();
}
}
} catch (ModelNotFoundException $modelNotFoundException) {
throw ClientSafeModelNotFoundException::fromLaravel($modelNotFoundException);
}
}
return $models;
}
/**
* Get the model class from the `model` argument of the field.
*
* @api
*
* @param string $argumentName The default argument name "model" may be overwritten
* @return class-string<Model>[]
*/
protected function getModelClasses(string $argumentName = 'models'): array
{
$models = $this->directiveArgValue($argumentName, ASTHelper::modelName($this->definitionNode))
?? throw new DefinitionException("Could not determine a model name for the '@{$this->name()}' directive on '{$this->nodeName()}'.");
$namespaces = [];
foreach ($models as $model) {
$namespaces[] = $this->namespaceModelClass($model);
}
return $namespaces;
}
public static function missingKeyToFindModel(string $find): Error
{
return new Error("Got no key to find a model at the expected input path: {$find}.");
}
}
@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Directives;
use Nuwave\Lighthouse\Support\Contracts\FieldManipulator;
class HasManyCustomDirective extends RelationCustomDirective implements FieldManipulator
{
public static function definition(): string
{
return /** @lang GraphQL */ <<<'GRAPHQL'
"""
Corresponds to [the Eloquent relationship HasMany](https://laravel.com/docs/eloquent-relationships#one-to-many).
"""
directive @hasManyCustom(
"""
Specify the relationship method name in the model class,
if it is named different from the field in the schema.
"""
relation: String
"""
Apply scopes to the underlying query.
"""
scopes: [String!]
"""
Allows to resolve the relation as a paginated list.
"""
type: HasManyType
"""
Allow clients to query paginated lists without specifying the amount of items.
Overrules the `pagination.default_count` setting from `lighthouse.php`.
Setting this to `null` means clients have to explicitly ask for the count.
"""
defaultCount: Int
"""
Limit the maximum amount of items that clients can request from paginated lists.
Overrules the `pagination.max_count` setting from `lighthouse.php`.
Setting this to `null` means the count is unrestricted.
"""
maxCount: Int
"""
Specify a custom type that implements the Edge interface
to extend edge object.
Only applies when using Relay style "connection" pagination.
"""
edgeType: String
) on FIELD_DEFINITION
"""
Options for the `type` argument of `@hasMany`.
"""
enum HasManyType {
"""
Offset-based pagination, similar to the Laravel default.
"""
PAGINATOR
"""
Offset-based pagination like the Laravel "Simple Pagination", which does not count the total number of records.
"""
SIMPLE
"""
Cursor-based pagination, compatible with the Relay specification.
"""
CONNECTION
}
GRAPHQL;
}
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Directives;
use Illuminate\Support\Str;
use Nuwave\Lighthouse\Schema\Directives\BaseDirective;
use Nuwave\Lighthouse\Schema\Values\FieldValue;
use Nuwave\Lighthouse\Support\Contracts\FieldResolver;
class LocalizedDirective extends BaseDirective implements FieldResolver
{
public static function definition(): string
{
return /** @lang GraphQL */ <<<'GRAPHQL'
directive @localized on FIELD_DEFINITION
GRAPHQL;
}
/**
* Returns a field resolver function.
*
* @return callable(mixed, array<string, mixed>, \Nuwave\Lighthouse\Support\Contracts\GraphQLContext, \Nuwave\Lighthouse\Execution\ResolveInfo): mixed
*/
public function resolveField(FieldValue $fieldValue): callable
{
return function ($root) use ($fieldValue) {
$field = Str::snake(Str::before($fieldValue->getFieldName(), 'Localized'));
return $root->getAttribute($field)?->localize();
};
}
}
@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Directives;
use App\GraphQL\Pagination\PaginationManipulator;
use GraphQL\Language\AST\FieldDefinitionNode;
use GraphQL\Language\AST\InterfaceTypeDefinitionNode;
use GraphQL\Language\AST\ObjectTypeDefinitionNode;
use Nuwave\Lighthouse\Exceptions\DefinitionException;
use Nuwave\Lighthouse\Pagination\PaginationType;
use Nuwave\Lighthouse\Schema\AST\ASTHelper;
use Nuwave\Lighthouse\Schema\AST\DocumentAST;
use Nuwave\Lighthouse\Schema\Directives\RelationDirective;
abstract class RelationCustomDirective extends RelationDirective
{
public function manipulateFieldDefinition(
DocumentAST &$documentAST,
FieldDefinitionNode &$fieldDefinition,
ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode &$parentType,
): void {
$paginationType = $this->paginationType();
// We default to not changing the field if no pagination type is set explicitly.
// This makes sense for relations, as there should not be too many entries.
if (! $paginationType instanceof PaginationType) {
return;
}
$paginationManipulator = new PaginationManipulator($documentAST);
$relatedModelName = ASTHelper::modelName($fieldDefinition);
if (is_string($relatedModelName)) {
try {
$modelClass = $this->namespaceModelClass($relatedModelName);
$paginationManipulator->setModelClass($modelClass);
} catch (DefinitionException) {
/** @see \Tests\Integration\Schema\Directives\HasManyDirectiveTest::testDoesNotRequireModelClassForPaginatedHasMany() */
}
}
$paginationManipulator->transformToPaginatedField(
$paginationType,
$fieldDefinition,
$parentType,
$this->paginationDefaultCount(),
$this->paginationMaxCount(),
$this->edgeType($documentAST),
);
}
protected function edgeType(DocumentAST $documentAST): ?ObjectTypeDefinitionNode
{
if ($edgeTypeName = $this->directiveArgValue('edgeType')) {
$edgeType = $documentAST->types[$edgeTypeName] ?? null;
if (! $edgeType instanceof ObjectTypeDefinitionNode) {
throw new DefinitionException("The `edgeType` argument of @{$this->name()} on {$this->nodeName()} must reference an existing object type definition.");
}
return $edgeType;
}
return null;
}
protected function paginationMaxCount(): ?int
{
return $this->directiveArgValue('maxCount', $this->lighthouseConfig['pagination']['relation']['max_count']);
}
protected function paginationDefaultCount(): ?int
{
return $this->directiveArgValue('defaultCount', $this->lighthouseConfig['pagination']['relation']['default_count']);
}
}
+51
View File
@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Directives;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\Http\Api\Field\AggregateFunction;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Nuwave\Lighthouse\Schema\Directives\BaseDirective;
use Nuwave\Lighthouse\Support\Contracts\ArgBuilderDirective;
use Nuwave\Lighthouse\Support\Contracts\ArgDirective;
use UnitEnum;
class SortDirective extends BaseDirective implements ArgBuilderDirective, ArgDirective
{
public static function definition(): string
{
return /** @lang GraphQL */ <<<'GRAPHQL'
directive @sort on ARGUMENT_DEFINITION
GRAPHQL;
}
/**
* Add additional constraints to the builder based on the given argument value.
*
* @param QueryBuilder|EloquentBuilder|Relation $builder the builder used to resolve the field
* @param array<int, UnitEnum&EnumSort> $value the client given value of the argument
* @return QueryBuilder|EloquentBuilder|Relation the modified builder
*/
public function handleBuilder(QueryBuilder|EloquentBuilder|Relation $builder, mixed $value): QueryBuilder|EloquentBuilder|Relation
{
foreach ($value as $sort) {
$criteria = $sort->getSortCriteria();
if ($criteria->aggregateRelation !== null) {
match ($criteria->function) {
AggregateFunction::EXISTS,
AggregateFunction::COUNT => $builder->{"with{$criteria->function->value}"}($criteria->aggregateRelation),
default => $builder->{"with{$criteria->function->value}"}($criteria->aggregateRelation, $criteria->getColumn()),
};
}
$criteria->sort($builder);
}
return $builder;
}
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Directives;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Nuwave\Lighthouse\Schema\Directives\BaseDirective;
use Nuwave\Lighthouse\Schema\Values\FieldValue;
use Nuwave\Lighthouse\Support\Contracts\FieldResolver;
class TimestampDirective extends BaseDirective implements FieldResolver
{
public static function definition(): string
{
return /** @lang GraphQL */ <<<'GRAPHQL'
directive @timestamp(attribute: String) on FIELD_DEFINITION
GRAPHQL;
}
/**
* Returns a field resolver function.
*
* @return callable(mixed, array<string, mixed>, \Nuwave\Lighthouse\Support\Contracts\GraphQLContext, \Nuwave\Lighthouse\Execution\ResolveInfo): mixed
*/
public function resolveField(FieldValue $fieldValue): callable
{
return function (Model|array $root, array $args) use ($fieldValue) {
$format = Arr::string($args, 'format');
/** @var Carbon|null $field */
$field = $root instanceof Model
? $root->getAttribute($this->directiveArgValue('attribute') ?? $fieldValue->getFieldName())
: $root[$fieldValue->getFieldName()];
return $field?->format($format);
};
}
}
-6
View File
@@ -5,16 +5,10 @@ declare(strict_types=1);
namespace App\GraphQL\Filter;
use App\Rules\Api\IsValidBoolean;
use GraphQL\Type\Definition\Type;
use Illuminate\Support\Arr;
class BooleanFilter extends Filter
{
public function getBaseType(): Type
{
return Type::boolean();
}
/**
* Convert filter values if needed. By default, no conversion is needed.
*/
-52
View File
@@ -1,52 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Filter;
use App\Enums\Http\Api\Filter\AllowedDateFormat;
use DateTime;
use GraphQL\Type\Definition\Type;
use Illuminate\Support\Arr;
class DateTimeTzFilter extends Filter
{
public function getBaseType(): Type
{
return Type::string();
}
/**
* Convert filter values if needed. By default, no conversion is needed.
*/
protected function convertFilterValues(array $filterValues): array
{
return Arr::map(
$filterValues,
function (string $filterValue): ?string {
foreach (AllowedDateFormat::cases() as $allowedDateFormat) {
$date = DateTime::createFromFormat('!'.$allowedDateFormat->value, $filterValue);
if ($date && $date->format($allowedDateFormat->value) === $filterValue) {
return $date->format(AllowedDateFormat::YMDHISU->value);
}
}
return null;
}
);
}
/**
* Get the validation rules for the filter.
*/
protected function getRules(): array
{
$allowedDateFormats = array_column(AllowedDateFormat::cases(), 'value');
$dateFormats = implode(',', $allowedDateFormats);
return [
'required',
"date_format:$dateFormats",
];
}
}
+3 -10
View File
@@ -6,9 +6,7 @@ namespace App\GraphQL\Filter;
use BackedEnum;
use Closure;
use GraphQL\Type\Definition\Type;
use Illuminate\Support\Arr;
use Rebing\GraphQL\Support\Facades\GraphQL;
use UnitEnum;
class EnumFilter extends Filter
@@ -17,16 +15,11 @@ class EnumFilter extends Filter
* @param class-string<UnitEnum> $enumClass
*/
public function __construct(
string $field,
protected string $enumName,
protected readonly string $enumClass,
?string $column = null,
string $column,
) {
parent::__construct($field, $column);
}
public function getBaseType(): Type
{
return GraphQL::type(class_basename($this->enumClass));
parent::__construct($enumName, $column);
}
/**
+5 -113
View File
@@ -4,47 +4,18 @@ declare(strict_types=1);
namespace App\GraphQL\Filter;
use App\Enums\GraphQL\Filter\Clause;
use App\Enums\Http\Api\Filter\ComparisonOperator;
use App\GraphQL\Argument\Argument;
use App\GraphQL\Argument\FilterArgument;
use GraphQL\Type\Definition\Type;
use Illuminate\Support\Facades\Validator;
abstract class Filter
{
/**
* @var Argument[]
*/
protected array $arguments = [];
public function __construct(
protected readonly string $fieldName,
protected readonly ?string $column = null,
protected readonly Clause $clause = Clause::WHERE,
protected string $enumName,
protected readonly string $column,
) {}
public function getFieldName(): string
{
return $this->fieldName;
}
public function getColumn(): string
{
return $this->column ?? $this->getFieldName();
}
public function getClause(): Clause
{
return $this->clause;
}
/**
* @return Argument[]
*/
public function getArguments(): array
{
return $this->arguments;
return $this->column;
}
/**
@@ -69,8 +40,8 @@ abstract class Filter
{
foreach ($filterValues as $filterValue) {
Validator::make(
[$this->fieldName => $filterValue],
[$this->fieldName => $this->getRules()],
[$this->enumName => $filterValue],
[$this->enumName => $this->getRules()],
)->validate();
}
}
@@ -82,83 +53,4 @@ abstract class Filter
{
return [];
}
/**
* Allow the Equal operator to the filter.
*/
public function useEq(mixed $defaultValue = null): static
{
$this->arguments[] = new FilterArgument($this->fieldName, $this->getBaseType(), ComparisonOperator::EQ)
->withDefaultValue($defaultValue);
return $this;
}
/**
* Allow the Greater operator to the filter.
*/
public function useGt(mixed $defaultValue = null): static
{
$this->arguments[] = new FilterArgument($this->fieldName.'_greater', $this->getBaseType(), ComparisonOperator::GT)
->withDefaultValue($defaultValue);
return $this;
}
/**
* Allow the Lesser operator to the filter.
*/
public function useLt(mixed $defaultValue = null): static
{
$this->arguments[] = new FilterArgument($this->fieldName.'_lesser', $this->getBaseType(), ComparisonOperator::LT)
->withDefaultValue($defaultValue);
return $this;
}
/**
* Allow the Like operator to the filter.
*/
public function useLike(mixed $defaultValue = null): static
{
$this->arguments[] = new FilterArgument($this->fieldName.'_like', $this->getBaseType(), ComparisonOperator::LIKE)
->withDefaultValue($defaultValue);
return $this;
}
/**
* Allow the Not Like operator to the filter.
*/
public function useNotLike(mixed $defaultValue = null): static
{
$this->arguments[] = new FilterArgument($this->fieldName.'_not_like', $this->getBaseType(), ComparisonOperator::NOTLIKE)
->withDefaultValue($defaultValue);
return $this;
}
/**
* Allow the IN operator to the filter.
*/
public function useIn(mixed $defaultValue = null): static
{
$this->arguments[] = new Argument($this->fieldName.'_in', Type::listOf(Type::nonNull($this->getBaseType())))
->withDefaultValue($defaultValue);
return $this;
}
/**
* Allow the NOT IN operator to the filter.
*/
public function useNotIn(mixed $defaultValue = null): static
{
$this->arguments[] = new Argument($this->fieldName.'_not_in', Type::listOf(Type::nonNull($this->getBaseType())))
->withDefaultValue($defaultValue);
return $this;
}
abstract public function getBaseType(): Type;
}
-6
View File
@@ -4,16 +4,10 @@ declare(strict_types=1);
namespace App\GraphQL\Filter;
use GraphQL\Type\Definition\Type;
use Illuminate\Support\Arr;
class FloatFilter extends Filter
{
public function getBaseType(): Type
{
return Type::float();
}
/**
* Convert filter values if needed. By default, no conversion is needed.
*/

Some files were not shown because too many files have changed in this diff Show More