feat(graphql): build sort enums on demand for better management (#1177)

This commit is contained in:
Kyrch
2026-04-19 09:50:00 -03:00
committed by GitHub
parent 80d59f7e45
commit 75f391cc65
66 changed files with 1252 additions and 449 deletions
+7 -8
View File
@@ -8,10 +8,9 @@ use App\Concerns\Actions\GraphQL\ConstrainsEagerLoads;
use App\Concerns\Actions\GraphQL\FieldSelection; use App\Concerns\Actions\GraphQL\FieldSelection;
use App\Concerns\Actions\GraphQL\PaginatesModels; use App\Concerns\Actions\GraphQL\PaginatesModels;
use App\Concerns\Actions\GraphQL\SortsModels; use App\Concerns\Actions\GraphQL\SortsModels;
use App\Contracts\GraphQL\EnumSort;
use App\GraphQL\Argument\SortArgument; use App\GraphQL\Argument\SortArgument;
use App\GraphQL\Criteria\Sort\RelationSortCriteria; use App\GraphQL\Criteria\Sort\RelationSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Schema\Enums\SortableColumns;
use App\GraphQL\Schema\Types\BaseType; use App\GraphQL\Schema\Types\BaseType;
use App\Rules\GraphQL\Argument\FirstArgumentRule; use App\Rules\GraphQL\Argument\FirstArgumentRule;
use App\Scout\Criteria; use App\Scout\Criteria;
@@ -21,6 +20,7 @@ use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use UnitEnum;
class IndexAction class IndexAction
{ {
@@ -35,7 +35,7 @@ class IndexAction
$this->filter($builder, $args, $type); $this->filter($builder, $args, $type);
$this->sort($builder, $args, $type); $this->sort($builder, $args);
$this->constrainEagerLoads($builder, $resolveInfo, $type); $this->constrainEagerLoads($builder, $resolveInfo, $type);
@@ -53,7 +53,7 @@ class IndexAction
$this->filter($builder, $args, $type); $this->filter($builder, $args, $type);
$this->sort($builder, $args, $type); $this->sort($builder, $args);
$this->constrainEagerLoads($builder, $resolveInfo, $type); $this->constrainEagerLoads($builder, $resolveInfo, $type);
}; };
@@ -66,15 +66,14 @@ class IndexAction
'first' => ['required', 'integer', 'min:1', new FirstArgumentRule()], 'first' => ['required', 'integer', 'min:1', new FirstArgumentRule()],
])->validate(); ])->validate();
/** @var array<int, UnitEnum&EnumSort> $sorts */
$sorts = Arr::get($args, SortArgument::ARGUMENT, []); $sorts = Arr::get($args, SortArgument::ARGUMENT, []);
$criteria = Arr::get(new SortableColumns($type)->getAttributes(), 'criteria');
$sortsRaw = []; $sortsRaw = [];
foreach ($sorts as $sort) { foreach ($sorts as $sort) {
/** @var SortCriteria $criterion */ $criterion = $sort->getSortCriteria();
$criterion = Arr::get($criteria, $sort);
$column = $criterion->getSort()->getColumn(); $column = $criterion->getColumn();
$direction = $criterion->getDirection(); $direction = $criterion->getDirection();
$isString = $criterion->isStringField(); $isString = $criterion->isStringField();
@@ -119,7 +119,7 @@ trait ConstrainsEagerLoads
$this->filter($builder, $args, $type); $this->filter($builder, $args, $type);
$this->sort($builder, $args, $type, $relation, $graphqlRelation); $this->sort($builder, $args);
$fields = Arr::get($selection, 'selectionSet.data.data.selectionSet') $fields = Arr::get($selection, 'selectionSet.data.data.selectionSet')
?? Arr::get($selection, 'selectionSet.edges.edges.selectionSet.node.node.selectionSet') ?? Arr::get($selection, 'selectionSet.edges.edges.selectionSet.node.node.selectionSet')
+5 -23
View File
@@ -4,38 +4,20 @@ declare(strict_types=1);
namespace App\Concerns\Actions\GraphQL; namespace App\Concerns\Actions\GraphQL;
use App\Contracts\GraphQL\EnumSort;
use App\GraphQL\Argument\SortArgument; use App\GraphQL\Argument\SortArgument;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Schema\Enums\SortableColumns;
use App\GraphQL\Schema\Fields\Relations\Relation as GraphQLRelation;
use App\GraphQL\Schema\Types\BaseType;
use App\GraphQL\Schema\Unions\BaseUnion;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
trait SortsModels trait SortsModels
{ {
public function sort(Builder $builder, array $args, BaseType|BaseUnion $type, ?Relation $relation = null, ?GraphQLRelation $graphqlRelation = null): Builder public function sort(Builder $builder, array $args): Builder
{ {
$sorts = Arr::get($args, SortArgument::ARGUMENT); /** @var EnumSort[] $sorts */
$sorts = Arr::get($args, SortArgument::ARGUMENT, []);
if (blank($sorts)) {
return $builder;
}
$relation = $relation instanceof BelongsToMany
? $relation
: null;
$criteria = Arr::get(new SortableColumns($type, $graphqlRelation?->getPivotType(), $relation)->getAttributes(), 'criteria');
foreach ($sorts as $sort) { foreach ($sorts as $sort) {
/** @var SortCriteria $criterion */ $sort->getSortCriteria()->sort($builder);
$criterion = Arr::get($criteria, $sort);
$criterion->sort($builder);
} }
return $builder; return $builder;
+14
View File
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Contracts\GraphQL;
use App\GraphQL\Criteria\Sort\SortCriteria;
interface EnumSort
{
public function getSortCriteria(): SortCriteria;
public function shouldQualifyColumn(): bool;
}
@@ -1,12 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Contracts\GraphQL\Fields;
use App\GraphQL\Sort\Sort;
interface SortableField
{
public function getSort(): Sort;
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
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\Models\Admin\Announcement;
enum AnnouncementSort implements EnumSort
{
case ID;
case ID_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
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\Models\Admin\Dump;
enum DumpSort implements EnumSort
{
case ID;
case ID_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
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\Models\Document\Page;
enum PageSort 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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
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\Models\List\Playlist\PlaylistTrack;
enum PlaylistTrackSort implements EnumSort
{
case ID;
case ID_DESC;
case POSITION;
case POSITION_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Sort\List;
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\Models\List\Playlist;
enum PlaylistSort implements EnumSort
{
case ID;
case ID_DESC;
case NAME;
case NAME_DESC;
case LIKES_COUNT;
case LIKES_COUNT_DESC;
case TRACKS_COUNT;
case TRACKS_COUNT_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, 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,
};
}
}
@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Artist;
use App\Pivots\Wiki\ArtistMember;
enum ArtistMemberSort implements EnumSort
{
case ID;
case ID_DESC;
case NAME;
case NAME_DESC;
case MEMBER_ALIAS;
case MEMBER_ALIAS_DESC;
case MEMBER_AS;
case MEMBER_AS_DESC;
case MEMBER_RELEVANCE;
case MEMBER_RELEVANCE_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Image;
use App\Pivots\Morph\Imageable;
enum ImageableSort implements EnumSort
{
case ID;
case ID_DESC;
case DEPTH;
case DEPTH_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace App\Enums\GraphQL\Sort\Wiki\Anime\AnimeTheme;
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\Models\Wiki\Anime\Theme\AnimeThemeEntry;
enum AnimeThemeEntrySort implements EnumSort
{
case ID;
case ID_DESC;
case EPISODES;
case EPISODES_DESC;
case VERSION;
case VERSION_DESC;
case LIKES_COUNT;
case LIKES_COUNT_DESC;
case TRACKS_COUNT;
case TRACKS_COUNT_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, 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,
};
}
}
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Anime\AnimeTheme;
use App\Models\Wiki\Song;
enum AnimeThemeSort implements EnumSort
{
case ID;
case ID_DESC;
case SEQUENCE;
case SEQUENCE_DESC;
case CREATED_AT;
case CREATED_AT_DESC;
case UPDATED_AT;
case UPDATED_AT_DESC;
case SONG_TITLE;
case SONG_TITLE_DESC;
case SONG_TITLE_NATIVE;
case SONG_TITLE_NATIVE_DESC;
case RANDOM;
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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+49
View File
@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Anime;
enum AnimeSort implements EnumSort
{
case ID;
case ID_DESC;
case NAME;
case NAME_DESC;
case YEAR;
case YEAR_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Artist;
enum ArtistSort 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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+53
View File
@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Audio;
enum AudioSort implements EnumSort
{
case ID;
case ID_DESC;
case BASENAME;
case BASENAME_DESC;
case FILENAME;
case FILENAME_DESC;
case SIZE;
case SIZE_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Image;
enum ImageSort implements EnumSort
{
case ID;
case ID_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Series;
enum SeriesSort 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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Song\Performance;
enum PerformanceSort implements EnumSort
{
case ID;
case ID_DESC;
case ALIAS;
case ALIAS_DESC;
case AS;
case AS_DESC;
case MEMBER_ALIAS;
case MEMBER_ALIAS_DESC;
case MEMBER_AS;
case MEMBER_AS_DESC;
case RELEVANCE;
case RELEVANCE_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+49
View File
@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Song;
enum SongSort implements EnumSort
{
case ID;
case ID_DESC;
case TITLE;
case TITLE_DESC;
case TITLE_NATIVE;
case TITLE_NATIVE_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Studio;
enum StudioSort 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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Synonym;
enum SynonymSort implements EnumSort
{
case ID;
case ID_DESC;
case TEXT;
case TEXT_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
+57
View File
@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
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\Models\Wiki\Video;
enum VideoSort implements EnumSort
{
case ID;
case ID_DESC;
case BASENAME;
case BASENAME_DESC;
case FILENAME;
case FILENAME_DESC;
case RESOLUTION;
case RESOLUTION_DESC;
case SIZE;
case SIZE_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, 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, ''),
};
}
public function shouldQualifyColumn(): bool
{
return true;
}
}
@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace App\Enums\GraphQL\Sort; namespace App\Enums\GraphQL;
enum SortDirection: string enum SortDirection: string
{ {
+8 -10
View File
@@ -4,25 +4,23 @@ declare(strict_types=1);
namespace App\GraphQL\Argument; namespace App\GraphQL\Argument;
use App\GraphQL\Schema\Enums\SortableColumns; use App\Contracts\GraphQL\EnumSort;
use App\GraphQL\Schema\Types\BaseType; use App\GraphQL\Schema\Types\BaseType;
use App\GraphQL\Schema\Types\Pivot\PivotType;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
use Illuminate\Support\Arr;
use Rebing\GraphQL\Support\Facades\GraphQL; use Rebing\GraphQL\Support\Facades\GraphQL;
use UnitEnum;
class SortArgument extends Argument class SortArgument extends Argument
{ {
final public const string ARGUMENT = 'sort'; final public const string ARGUMENT = 'sort';
public function __construct(protected BaseType $type, ?PivotType $pivotType = null) /**
* @param class-string<UnitEnum&EnumSort> $sortEnum
*/
public function __construct(protected BaseType $type, ?string $sortEnum = null)
{ {
$sortableColumns = new SortableColumns($type, $pivotType); $enum = $sortEnum ?? $type->getEnumSortClass();
GraphQL::addType($sortableColumns); parent::__construct(self::ARGUMENT, Type::listOf(Type::nonNull(GraphQL::type(class_basename($enum)))));
$name = Arr::get($sortableColumns->getAttributes(), 'name');
parent::__construct(self::ARGUMENT, Type::listOf(Type::nonNull(GraphQL::type($name))));
} }
} }
@@ -13,11 +13,9 @@ class FieldSortCriteria extends SortCriteria
*/ */
public function sort(Builder $builder): Builder public function sort(Builder $builder): Builder
{ {
$sort = $this->getSort(); $column = $this->sortCase->shouldQualifyColumn()
? $builder->qualifyColumn($this->column)
$column = $sort->shouldQualifyColumn() : $this->column;
? $builder->qualifyColumn($sort->getColumn())
: $sort->getColumn();
return $builder->orderBy($column, $this->direction->value); return $builder->orderBy($column, $this->direction->value);
} }
@@ -4,51 +4,19 @@ declare(strict_types=1);
namespace App\GraphQL\Criteria\Sort; namespace App\GraphQL\Criteria\Sort;
use App\Enums\GraphQL\Sort\SortDirection;
use App\GraphQL\Sort\Sort;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Str;
class PivotSortCriteria extends SortCriteria class PivotSortCriteria extends SortCriteria
{ {
public function __construct(
protected Sort $sort,
protected SortDirection $direction = SortDirection::ASC,
protected ?BelongsToMany $relation = null,
protected bool $isStringField = false,
) {
parent::__construct($sort, $direction, $isStringField);
}
/**
* Build the enum case for a direction.
* Template: PIVOT_{FIELD_NAME}.
* Template: PIVOT_{FIELD_NAME}_DESC.
*/
public function __toString(): string
{
$name = Str::of($this->getSort()->getName())
->snake()
->upper()
->prepend('PIVOT_');
return (string) match ($this->getDirection()) {
SortDirection::ASC => $name,
SortDirection::DESC => $name->append('_DESC'),
};
}
/** /**
* Apply the ordering to the current Eloquent builder. * Apply the ordering to the current Eloquent builder.
*/ */
public function sort(Builder $builder): Builder public function sort(Builder $builder, ?BelongsToMany $relation = null): Builder
{ {
$sort = $this->getSort(); $column = $this->sortCase->shouldQualifyColumn()
? $relation?->qualifyPivotColumn($this->column)
$column = $sort->shouldQualifyColumn() : $this->column;
? $this->relation?->qualifyPivotColumn($sort->getColumn())
: $sort->getColumn();
return $builder->orderBy($column, $this->getDirection()->value); return $builder->orderBy($column, $this->getDirection()->value);
} }
@@ -4,17 +4,10 @@ declare(strict_types=1);
namespace App\GraphQL\Criteria\Sort; namespace App\GraphQL\Criteria\Sort;
use App\GraphQL\Sort\Sort;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
class RandomSortCriteria extends SortCriteria class RandomSortCriteria extends SortCriteria
{ {
public function __construct()
{
// Random Sort doesn't need a field so we fake it.
parent::__construct(new Sort(''));
}
/** /**
* Build the enum case. * Build the enum case.
*/ */
@@ -4,54 +4,34 @@ declare(strict_types=1);
namespace App\GraphQL\Criteria\Sort; namespace App\GraphQL\Criteria\Sort;
use App\Enums\GraphQL\Sort\SortDirection; use App\Contracts\GraphQL\EnumSort;
use App\GraphQL\Sort\Sort; use App\Enums\GraphQL\SortDirection;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str; use UnitEnum;
class RelationSortCriteria extends SortCriteria class RelationSortCriteria extends SortCriteria
{ {
public function __construct( public function __construct(
protected Sort $sort, protected UnitEnum&EnumSort $sortCase,
protected string $column,
protected string $relation, protected string $relation,
protected SortDirection $direction = SortDirection::ASC, protected SortDirection $direction = SortDirection::ASC,
protected bool $isStringField = false, protected bool $isStringField = false,
) { ) {}
parent::__construct($sort, $direction, $isStringField);
}
public function getRelation(): string public function getRelation(): string
{ {
return $this->relation; return $this->relation;
} }
/**
* Build the enum case for a direction.
* Template: {RELATION}_{FIELD_NAME}.
* Template: {RELATION}_{FIELD_NAME}_DESC.
*/
public function __toString(): string
{
$name = Str::of($this->getRelation())
->append('_')
->append($this->getSort()->getName())
->snake()
->upper();
return (string) match ($this->direction) {
SortDirection::ASC => $name,
SortDirection::DESC => $name->append('_DESC'),
};
}
/** /**
* Apply the ordering to the current Eloquent builder. * Apply the ordering to the current Eloquent builder.
*/ */
public function sort(Builder $builder): Builder public function sort(Builder $builder): Builder
{ {
$relation = $builder->getRelation($this->getRelation()); $relation = $builder->getRelation($this->relation);
$orderBySubQuery = $relation->getRelationExistenceQuery($relation->getQuery(), $builder, [$this->getSort()->getColumn()]); $orderBySubQuery = $relation->getRelationExistenceQuery($relation->getQuery(), $builder, [$this->column]);
return $builder->orderBy($orderBySubQuery->toBase(), $this->direction->value); return $builder->orderBy($orderBySubQuery->toBase(), $this->direction->value);
} }
+8 -14
View File
@@ -4,23 +4,24 @@ declare(strict_types=1);
namespace App\GraphQL\Criteria\Sort; namespace App\GraphQL\Criteria\Sort;
use App\Enums\GraphQL\Sort\SortDirection; use App\Contracts\GraphQL\EnumSort;
use App\GraphQL\Sort\Sort; use App\Enums\GraphQL\SortDirection;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str;
use Stringable; use Stringable;
use UnitEnum;
abstract class SortCriteria implements Stringable abstract class SortCriteria implements Stringable
{ {
public function __construct( public function __construct(
protected Sort $sort, protected UnitEnum&EnumSort $sortCase,
protected string $column,
protected SortDirection $direction = SortDirection::ASC, protected SortDirection $direction = SortDirection::ASC,
protected bool $isStringField = false, protected bool $isStringField = false,
) {} ) {}
public function getSort(): Sort public function getColumn(): string
{ {
return $this->sort; return $this->column;
} }
public function getDirection(): SortDirection public function getDirection(): SortDirection
@@ -40,14 +41,7 @@ abstract class SortCriteria implements Stringable
*/ */
public function __toString(): string public function __toString(): string
{ {
$name = Str::of($this->getSort()->getName()) return $this->sortCase->name;
->snake()
->upper();
return (string) match ($this->direction) {
SortDirection::ASC => $name,
SortDirection::DESC => $name->append('_DESC'),
};
} }
/** /**
@@ -1,114 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Schema\Enums;
use App\Contracts\GraphQL\Fields\SortableField;
use App\Enums\GraphQL\Sort\SortDirection;
use App\GraphQL\Criteria\Sort\FieldSortCriteria;
use App\GraphQL\Criteria\Sort\PivotSortCriteria;
use App\GraphQL\Criteria\Sort\RandomSortCriteria;
use App\GraphQL\Criteria\Sort\RelationSortCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Schema\Fields\Field;
use App\GraphQL\Schema\Fields\Relations\BelongsToRelation;
use App\GraphQL\Schema\Fields\Relations\Relation;
use App\GraphQL\Schema\Fields\StringField;
use App\GraphQL\Schema\Types\BaseType;
use App\GraphQL\Schema\Types\Pivot\PivotType;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;
use Rebing\GraphQL\Support\EnumType;
/**
* Dynamic enum type to build the {Type}SortableColumns enums.
*/
class SortableColumns extends EnumType
{
final public const string SUFFIX = 'SortableColumns';
public function __construct(
protected BaseType $type,
protected ?PivotType $pivotType = null,
protected ?BelongsToMany $relation = null,
) {}
/**
* @return array<string, mixed>
*/
public function attributes(): array
{
$typeName = $this->type->name();
$name = $this->pivotType instanceof PivotType
? $typeName.$this->pivotType->name()
: $typeName;
return [
'name' => $name.self::SUFFIX,
'values' => $this->getCriteria()->mapWithKeys(fn (SortCriteria $criterion): array => [$criterion->__toString() => $criterion->__toString()])->all(),
'criteria' => $this->getCriteria()->mapWithKeys(fn (SortCriteria $criterion): array => [$criterion->__toString() => $criterion])->all(),
];
}
/**
* @return Collection<int, Field&SortableField>
*/
private function getSortableFields(): Collection
{
return collect($this->type->fieldClasses())
->filter(fn (Field $field): bool => $field instanceof SortableField);
}
private function getCriteria(): Collection
{
return $this->getFieldSortCriteria()
->merge($this->getPivotSortCriteria())
->merge($this->getRelationSortCriteria())
->push(new RandomSortCriteria());
}
private function getFieldSortCriteria(): Collection
{
return $this->getSortableFields()
->map(fn (Field&SortableField $field): array => [
new FieldSortCriteria($field->getSort(), SortDirection::ASC, $field instanceof StringField),
new FieldSortCriteria($field->getSort(), SortDirection::DESC, $field instanceof StringField),
])
->flatten();
}
private function getPivotSortCriteria(): Collection
{
return collect($this->pivotType?->fieldClasses() ?? [])
->filter(fn (Field $field): bool => $field instanceof SortableField)
->map(fn (Field&SortableField $field): array => [
new PivotSortCriteria($field->getSort(), SortDirection::ASC, $this->relation, $field instanceof StringField),
new PivotSortCriteria($field->getSort(), SortDirection::DESC, $this->relation, $field instanceof StringField),
])
->flatten();
}
private function getRelationSortCriteria(): Collection
{
return $this->getRelations($this->type)
->flatMap(fn (Collection $fields, $relation) => $fields->map(fn (Field&SortableField $field): array => [
new RelationSortCriteria($field->getSort(), $relation, SortDirection::ASC, $field instanceof StringField),
new RelationSortCriteria($field->getSort(), $relation, SortDirection::DESC, $field instanceof StringField),
]))
->flatten();
}
private function getRelations(BaseType $type): Collection
{
return collect($type->relations())
->filter(fn (Relation $relation): bool => $relation instanceof BelongsToRelation && $relation->baseType() instanceof BaseType)
->mapWithKeys(
fn (Relation $relation): array => [
$relation->name() => collect($relation->baseType()->fieldClasses())
->filter(fn (Field $field): bool => $field instanceof SortableField),
],
);
}
}
@@ -4,18 +4,14 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Fields\Base\Aggregate; namespace App\GraphQL\Schema\Fields\Base\Aggregate;
use App\Contracts\GraphQL\EnumSort;
use App\Contracts\GraphQL\Fields\FilterableField; use App\Contracts\GraphQL\Fields\FilterableField;
use App\Contracts\GraphQL\Fields\SortableField;
use App\Enums\GraphQL\Field\AggregateFunction; use App\Enums\GraphQL\Field\AggregateFunction;
use App\Enums\GraphQL\QualifyColumn;
use App\GraphQL\Criteria\Filter\FilterCriteria; use App\GraphQL\Criteria\Filter\FilterCriteria;
use App\GraphQL\Criteria\Filter\WhereConditionsFilterCriteria; use App\GraphQL\Criteria\Filter\WhereConditionsFilterCriteria;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Schema\Enums\FilterableColumns; use App\GraphQL\Schema\Enums\FilterableColumns;
use App\GraphQL\Schema\Enums\SortableColumns;
use App\GraphQL\Schema\Fields\Field; use App\GraphQL\Schema\Fields\Field;
use App\GraphQL\Schema\Types\BaseType; use App\GraphQL\Schema\Types\BaseType;
use App\GraphQL\Sort\Sort;
use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\ResolveInfo;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@@ -23,8 +19,9 @@ use Illuminate\Support\Arr;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Illuminate\Support\Stringable; use Illuminate\Support\Stringable;
use UnitEnum;
abstract class AggregateField extends Field implements FilterableField, SortableField abstract class AggregateField extends Field implements FilterableField
{ {
private Collection $filterableFields; private Collection $filterableFields;
@@ -38,11 +35,6 @@ abstract class AggregateField extends Field implements FilterableField, Sortable
parent::__construct($this->alias(), $fieldName, $nullable); parent::__construct($this->alias(), $fieldName, $nullable);
} }
public function getSort(): Sort
{
return new Sort($this->fieldName, $this->alias(), qualifyColumn: QualifyColumn::NO);
}
/** /**
* Eager load the aggregate value for the query builder. * Eager load the aggregate value for the query builder.
*/ */
@@ -54,11 +46,10 @@ abstract class AggregateField extends Field implements FilterableField, Sortable
} }
// If the sorting is requesting an aggregate function. // If the sorting is requesting an aggregate function.
/** @var SortCriteria[] $sortCriteria */ /** @var array<int, UnitEnum&EnumSort> $sorts */
$sortCriteria = Arr::get(new SortableColumns($type)->getAttributes(), 'criteria');
$sorts = Arr::get($args, 'sort', []); $sorts = Arr::get($args, 'sort', []);
foreach ($sortCriteria as $sortCriterion) { foreach ($sorts as $sort) {
if (in_array($sortCriterion->__toString(), $sorts) && $sortCriterion->getSort()->getName() === $this->name()) { if ($sort->getSortCriteria()->getColumn() === $this->alias()) {
return true; return true;
} }
} }
@@ -5,14 +5,13 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Fields\Base\Aggregate; namespace App\GraphQL\Schema\Fields\Base\Aggregate;
use App\Contracts\GraphQL\Fields\DisplayableField; use App\Contracts\GraphQL\Fields\DisplayableField;
use App\Contracts\GraphQL\Fields\SortableField;
use App\Enums\GraphQL\Field\AggregateFunction; use App\Enums\GraphQL\Field\AggregateFunction;
use App\Enums\GraphQL\Filter\Clause; use App\Enums\GraphQL\Filter\Clause;
use App\GraphQL\Filter\IntFilter; use App\GraphQL\Filter\IntFilter;
use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
class CountAggregateField extends AggregateField implements DisplayableField, SortableField class CountAggregateField extends AggregateField implements DisplayableField
{ {
public function __construct( public function __construct(
public string $aggregateRelation, public string $aggregateRelation,
@@ -6,13 +6,12 @@ namespace App\GraphQL\Schema\Fields\Base\Aggregate;
use App\Contracts\GraphQL\Fields\DisplayableField; use App\Contracts\GraphQL\Fields\DisplayableField;
use App\Contracts\GraphQL\Fields\FilterableField; use App\Contracts\GraphQL\Fields\FilterableField;
use App\Contracts\GraphQL\Fields\SortableField;
use App\Enums\GraphQL\Field\AggregateFunction; use App\Enums\GraphQL\Field\AggregateFunction;
use App\Enums\GraphQL\Filter\Clause; use App\Enums\GraphQL\Filter\Clause;
use App\GraphQL\Filter\IntFilter; use App\GraphQL\Filter\IntFilter;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
class CountField extends AggregateField implements DisplayableField, FilterableField, SortableField class CountField extends AggregateField implements DisplayableField, FilterableField
{ {
public function __construct( public function __construct(
protected string $aggregateRelation, protected string $aggregateRelation,
+1 -8
View File
@@ -6,12 +6,10 @@ namespace App\GraphQL\Schema\Fields;
use App\Contracts\GraphQL\Fields\DisplayableField; use App\Contracts\GraphQL\Fields\DisplayableField;
use App\Contracts\GraphQL\Fields\FilterableField; use App\Contracts\GraphQL\Fields\FilterableField;
use App\Contracts\GraphQL\Fields\SortableField;
use App\GraphQL\Filter\BooleanFilter; use App\GraphQL\Filter\BooleanFilter;
use App\GraphQL\Sort\Sort;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
abstract class BooleanField extends Field implements DisplayableField, FilterableField, SortableField abstract class BooleanField extends Field implements DisplayableField, FilterableField
{ {
public function baseType(): Type public function baseType(): Type
{ {
@@ -28,9 +26,4 @@ abstract class BooleanField extends Field implements DisplayableField, Filterabl
return new BooleanFilter($this->name(), $this->getColumn()) return new BooleanFilter($this->name(), $this->getColumn())
->useEq(); ->useEq();
} }
public function getSort(): Sort
{
return new Sort($this->name(), $this->getColumn());
}
} }
+1 -8
View File
@@ -6,16 +6,14 @@ namespace App\GraphQL\Schema\Fields;
use App\Contracts\GraphQL\Fields\DisplayableField; use App\Contracts\GraphQL\Fields\DisplayableField;
use App\Contracts\GraphQL\Fields\FilterableField; use App\Contracts\GraphQL\Fields\FilterableField;
use App\Contracts\GraphQL\Fields\SortableField;
use App\GraphQL\Filter\EnumFilter; use App\GraphQL\Filter\EnumFilter;
use App\GraphQL\Sort\Sort;
use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Rebing\GraphQL\Support\Facades\GraphQL; use Rebing\GraphQL\Support\Facades\GraphQL;
use UnitEnum; use UnitEnum;
abstract class EnumField extends Field implements DisplayableField, FilterableField, SortableField abstract class EnumField extends Field implements DisplayableField, FilterableField
{ {
/** /**
* @param class-string<UnitEnum> $enum * @param class-string<UnitEnum> $enum
@@ -51,9 +49,4 @@ abstract class EnumField extends Field implements DisplayableField, FilterableFi
->useIn() ->useIn()
->useNotIn(); ->useNotIn();
} }
public function getSort(): Sort
{
return new Sort($this->name(), $this->getColumn());
}
} }
+1 -8
View File
@@ -6,12 +6,10 @@ namespace App\GraphQL\Schema\Fields;
use App\Contracts\GraphQL\Fields\DisplayableField; use App\Contracts\GraphQL\Fields\DisplayableField;
use App\Contracts\GraphQL\Fields\FilterableField; use App\Contracts\GraphQL\Fields\FilterableField;
use App\Contracts\GraphQL\Fields\SortableField;
use App\GraphQL\Filter\FloatFilter; use App\GraphQL\Filter\FloatFilter;
use App\GraphQL\Sort\Sort;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
abstract class FloatField extends Field implements DisplayableField, FilterableField, SortableField abstract class FloatField extends Field implements DisplayableField, FilterableField
{ {
public function baseType(): Type public function baseType(): Type
{ {
@@ -30,9 +28,4 @@ abstract class FloatField extends Field implements DisplayableField, FilterableF
->useLt() ->useLt()
->useGt(); ->useGt();
} }
public function getSort(): Sort
{
return new Sort($this->name(), $this->getColumn());
}
} }
+1 -8
View File
@@ -6,12 +6,10 @@ namespace App\GraphQL\Schema\Fields;
use App\Contracts\GraphQL\Fields\DisplayableField; use App\Contracts\GraphQL\Fields\DisplayableField;
use App\Contracts\GraphQL\Fields\FilterableField; use App\Contracts\GraphQL\Fields\FilterableField;
use App\Contracts\GraphQL\Fields\SortableField;
use App\GraphQL\Filter\IntFilter; use App\GraphQL\Filter\IntFilter;
use App\GraphQL\Sort\Sort;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
abstract class IntField extends Field implements DisplayableField, FilterableField, SortableField abstract class IntField extends Field implements DisplayableField, FilterableField
{ {
public function baseType(): Type public function baseType(): Type
{ {
@@ -32,9 +30,4 @@ abstract class IntField extends Field implements DisplayableField, FilterableFie
->useIn() ->useIn()
->useNotIn(); ->useNotIn();
} }
public function getSort(): Sort
{
return new Sort($this->name(), $this->getColumn());
}
} }
@@ -46,7 +46,11 @@ class BelongsToManyRelation extends Relation
return [ return [
...parent::arguments(), ...parent::arguments(),
new SortArgument($this->baseType(), $pivotType), ...(
$this->baseType()->getEnumSortClass() !== null || $this->sortEnum
? [new SortArgument($this->baseType(), $this->sortEnum)]
: []
),
]; ];
} }
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Fields\Relations; namespace App\GraphQL\Schema\Fields\Relations;
use App\Concerns\Actions\GraphQL\FiltersModels; use App\Concerns\Actions\GraphQL\FiltersModels;
use App\Contracts\GraphQL\EnumSort;
use App\Enums\GraphQL\PaginationType; use App\Enums\GraphQL\PaginationType;
use App\GraphQL\Argument\Argument; use App\GraphQL\Argument\Argument;
use App\GraphQL\Argument\FirstArgument; use App\GraphQL\Argument\FirstArgument;
@@ -21,6 +22,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use UnitEnum;
abstract class Relation extends Field abstract class Relation extends Field
{ {
@@ -28,6 +30,9 @@ abstract class Relation extends Field
protected bool $asPivot = false; protected bool $asPivot = false;
/** @var class-string<UnitEnum&EnumSort>|null */
protected ?string $sortEnum = null;
public function __construct( public function __construct(
protected BaseType|BaseUnion $relatedType, protected BaseType|BaseUnion $relatedType,
protected string $relationName, protected string $relationName,
@@ -65,6 +70,16 @@ abstract class Relation extends Field
return $this; return $this;
} }
/**
* @param class-string<UnitEnum&EnumSort> $enum
*/
public function setSortEnum(string $enum): static
{
$this->sortEnum = $enum;
return $this;
}
/** /**
* Get the relation name in the model. * Get the relation name in the model.
*/ */
@@ -99,7 +114,7 @@ abstract class Relation extends Field
$arguments[] = new FirstArgument(true); $arguments[] = new FirstArgument(true);
$arguments[] = new PageArgument(); $arguments[] = new PageArgument();
if ($type instanceof BaseType && $type->hasSortableColumns()) { if ($type instanceof BaseType && $type->getEnumSortClass() !== null) {
$arguments[] = new SortArgument($type); $arguments[] = new SortArgument($type);
} }
} }
+1 -8
View File
@@ -6,13 +6,11 @@ namespace App\GraphQL\Schema\Fields;
use App\Contracts\GraphQL\Fields\DisplayableField; use App\Contracts\GraphQL\Fields\DisplayableField;
use App\Contracts\GraphQL\Fields\FilterableField; use App\Contracts\GraphQL\Fields\FilterableField;
use App\Contracts\GraphQL\Fields\SortableField;
use App\GraphQL\Filter\Filter; use App\GraphQL\Filter\Filter;
use App\GraphQL\Filter\StringFilter; use App\GraphQL\Filter\StringFilter;
use App\GraphQL\Sort\Sort;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
abstract class StringField extends Field implements DisplayableField, FilterableField, SortableField abstract class StringField extends Field implements DisplayableField, FilterableField
{ {
public function baseType(): Type public function baseType(): Type
{ {
@@ -30,9 +28,4 @@ abstract class StringField extends Field implements DisplayableField, Filterable
->useEq() ->useEq()
->useLike(); ->useLike();
} }
public function getSort(): Sort
{
return new Sort($this->name(), $this->getColumn());
}
} }
+1 -1
View File
@@ -69,7 +69,7 @@ abstract class BaseQuery extends Query
$arguments[] = FilterCriteria::getFilters($baseType)->map(fn (Filter $filter): array => $filter->getArguments())->flatten(); $arguments[] = FilterCriteria::getFilters($baseType)->map(fn (Filter $filter): array => $filter->getArguments())->flatten();
} }
if ($baseType->hasSortableColumns()) { if ($baseType->getEnumSortClass() !== null) {
$arguments[] = new SortArgument($baseType); $arguments[] = new SortArgument($baseType);
} }
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Admin; namespace App\GraphQL\Schema\Types\Admin;
use App\Enums\GraphQL\Sort\Admin\AnnouncementSort;
use App\GraphQL\Schema\Fields\Admin\Announcement\AnnouncementContentField; use App\GraphQL\Schema\Fields\Admin\Announcement\AnnouncementContentField;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\IdField; use App\GraphQL\Schema\Fields\Base\IdField;
@@ -19,6 +20,14 @@ class AnnouncementType extends EloquentType
return 'Represents a site-wide message to be broadcasted on the homepage.'; return 'Represents a site-wide message to be broadcasted on the homepage.';
} }
/**
* @return class-string<AnnouncementSort>
*/
public function getEnumSortClass(): string
{
return AnnouncementSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Admin; namespace App\GraphQL\Schema\Types\Admin;
use App\Enums\GraphQL\Sort\Admin\DumpSort;
use App\GraphQL\Schema\Fields\Admin\Dump\DumpLinkField; use App\GraphQL\Schema\Fields\Admin\Dump\DumpLinkField;
use App\GraphQL\Schema\Fields\Admin\Dump\DumpPathField; use App\GraphQL\Schema\Fields\Admin\Dump\DumpPathField;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
@@ -20,6 +21,14 @@ class DumpType extends EloquentType
return "Represents a database dump of selected tables at a given point in time.\n\nFor example, the animethemes-db-dump-wiki-1663559663946.sql dump represents the database dump of wiki tables performed at 2022-09-19."; return "Represents a database dump of selected tables at a given point in time.\n\nFor example, the animethemes-db-dump-wiki-1663559663946.sql dump represents the database dump of wiki tables performed at 2022-09-19.";
} }
/**
* @return class-string<DumpSort>
*/
public function getEnumSortClass(): string
{
return DumpSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
+7 -3
View File
@@ -4,14 +4,15 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types; namespace App\GraphQL\Schema\Types;
use App\Contracts\GraphQL\EnumSort;
use App\Contracts\GraphQL\Fields\DeprecatedField; use App\Contracts\GraphQL\Fields\DeprecatedField;
use App\Contracts\GraphQL\Fields\DisplayableField; use App\Contracts\GraphQL\Fields\DisplayableField;
use App\Contracts\GraphQL\Fields\FilterableField; use App\Contracts\GraphQL\Fields\FilterableField;
use App\Contracts\GraphQL\Fields\SortableField;
use App\GraphQL\Schema\Fields\Field; use App\GraphQL\Schema\Fields\Field;
use App\GraphQL\Schema\Fields\Relations\Relation; use App\GraphQL\Schema\Fields\Relations\Relation;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Rebing\GraphQL\Support\Type as RebingType; use Rebing\GraphQL\Support\Type as RebingType;
use UnitEnum;
abstract class BaseType extends RebingType abstract class BaseType extends RebingType
{ {
@@ -100,9 +101,12 @@ abstract class BaseType extends RebingType
return $fields->merge($relations)->all(); return $fields->merge($relations)->all();
} }
public function hasSortableColumns(): bool /**
* @return class-string<UnitEnum&EnumSort>|null
*/
public function getEnumSortClass(): ?string
{ {
return array_any($this->fieldClasses(), fn (Field $field): bool => $field instanceof SortableField); return null;
} }
public function hasFilterableColumns(): bool public function hasFilterableColumns(): bool
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Document; namespace App\GraphQL\Schema\Types\Document;
use App\Enums\GraphQL\Sort\Document\PageSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdUnbindableField; use App\GraphQL\Schema\Fields\Base\IdUnbindableField;
@@ -23,6 +24,14 @@ class PageType extends EloquentType
return "Represents a static markdown page used for guides and other documentation.\n\nFor example, the 'encoding/audio_normalization' page represents the documentation for audio normalization."; return "Represents a static markdown page used for guides and other documentation.\n\nFor example, the 'encoding/audio_normalization' page represents the documentation for audio normalization.";
} }
/**
* @return class-string<PageSort>
*/
public function getEnumSortClass(): string
{
return PageSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\List\Playlist; namespace App\GraphQL\Schema\Types\List\Playlist;
use App\Enums\GraphQL\Sort\List\Playlist\PlaylistTrackSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\UpdatedAtField; use App\GraphQL\Schema\Fields\Base\UpdatedAtField;
use App\GraphQL\Schema\Fields\Field; use App\GraphQL\Schema\Fields\Field;
@@ -28,6 +29,14 @@ class PlaylistTrackType extends EloquentType
return "Represents an entry in a playlist.\n\nFor example, a \"/r/anime's Best OPs and EDs of 2022\" playlist may contain a track for the ParipiKoumei-OP1.webm video."; return "Represents an entry in a playlist.\n\nFor example, a \"/r/anime's Best OPs and EDs of 2022\" playlist may contain a track for the ParipiKoumei-OP1.webm video.";
} }
/**
* @return class-string<PlaylistTrackSort>
*/
public function getEnumSortClass(): string
{
return PlaylistTrackSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
+12 -1
View File
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\List; namespace App\GraphQL\Schema\Types\List;
use App\Enums\GraphQL\Sort\List\PlaylistSort;
use App\Enums\GraphQL\Sort\Pivot\ImageableSort;
use App\GraphQL\Schema\Fields\Base\Aggregate\LikesCountField; use App\GraphQL\Schema\Fields\Base\Aggregate\LikesCountField;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\UpdatedAtField; use App\GraphQL\Schema\Fields\Base\UpdatedAtField;
@@ -32,6 +34,14 @@ class PlaylistType extends EloquentType
return "Represents a list of ordered tracks intended for continuous playback.\n\nFor example, a \"/r/anime's Best OPs and EDs of 2022\" playlist may contain a collection of tracks allowing the continuous playback of Best OP and ED nominations for the /r/anime Awards."; return "Represents a list of ordered tracks intended for continuous playback.\n\nFor example, a \"/r/anime's Best OPs and EDs of 2022\" playlist may contain a collection of tracks allowing the continuous playback of Best OP and ED nominations for the /r/anime Awards.";
} }
/**
* @return class-string<PlaylistSort>
*/
public function getEnumSortClass(): string
{
return PlaylistSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
@@ -56,7 +66,8 @@ class PlaylistType extends EloquentType
new BelongsToRelation(new UserType(), Playlist::RELATION_USER) new BelongsToRelation(new UserType(), Playlist::RELATION_USER)
->nonNullable(), ->nonNullable(),
new HasManyRelation(new PlaylistTrackType(), Playlist::RELATION_TRACKS), new HasManyRelation(new PlaylistTrackType(), Playlist::RELATION_TRACKS),
new MorphToManyRelation($this, new ImageType(), Playlist::RELATION_IMAGES, new ImageableType()), new MorphToManyRelation($this, new ImageType(), Playlist::RELATION_IMAGES, new ImageableType())
->setSortEnum(ImageableSort::class),
]; ];
} }
} }
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki\Anime; namespace App\GraphQL\Schema\Types\Wiki\Anime;
use App\Enums\GraphQL\Sort\Wiki\Anime\AnimeThemeSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdField; use App\GraphQL\Schema\Fields\Base\IdField;
@@ -30,6 +31,14 @@ class AnimeThemeType extends EloquentType
return "Represents an OP or ED sequence for an anime.\n\nFor example, the anime Bakemonogatari has five OP anime themes and one ED anime theme."; return "Represents an OP or ED sequence for an anime.\n\nFor example, the anime Bakemonogatari has five OP anime themes and one ED anime theme.";
} }
/**
* @return class-string<AnimeThemeSort>
*/
public function getEnumSortClass(): string
{
return AnimeThemeSort::class;
}
/** /**
* The relations of the type. * The relations of the type.
* *
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki\Anime\Theme; namespace App\GraphQL\Schema\Types\Wiki\Anime\Theme;
use App\Enums\GraphQL\Sort\Wiki\Anime\AnimeTheme\AnimeThemeEntrySort;
use App\GraphQL\Schema\Fields\Base\Aggregate\LikesCountField; use App\GraphQL\Schema\Fields\Base\Aggregate\LikesCountField;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
@@ -34,6 +35,14 @@ class AnimeThemeEntryType extends EloquentType
return "Represents a version of an anime theme.\n\nFor example, the ED theme of the Bakemonogatari anime has three anime theme entries to represent three versions."; return "Represents a version of an anime theme.\n\nFor example, the ED theme of the Bakemonogatari anime has three anime theme entries to represent three versions.";
} }
/**
* @return class-string<AnimeThemeEntrySort>
*/
public function getEnumSortClass(): string
{
return AnimeThemeEntrySort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
+12 -1
View File
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki; namespace App\GraphQL\Schema\Types\Wiki;
use App\Enums\GraphQL\Sort\Pivot\ImageableSort;
use App\Enums\GraphQL\Sort\Wiki\AnimeSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdUnbindableField; use App\GraphQL\Schema\Fields\Base\IdUnbindableField;
@@ -37,6 +39,14 @@ class AnimeType extends EloquentType
return "Represents a production with at least one opening or ending sequence.\n\nFor example, Bakemonogatari is an anime production with five opening sequences and one ending sequence."; return "Represents a production with at least one opening or ending sequence.\n\nFor example, Bakemonogatari is an anime production with five opening sequences and one ending sequence.";
} }
/**
* @return class-string<AnimeSort>
*/
public function getEnumSortClass(): string
{
return AnimeSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
@@ -66,7 +76,8 @@ class AnimeType extends EloquentType
new MorphManyRelation(new SynonymType(), Anime::RELATION_SYNONYMS), new MorphManyRelation(new SynonymType(), Anime::RELATION_SYNONYMS),
new HasManyRelation(new AnimeThemeType(), Anime::RELATION_THEMES), new HasManyRelation(new AnimeThemeType(), Anime::RELATION_THEMES),
new MorphToManyRelation($this, new ExternalResourceType(), Anime::RELATION_RESOURCES, new ResourceableType()), new MorphToManyRelation($this, new ExternalResourceType(), Anime::RELATION_RESOURCES, new ResourceableType()),
new MorphToManyRelation($this, new ImageType(), Anime::RELATION_IMAGES, new ImageableType()), new MorphToManyRelation($this, new ImageType(), Anime::RELATION_IMAGES, new ImageableType())
->setSortEnum(ImageableSort::class),
new BelongsToManyRelation($this, new SeriesType(), Anime::RELATION_SERIES, new AnimeSeriesType()), new BelongsToManyRelation($this, new SeriesType(), Anime::RELATION_SERIES, new AnimeSeriesType()),
new BelongsToManyRelation($this, new StudioType(), Anime::RELATION_STUDIOS, new AnimeStudioType()), new BelongsToManyRelation($this, new StudioType(), Anime::RELATION_STUDIOS, new AnimeStudioType()),
]; ];
+15 -2
View File
@@ -4,6 +4,9 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki; namespace App\GraphQL\Schema\Types\Wiki;
use App\Enums\GraphQL\Sort\Pivot\ArtistMemberSort;
use App\Enums\GraphQL\Sort\Pivot\ImageableSort;
use App\Enums\GraphQL\Sort\Wiki\ArtistSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdUnbindableField; use App\GraphQL\Schema\Fields\Base\IdUnbindableField;
@@ -30,6 +33,14 @@ class ArtistType extends EloquentType
return "Represents a musical performer of anime sequences.\n\nFor example, Chiwa Saitou is the musical performer of the Bakemonogatari OP1 theme, among many others."; return "Represents a musical performer of anime sequences.\n\nFor example, Chiwa Saitou is the musical performer of the Bakemonogatari OP1 theme, among many others.";
} }
/**
* @return class-string<ArtistSort>
*/
public function getEnumSortClass(): string
{
return ArtistSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
@@ -48,8 +59,10 @@ class ArtistType extends EloquentType
new MorphManyRelation(new SynonymType(), Artist::RELATION_SYNONYMS), new MorphManyRelation(new SynonymType(), Artist::RELATION_SYNONYMS),
new BelongsToManyRelation($this, new ArtistType(), Artist::RELATION_GROUPS, new ArtistMemberType()), new BelongsToManyRelation($this, new ArtistType(), Artist::RELATION_GROUPS, new ArtistMemberType()),
new BelongsToManyRelation($this, new ArtistType(), Artist::RELATION_MEMBERS, new ArtistMemberType()), new BelongsToManyRelation($this, new ArtistType(), Artist::RELATION_MEMBERS, new ArtistMemberType())
new MorphToManyRelation($this, new ImageType(), Artist::RELATION_IMAGES, new ImageableType()), ->setSortEnum(ArtistMemberSort::class),
new MorphToManyRelation($this, new ImageType(), Artist::RELATION_IMAGES, new ImageableType())
->setSortEnum(ImageableSort::class),
new MorphToManyRelation($this, new ExternalResourceType(), Artist::RELATION_RESOURCES, new ResourceableType()), new MorphToManyRelation($this, new ExternalResourceType(), Artist::RELATION_RESOURCES, new ResourceableType()),
new HasManyRelation(new PerformanceType(), Artist::RELATION_PERFORMANCES), new HasManyRelation(new PerformanceType(), Artist::RELATION_PERFORMANCES),
new HasManyRelation(new PerformanceType(), Artist::RELATION_MEMBER_PERFORMANCES), new HasManyRelation(new PerformanceType(), Artist::RELATION_MEMBER_PERFORMANCES),
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki; namespace App\GraphQL\Schema\Types\Wiki;
use App\Enums\GraphQL\Sort\Wiki\AudioSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdField; use App\GraphQL\Schema\Fields\Base\IdField;
@@ -26,6 +27,14 @@ class AudioType extends EloquentType
return "Represents the audio track of a video.\n\nFor example, the audio Bakemonogatari-OP1.ogg represents the audio track of the Bakemonogatari-OP1.webm video."; return "Represents the audio track of a video.\n\nFor example, the audio Bakemonogatari-OP1.ogg represents the audio track of the Bakemonogatari-OP1.webm video.";
} }
/**
* @return class-string<AudioSort>
*/
public function getEnumSortClass(): string
{
return AudioSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki; namespace App\GraphQL\Schema\Types\Wiki;
use App\Enums\GraphQL\Sort\Wiki\ImageSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdField; use App\GraphQL\Schema\Fields\Base\IdField;
@@ -25,6 +26,14 @@ class ImageType extends EloquentType
return "Represents a visual component for another resource such as an anime or artist.\n\nFor example, the Bakemonogatari anime has two images to represent small and large cover images."; return "Represents a visual component for another resource such as an anime or artist.\n\nFor example, the Bakemonogatari anime has two images to represent small and large cover images.";
} }
/**
* @return class-string<ImageSort>
*/
public function getEnumSortClass(): string
{
return ImageSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki; namespace App\GraphQL\Schema\Types\Wiki;
use App\Enums\GraphQL\Sort\Wiki\SeriesSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdUnbindableField; use App\GraphQL\Schema\Fields\Base\IdUnbindableField;
@@ -23,6 +24,14 @@ class SeriesType extends EloquentType
return "Represents a collection of related anime.\n\nFor example, the Monogatari series is the collection of the Bakemonogatari anime and its related productions."; return "Represents a collection of related anime.\n\nFor example, the Monogatari series is the collection of the Bakemonogatari anime and its related productions.";
} }
/**
* @return class-string<SeriesSort>
*/
public function getEnumSortClass(): string
{
return SeriesSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki\Song; namespace App\GraphQL\Schema\Types\Wiki\Song;
use App\Enums\GraphQL\Sort\Wiki\Song\PerformanceSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdField; use App\GraphQL\Schema\Fields\Base\IdField;
@@ -27,6 +28,14 @@ class PerformanceType extends EloquentType
return 'Represents the link between a song and an artist or group.'; return 'Represents the link between a song and an artist or group.';
} }
/**
* @return class-string<PerformanceSort>
*/
public function getEnumSortClass(): string
{
return PerformanceSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki; namespace App\GraphQL\Schema\Types\Wiki;
use App\Enums\GraphQL\Sort\Wiki\SongSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdField; use App\GraphQL\Schema\Fields\Base\IdField;
@@ -26,6 +27,14 @@ class SongType extends EloquentType
return "Represents the composition that accompanies an AnimeTheme.\n\nFor example, Staple Stable is the song for the Bakemonogatari OP1 AnimeTheme."; return "Represents the composition that accompanies an AnimeTheme.\n\nFor example, Staple Stable is the song for the Bakemonogatari OP1 AnimeTheme.";
} }
/**
* @return class-string<SongSort>
*/
public function getEnumSortClass(): string
{
return SongSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
+3 -1
View File
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki; namespace App\GraphQL\Schema\Types\Wiki;
use App\Enums\GraphQL\Sort\Pivot\ImageableSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdUnbindableField; use App\GraphQL\Schema\Fields\Base\IdUnbindableField;
@@ -42,7 +43,8 @@ class StudioType extends EloquentType
new DeletedAtField(), new DeletedAtField(),
new BelongsToManyRelation($this, new AnimeType(), Studio::RELATION_ANIME, new AnimeStudioType()), new BelongsToManyRelation($this, new AnimeType(), Studio::RELATION_ANIME, new AnimeStudioType()),
new MorphToManyRelation($this, new ImageType(), Studio::RELATION_IMAGES, new ImageableType()), new MorphToManyRelation($this, new ImageType(), Studio::RELATION_IMAGES, new ImageableType())
->setSortEnum(ImageableSort::class),
new MorphToManyRelation($this, new ExternalResourceType(), Studio::RELATION_RESOURCES, new ResourceableType()), new MorphToManyRelation($this, new ExternalResourceType(), Studio::RELATION_RESOURCES, new ResourceableType()),
]; ];
} }
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki; namespace App\GraphQL\Schema\Types\Wiki;
use App\Enums\GraphQL\Sort\Wiki\SynonymSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdField; use App\GraphQL\Schema\Fields\Base\IdField;
@@ -22,6 +23,14 @@ class SynonymType extends EloquentType
return "Represents an alternate title or common abbreviation for an entity.\n\nFor example, the anime Bakemonogatari has the synonym \"Monstory\"."; return "Represents an alternate title or common abbreviation for an entity.\n\nFor example, the anime Bakemonogatari has the synonym \"Monstory\".";
} }
/**
* @return class-string<SynonymSort>
*/
public function getEnumSortClass(): string
{
return SynonymSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\GraphQL\Schema\Types\Wiki; namespace App\GraphQL\Schema\Types\Wiki;
use App\Enums\GraphQL\Sort\Wiki\VideoSort;
use App\GraphQL\Schema\Fields\Base\CreatedAtField; use App\GraphQL\Schema\Fields\Base\CreatedAtField;
use App\GraphQL\Schema\Fields\Base\DeletedAtField; use App\GraphQL\Schema\Fields\Base\DeletedAtField;
use App\GraphQL\Schema\Fields\Base\IdField; use App\GraphQL\Schema\Fields\Base\IdField;
@@ -43,6 +44,14 @@ class VideoType extends EloquentType
return "Represents a WebM of an anime theme.\n\nFor example, the video Bakemonogatari-OP1.webm represents the WebM of the Bakemonogatari OP1 theme."; return "Represents a WebM of an anime theme.\n\nFor example, the video Bakemonogatari-OP1.webm represents the WebM of the Bakemonogatari OP1 theme.";
} }
/**
* @return class-string<VideoSort>
*/
public function getEnumSortClass(): string
{
return VideoSort::class;
}
/** /**
* The fields of the type. * The fields of the type.
* *
-40
View File
@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Sort;
use App\Enums\GraphQL\QualifyColumn;
class Sort
{
public function __construct(
protected readonly string $name,
protected readonly ?string $column = null,
protected readonly QualifyColumn $qualifyColumn = QualifyColumn::YES
) {}
/**
* Get sort key value.
*/
public function getName(): string
{
return $this->name;
}
/**
* Get sort column.
*/
public function getColumn(): string
{
return $this->column ?? $this->getName();
}
/**
* Determine if the column should be qualified for the sort.
*/
public function shouldQualifyColumn(): bool
{
return $this->qualifyColumn === QualifyColumn::YES;
}
}
+43 -1
View File
@@ -6,7 +6,26 @@ namespace App\Providers;
use App\Enums\GraphQL\Filter\ComparisonOperator; use App\Enums\GraphQL\Filter\ComparisonOperator;
use App\Enums\GraphQL\Filter\TrashedFilter; use App\Enums\GraphQL\Filter\TrashedFilter;
use App\Enums\GraphQL\Sort\SortDirection; use App\Enums\GraphQL\Sort\Admin\AnnouncementSort;
use App\Enums\GraphQL\Sort\Admin\DumpSort;
use App\Enums\GraphQL\Sort\Document\PageSort;
use App\Enums\GraphQL\Sort\List\Playlist\PlaylistTrackSort;
use App\Enums\GraphQL\Sort\List\PlaylistSort;
use App\Enums\GraphQL\Sort\Pivot\ArtistMemberSort;
use App\Enums\GraphQL\Sort\Pivot\ImageableSort;
use App\Enums\GraphQL\Sort\Wiki\Anime\AnimeTheme\AnimeThemeEntrySort;
use App\Enums\GraphQL\Sort\Wiki\Anime\AnimeThemeSort;
use App\Enums\GraphQL\Sort\Wiki\AnimeSort;
use App\Enums\GraphQL\Sort\Wiki\ArtistSort;
use App\Enums\GraphQL\Sort\Wiki\AudioSort;
use App\Enums\GraphQL\Sort\Wiki\ImageSort;
use App\Enums\GraphQL\Sort\Wiki\SeriesSort;
use App\Enums\GraphQL\Sort\Wiki\Song\PerformanceSort;
use App\Enums\GraphQL\Sort\Wiki\SongSort;
use App\Enums\GraphQL\Sort\Wiki\StudioSort;
use App\Enums\GraphQL\Sort\Wiki\SynonymSort;
use App\Enums\GraphQL\Sort\Wiki\VideoSort;
use App\Enums\GraphQL\SortDirection;
use App\Enums\Models\List\ExternalEntryStatus; use App\Enums\Models\List\ExternalEntryStatus;
use App\Enums\Models\List\ExternalProfileSite; use App\Enums\Models\List\ExternalProfileSite;
use App\Enums\Models\List\ExternalProfileVisibility; use App\Enums\Models\List\ExternalProfileVisibility;
@@ -48,6 +67,29 @@ class GraphQLServiceProvider extends ServiceProvider
protected function bootEnums(): void protected function bootEnums(): void
{ {
// Sort Enums.
GraphQL::addType(new EnumType(AnnouncementSort::class));
GraphQL::addType(new EnumType(DumpSort::class));
GraphQL::addType(new EnumType(PageSort::class));
GraphQL::addType(new EnumType(PlaylistSort::class));
GraphQL::addType(new EnumType(PlaylistTrackSort::class));
GraphQL::addType(new EnumType(AnimeSort::class));
GraphQL::addType(new EnumType(AnimeThemeSort::class));
GraphQL::addType(new EnumType(AnimeThemeEntrySort::class));
GraphQL::addType(new EnumType(ArtistSort::class));
GraphQL::addType(new EnumType(AudioSort::class));
GraphQL::addType(new EnumType(ImageSort::class));
GraphQL::addType(new EnumType(PerformanceSort::class));
GraphQL::addType(new EnumType(SeriesSort::class));
GraphQL::addType(new EnumType(SongSort::class));
GraphQL::addType(new EnumType(StudioSort::class));
GraphQL::addType(new EnumType(SynonymSort::class));
GraphQL::addType(new EnumType(VideoSort::class));
// Pivot Sort Enums.
GraphQL::addType(new EnumType(ArtistMemberSort::class));
GraphQL::addType(new EnumType(ImageableSort::class));
GraphQL::addType(new EnumType(ComparisonOperator::class)); GraphQL::addType(new EnumType(ComparisonOperator::class));
GraphQL::addType(new EnumType(TrashedFilter::class)); GraphQL::addType(new EnumType(TrashedFilter::class));
GraphQL::addType(new EnumType(SortDirection::class)); GraphQL::addType(new EnumType(SortDirection::class));
@@ -1,21 +0,0 @@
<?php
declare(strict_types=1);
use App\Enums\GraphQL\Sort\SortDirection;
use App\GraphQL\Criteria\Sort\PivotSortCriteria;
use App\GraphQL\Sort\Sort;
it('formats for asc', function () {
$criteria = new class(new Sort(fake()->word()), SortDirection::ASC) extends PivotSortCriteria {};
$this->assertStringStartsWith('PIVOT_', $criteria->__toString());
$this->assertStringEndsNotWith('_DESC', $criteria->__toString());
});
it('formats for desc', function () {
$criteria = new class(new Sort(fake()->word()), SortDirection::DESC) extends PivotSortCriteria {};
$this->assertStringStartsWith('PIVOT_', $criteria->__toString());
$this->assertStringEndsWith('_DESC', $criteria->__toString());
});
@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
use App\Enums\GraphQL\Sort\SortDirection;
use App\GraphQL\Criteria\Sort\RelationSortCriteria;
use App\GraphQL\Sort\Sort;
use Illuminate\Support\Str;
it('formats for asc', function () {
$relation = fake()->word();
$criteria = new class(new Sort(fake()->word()), $relation, SortDirection::ASC) extends RelationSortCriteria {};
$this->assertStringStartsWith(Str::upper($relation), $criteria->__toString());
$this->assertStringEndsNotWith('_DESC', $criteria->__toString());
});
it('formats for desc', function () {
$relation = fake()->word();
$criteria = new class(new Sort(fake()->word()), $relation, SortDirection::DESC) extends RelationSortCriteria {};
$this->assertStringStartsWith(Str::upper($relation), $criteria->__toString());
$this->assertStringEndsWith('_DESC', $criteria->__toString());
});
@@ -1,32 +0,0 @@
<?php
declare(strict_types=1);
use App\Enums\GraphQL\Sort\SortDirection;
use App\GraphQL\Criteria\Sort\SortCriteria;
use App\GraphQL\Sort\Sort;
use Illuminate\Database\Eloquent\Builder;
it('formats for asc', function () {
$criteria = new class(new Sort(fake()->word()), SortDirection::ASC) extends SortCriteria
{
public function sort(Builder $builder): Builder
{
return $builder;
}
};
$this->assertStringEndsNotWith('_DESC', $criteria->__toString());
});
it('formats for desc', function () {
$criteria = new class(new Sort(fake()->word()), SortDirection::DESC) extends SortCriteria
{
public function sort(Builder $builder): Builder
{
return $builder;
}
};
$this->assertStringEndsWith('_DESC', $criteria->__toString());
});