mirror of
https://github.com/jikan-me/jikan-rest.git
synced 2025-02-20 11:23:35 +08:00
refactored user endpoints and cache ttl config
This commit is contained in:
parent
525ac030f3
commit
4a25c30d7d
@ -12,8 +12,8 @@ use Jikan\Model\Common\DateProp;
|
||||
*/
|
||||
class CarbonDateRange
|
||||
{
|
||||
private ?Carbon $fromObj;
|
||||
private ?Carbon $untilObj;
|
||||
private ?Carbon $fromObj = null;
|
||||
private ?Carbon $untilObj = null;
|
||||
|
||||
public function __construct(?Carbon $from, ?Carbon $to)
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ use Spatie\LaravelData\Resolvers\DataFromSomethingResolver;
|
||||
*/
|
||||
trait HasRequestFingerprint
|
||||
{
|
||||
protected ?string $fingerprint;
|
||||
protected ?string $fingerprint = null;
|
||||
|
||||
public static function fromRequest(Request $request): ?static
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ use App\Enums\AnimeScheduleFilterEnum;
|
||||
use App\Enums\AnimeTypeEnum;
|
||||
use Illuminate\Contracts\Database\Query\Builder as EloquentBuilder;
|
||||
use Illuminate\Support\Carbon;
|
||||
use \Laravel\Scout\Builder as ScoutBuilder;
|
||||
use Laravel\Scout\Builder as ScoutBuilder;
|
||||
|
||||
/**
|
||||
* @implements Repository<Anime>
|
||||
|
@ -3,8 +3,8 @@
|
||||
namespace App\Contracts;
|
||||
|
||||
use App\Character;
|
||||
use \Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use \Laravel\Scout\Builder as ScoutBuilder;
|
||||
use Illuminate\Contracts\Database\Query\Builder as EloquentBuilder;
|
||||
use Laravel\Scout\Builder as ScoutBuilder;
|
||||
|
||||
/**
|
||||
* @implements Repository<Character>
|
||||
|
@ -3,8 +3,8 @@
|
||||
namespace App\Contracts;
|
||||
|
||||
use App\Person;
|
||||
use \Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use \Laravel\Scout\Builder as ScoutBuilder;
|
||||
use Illuminate\Contracts\Database\Query\Builder as EloquentBuilder;
|
||||
use Laravel\Scout\Builder as ScoutBuilder;
|
||||
|
||||
/**
|
||||
* @implements Repository<Person>
|
||||
|
@ -5,9 +5,9 @@ namespace App\Dto;
|
||||
use App\Casts\EnumCast;
|
||||
use App\Enums\AnimeForumFilterEnum;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
|
@ -3,9 +3,9 @@
|
||||
namespace App\Dto;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\LaravelData\Attributes\Validation\Min;
|
||||
use Spatie\LaravelData\Attributes\Validation\Numeric;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
|
@ -6,11 +6,11 @@ use App\Casts\EnumCast;
|
||||
use App\Contracts\DataRequest;
|
||||
use App\Enums\CharacterOrderByEnum;
|
||||
use App\Http\Resources\V4\CharacterCollection;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements DataRequest<CharacterCollection>
|
||||
|
@ -8,11 +8,11 @@ use App\Enums\ClubCategoryEnum;
|
||||
use App\Enums\ClubOrderByEnum;
|
||||
use App\Enums\ClubTypeEnum;
|
||||
use App\Http\Resources\V4\ClubCollection;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements DataRequest<ClubCollection>
|
||||
|
16
app/Dto/Concerns/HasLimitParameter.php
Normal file
16
app/Dto/Concerns/HasLimitParameter.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto\Concerns;
|
||||
|
||||
use App\Rules\Attributes\MaxLimitWithFallback;
|
||||
use Spatie\LaravelData\Attributes\Validation\IntegerType;
|
||||
use Spatie\LaravelData\Attributes\Validation\Min;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
trait HasLimitParameter
|
||||
{
|
||||
use MapsDefaultLimitParameter;
|
||||
|
||||
#[IntegerType, Min(1), MaxLimitWithFallback]
|
||||
public int|Optional $limit;
|
||||
}
|
13
app/Dto/Concerns/HasPageParameter.php
Normal file
13
app/Dto/Concerns/HasPageParameter.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto\Concerns;
|
||||
|
||||
use Spatie\LaravelData\Attributes\Validation\Min;
|
||||
use Spatie\LaravelData\Attributes\Validation\Numeric;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
trait HasPageParameter
|
||||
{
|
||||
#[Numeric, Min(1)]
|
||||
public int|Optional $page = 1;
|
||||
}
|
27
app/Dto/LookupByUsernameCommand.php
Normal file
27
app/Dto/LookupByUsernameCommand.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
use App\Concerns\HasRequestFingerprint;
|
||||
use App\Contracts\DataRequest;
|
||||
use App\Dto\Concerns\MapsRouteParameters;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
use Illuminate\Http\Response;
|
||||
use Spatie\LaravelData\Attributes\Validation\Max;
|
||||
use Spatie\LaravelData\Attributes\Validation\Min;
|
||||
use Spatie\LaravelData\Attributes\Validation\StringType;
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
/**
|
||||
* Base class for all requests/commands which are for looking up things by username.
|
||||
* @template T of ResourceCollection|JsonResource|Response
|
||||
* @implements DataRequest<T>
|
||||
*/
|
||||
abstract class LookupByUsernameCommand extends Data implements DataRequest
|
||||
{
|
||||
use MapsRouteParameters, HasRequestFingerprint;
|
||||
|
||||
#[StringType, Max(255), Min(3)]
|
||||
public string $username;
|
||||
}
|
@ -6,11 +6,11 @@ use App\Casts\EnumCast;
|
||||
use App\Contracts\DataRequest;
|
||||
use App\Enums\MagazineOrderByEnum;
|
||||
use App\Http\Resources\V4\MagazineCollection;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements DataRequest<MagazineCollection>
|
||||
|
@ -6,9 +6,9 @@ namespace App\Dto;
|
||||
use App\Casts\EnumCast;
|
||||
use App\Enums\MangaForumFilterEnum;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
|
@ -6,11 +6,11 @@ use App\Casts\EnumCast;
|
||||
use App\Contracts\DataRequest;
|
||||
use App\Enums\PeopleOrderByEnum;
|
||||
use App\Http\Resources\V4\PersonCollection;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements DataRequest<PersonCollection>
|
||||
|
@ -6,11 +6,11 @@ use App\Casts\EnumCast;
|
||||
use App\Contracts\DataRequest;
|
||||
use App\Enums\ProducerOrderByEnum;
|
||||
use App\Http\Resources\V4\ProducerCollection;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements DataRequest<ProducerCollection>
|
||||
|
@ -6,18 +6,14 @@ namespace App\Dto;
|
||||
use App\Casts\EnumCast;
|
||||
use App\Concerns\HasRequestFingerprint;
|
||||
use App\Contracts\DataRequest;
|
||||
use App\Dto\Concerns\MapsDefaultLimitParameter;
|
||||
use App\Dto\Concerns\HasLimitParameter;
|
||||
use App\Dto\Concerns\HasPageParameter;
|
||||
use App\Enums\AnimeScheduleFilterEnum;
|
||||
use App\Rules\Attributes\MaxLimitWithFallback;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Env;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\Validation\BooleanType;
|
||||
use Spatie\LaravelData\Attributes\Validation\IntegerType;
|
||||
use Spatie\LaravelData\Attributes\Validation\Min;
|
||||
use Spatie\LaravelData\Attributes\Validation\Nullable;
|
||||
use Spatie\LaravelData\Attributes\Validation\Numeric;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Data;
|
||||
use Spatie\LaravelData\Optional;
|
||||
@ -27,13 +23,7 @@ use Spatie\LaravelData\Optional;
|
||||
*/
|
||||
final class QueryAnimeSchedulesCommand extends Data implements DataRequest
|
||||
{
|
||||
use MapsDefaultLimitParameter, HasRequestFingerprint;
|
||||
|
||||
#[Numeric, Min(1)]
|
||||
public int|Optional $page = 1;
|
||||
|
||||
#[IntegerType, Min(1), MaxLimitWithFallback]
|
||||
public int|Optional $limit;
|
||||
use HasLimitParameter, HasRequestFingerprint, HasPageParameter;
|
||||
|
||||
#[BooleanType]
|
||||
public bool|Optional $kids = false;
|
||||
|
@ -6,12 +6,10 @@ namespace App\Dto;
|
||||
use App\Casts\EnumCast;
|
||||
use App\Concerns\HasRequestFingerprint;
|
||||
use App\Contracts\DataRequest;
|
||||
use App\Dto\Concerns\MapsDefaultLimitParameter;
|
||||
use App\Dto\Concerns\HasLimitParameter;
|
||||
use App\Dto\Concerns\HasPageParameter;
|
||||
use App\Enums\AnimeTypeEnum;
|
||||
use App\Rules\Attributes\MaxLimitWithFallback;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\Validation\Min;
|
||||
use Spatie\LaravelData\Attributes\Validation\Numeric;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Data;
|
||||
use Spatie\LaravelData\Optional;
|
||||
@ -19,18 +17,11 @@ use Spatie\LaravelData\Optional;
|
||||
|
||||
abstract class QueryAnimeSeasonCommand extends Data implements DataRequest
|
||||
{
|
||||
use MapsDefaultLimitParameter, HasRequestFingerprint;
|
||||
use HasLimitParameter, HasRequestFingerprint, HasPageParameter;
|
||||
|
||||
#[WithCast(EnumCast::class, AnimeTypeEnum::class)]
|
||||
public AnimeTypeEnum|Optional $filter;
|
||||
|
||||
#[Numeric, Min(1)]
|
||||
public int|Optional $page = 1;
|
||||
|
||||
#[Numeric, Min(1), MaxLimitWithFallback]
|
||||
public int|Optional $limit;
|
||||
|
||||
|
||||
public static function rules(...$args): array
|
||||
{
|
||||
return [
|
||||
|
@ -4,9 +4,9 @@ namespace App\Dto;
|
||||
|
||||
use App\Contracts\DataRequest;
|
||||
use App\Http\Resources\V4\AnimeResource;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\LaravelData\Attributes\Validation\BooleanType;
|
||||
use Spatie\LaravelData\Data;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements DataRequest<AnimeResource>
|
||||
|
@ -4,9 +4,9 @@ namespace App\Dto;
|
||||
|
||||
use App\Contracts\DataRequest;
|
||||
use App\Http\Resources\V4\MangaResource;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\LaravelData\Attributes\Validation\BooleanType;
|
||||
use Spatie\LaravelData\Data;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements DataRequest<MangaResource>
|
||||
|
15
app/Dto/QueryRecentlyOnlineUsersCommand.php
Normal file
15
app/Dto/QueryRecentlyOnlineUsersCommand.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use App\Contracts\DataRequest;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
/**
|
||||
* @extends DataRequest<JsonResponse>
|
||||
*/
|
||||
final class QueryRecentlyOnlineUsersCommand extends Data implements DataRequest
|
||||
{
|
||||
}
|
@ -6,6 +6,7 @@ namespace App\Dto;
|
||||
use App\Casts\EnumCast;
|
||||
use App\Concerns\HasRequestFingerprint;
|
||||
use App\Contracts\DataRequest;
|
||||
use App\Dto\Concerns\HasPageParameter;
|
||||
use App\Enums\MediaReviewsSortEnum;
|
||||
use App\Http\Resources\V4\ResultsResource;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
@ -21,10 +22,7 @@ use Spatie\LaravelData\Optional;
|
||||
*/
|
||||
abstract class QueryReviewsCommand extends Data implements DataRequest
|
||||
{
|
||||
use HasRequestFingerprint;
|
||||
|
||||
#[Numeric, Min(1)]
|
||||
public int|Optional $page = 1;
|
||||
use HasRequestFingerprint, HasPageParameter;
|
||||
|
||||
#[WithCast(EnumCast::class, MediaReviewsSortEnum::class)]
|
||||
public MediaReviewsSortEnum|Optional $sort;
|
||||
|
@ -2,20 +2,11 @@
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
use App\Dto\Concerns\MapsDefaultLimitParameter;
|
||||
use App\Rules\Attributes\MaxLimitWithFallback;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\LaravelData\Attributes\Validation\Min;
|
||||
use Spatie\LaravelData\Attributes\Validation\Numeric;
|
||||
use App\Dto\Concerns\HasLimitParameter;
|
||||
use App\Dto\Concerns\HasPageParameter;
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
abstract class QueryTopItemsCommand extends Data
|
||||
{
|
||||
use MapsDefaultLimitParameter;
|
||||
|
||||
#[Numeric, Min(1)]
|
||||
public int|Optional $page = 1;
|
||||
|
||||
#[Numeric, Min(1), MaxLimitWithFallback]
|
||||
public int|Optional $limit;
|
||||
use HasLimitParameter, HasPageParameter;
|
||||
}
|
||||
|
@ -7,10 +7,9 @@ use App\Contracts\DataRequest;
|
||||
use App\Enums\MangaTypeEnum;
|
||||
use App\Enums\TopMangaFilterEnum;
|
||||
use App\Http\Resources\V4\MangaCollection;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\Validation\Rule;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements DataRequest<MangaCollection>
|
||||
|
@ -3,17 +3,12 @@
|
||||
namespace App\Dto;
|
||||
|
||||
use App\Casts\EnumCast;
|
||||
use App\Dto\Concerns\MapsDefaultLimitParameter;
|
||||
use App\Dto\Concerns\HasLimitParameter;
|
||||
use App\Dto\Concerns\HasPageParameter;
|
||||
use App\Enums\SortDirection;
|
||||
use App\Rules\Attributes\MaxLimitWithFallback;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||
use Spatie\LaravelData\Attributes\Validation\Alpha;
|
||||
use Spatie\LaravelData\Attributes\Validation\IntegerType;
|
||||
use Spatie\LaravelData\Attributes\Validation\Max;
|
||||
use Spatie\LaravelData\Attributes\Validation\Min;
|
||||
use Spatie\LaravelData\Attributes\Validation\Numeric;
|
||||
use Spatie\LaravelData\Attributes\Validation\Size;
|
||||
use Spatie\LaravelData\Attributes\Validation\StringType;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
@ -22,7 +17,7 @@ use Spatie\LaravelData\Optional;
|
||||
|
||||
class SearchCommand extends Data
|
||||
{
|
||||
use MapsDefaultLimitParameter;
|
||||
use HasLimitParameter, HasPageParameter;
|
||||
|
||||
/**
|
||||
* The search keywords
|
||||
@ -31,12 +26,6 @@ class SearchCommand extends Data
|
||||
#[Max(255), StringType]
|
||||
public string|Optional $q;
|
||||
|
||||
#[Numeric, Min(1)]
|
||||
public int|Optional $page = 1;
|
||||
|
||||
#[IntegerType, Min(1), MaxLimitWithFallback]
|
||||
public int|Optional $limit;
|
||||
|
||||
#[WithCast(EnumCast::class, SortDirection::class)]
|
||||
public SortDirection|Optional $sort;
|
||||
|
||||
|
13
app/Dto/UserAboutLookupCommand.php
Normal file
13
app/Dto/UserAboutLookupCommand.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserAboutLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
}
|
13
app/Dto/UserClubsLookupCommand.php
Normal file
13
app/Dto/UserClubsLookupCommand.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserClubsLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
}
|
13
app/Dto/UserExternalLookupCommand.php
Normal file
13
app/Dto/UserExternalLookupCommand.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserExternalLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
}
|
13
app/Dto/UserFavoritesLookupCommand.php
Normal file
13
app/Dto/UserFavoritesLookupCommand.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserFavoritesLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
}
|
15
app/Dto/UserFriendsLookupCommand.php
Normal file
15
app/Dto/UserFriendsLookupCommand.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use App\Dto\Concerns\HasPageParameter;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserFriendsLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
use HasPageParameter;
|
||||
}
|
13
app/Dto/UserFullLookupCommand.php
Normal file
13
app/Dto/UserFullLookupCommand.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserFullLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
}
|
27
app/Dto/UserHistoryLookupCommand.php
Normal file
27
app/Dto/UserHistoryLookupCommand.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use App\Casts\EnumCast;
|
||||
use App\Enums\UserHistoryTypeEnum;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\Validation\Nullable;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserHistoryLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
#[WithCast(EnumCast::class, UserHistoryTypeEnum::class)]
|
||||
public ?UserHistoryTypeEnum $type;
|
||||
|
||||
public static function rules(...$args): array
|
||||
{
|
||||
return [
|
||||
"type" => [new EnumRule(UserHistoryTypeEnum::class), new Nullable()]
|
||||
];
|
||||
}
|
||||
}
|
13
app/Dto/UserProfileLookupCommand.php
Normal file
13
app/Dto/UserProfileLookupCommand.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserProfileLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
}
|
15
app/Dto/UserRecommendationsLookupCommand.php
Normal file
15
app/Dto/UserRecommendationsLookupCommand.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use App\Dto\Concerns\HasPageParameter;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserRecommendationsLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
use HasPageParameter;
|
||||
}
|
15
app/Dto/UserReviewsLookupCommand.php
Normal file
15
app/Dto/UserReviewsLookupCommand.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use App\Dto\Concerns\HasPageParameter;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserReviewsLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
use HasPageParameter;
|
||||
}
|
13
app/Dto/UserStatisticsLookupCommand.php
Normal file
13
app/Dto/UserStatisticsLookupCommand.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserStatisticsLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
}
|
13
app/Dto/UserUpdatesLookupCommand.php
Normal file
13
app/Dto/UserUpdatesLookupCommand.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @extends LookupDataCommand<JsonResponse>
|
||||
*/
|
||||
final class UserUpdatesLookupCommand extends LookupByUsernameCommand
|
||||
{
|
||||
}
|
@ -7,10 +7,10 @@ use App\Concerns\HasRequestFingerprint;
|
||||
use App\Contracts\DataRequest;
|
||||
use App\Enums\GenderEnum;
|
||||
use App\Http\Resources\V4\UserCollection;
|
||||
use Illuminate\Support\Optional;
|
||||
use Spatie\Enum\Laravel\Rules\EnumRule;
|
||||
use Spatie\LaravelData\Attributes\Validation\StringType;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements DataRequest<UserCollection>
|
||||
|
14
app/Enums/UserHistoryTypeEnum.php
Normal file
14
app/Enums/UserHistoryTypeEnum.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
|
||||
use Spatie\Enum\Laravel\Enum;
|
||||
|
||||
/**
|
||||
* @method static self anime()
|
||||
* @method static self manga()
|
||||
*/
|
||||
final class UserHistoryTypeEnum extends Enum
|
||||
{
|
||||
}
|
29
app/Features/QueryRecentlyOnlineUsersHandler.php
Normal file
29
app/Features/QueryRecentlyOnlineUsersHandler.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\QueryRecentlyOnlineUsersCommand;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use App\Support\CachedData;
|
||||
use Jikan\MyAnimeList\MalClient;
|
||||
use Jikan\Request\User\RecentlyOnlineUsersRequest;
|
||||
|
||||
/**
|
||||
* @extends RequestHandlerWithScraperCache<QueryRecentlyOnlineUsersCommand, JsonResponse>
|
||||
*/
|
||||
final class QueryRecentlyOnlineUsersHandler extends RequestHandlerWithScraperCache
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return QueryRecentlyOnlineUsersCommand::class;
|
||||
}
|
||||
|
||||
protected function getScraperData(string $requestFingerPrint, Collection $requestParams): CachedData
|
||||
{
|
||||
return $this->scraperService->findList(
|
||||
$requestFingerPrint,
|
||||
fn(MalClient $jikan, ?int $page = null) => ["results" => $jikan->getRecentOnlineUsers(new RecentlyOnlineUsersRequest())]
|
||||
);
|
||||
}
|
||||
}
|
24
app/Features/UserAboutLookupHandler.php
Normal file
24
app/Features/UserAboutLookupHandler.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserAboutLookupCommand;
|
||||
use App\Http\Resources\V4\ProfileAboutResource;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @extends UserLookupHandler<UserAboutLookupCommand>
|
||||
*/
|
||||
final class UserAboutLookupHandler extends UserLookupHandler
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserAboutLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function resource(Collection $results): JsonResource
|
||||
{
|
||||
return new ProfileAboutResource($results->first());
|
||||
}
|
||||
}
|
30
app/Features/UserClubsLookupHandler.php
Normal file
30
app/Features/UserClubsLookupHandler.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserClubsLookupCommand;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use App\Support\CachedData;
|
||||
use Jikan\MyAnimeList\MalClient;
|
||||
use Jikan\Request\User\UserClubsRequest;
|
||||
|
||||
/**
|
||||
* @extends RequestHandlerWithScraperCache<UserClubsLookupCommand, JsonResponse>
|
||||
*/
|
||||
final class UserClubsLookupHandler extends RequestHandlerWithScraperCache
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserClubsLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function getScraperData(string $requestFingerPrint, Collection $requestParams): CachedData
|
||||
{
|
||||
$username = $requestParams->get("username");
|
||||
return $this->scraperService->findList(
|
||||
$requestFingerPrint,
|
||||
fn(MalClient $jikan, ?int $page = null) => ["results" => $jikan->getUserClubs(new UserClubsRequest($username))]
|
||||
);
|
||||
}
|
||||
}
|
24
app/Features/UserExternalLookupHandler.php
Normal file
24
app/Features/UserExternalLookupHandler.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserExternalLookupCommand;
|
||||
use App\Http\Resources\V4\ExternalLinksResource;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @extends UserLookupHandler<UserExternalLookupCommand>
|
||||
*/
|
||||
final class UserExternalLookupHandler extends UserLookupHandler
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserExternalLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function resource(Collection $results): JsonResource
|
||||
{
|
||||
return new ExternalLinksResource($results->first());
|
||||
}
|
||||
}
|
24
app/Features/UserFavoritesLookupHandler.php
Normal file
24
app/Features/UserFavoritesLookupHandler.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserFavoritesLookupCommand;
|
||||
use App\Http\Resources\V4\ProfileFavoritesResource;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @extends UserLookupHandler<UserFavoritesLookupCommand>
|
||||
*/
|
||||
final class UserFavoritesLookupHandler extends UserLookupHandler
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserFavoritesLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function resource(Collection $results): JsonResource
|
||||
{
|
||||
return new ProfileFavoritesResource($results->first());
|
||||
}
|
||||
}
|
31
app/Features/UserFriendsLookupHandler.php
Normal file
31
app/Features/UserFriendsLookupHandler.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserFriendsLookupCommand;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use App\Support\CachedData;
|
||||
use Jikan\MyAnimeList\MalClient;
|
||||
use Jikan\Request\User\UserFriendsRequest;
|
||||
|
||||
/**
|
||||
* @extends RequestHandlerWithScraperCache<UserFriendsLookupCommand, JsonResponse>
|
||||
*/
|
||||
final class UserFriendsLookupHandler extends RequestHandlerWithScraperCache
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserFriendsLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function getScraperData(string $requestFingerPrint, Collection $requestParams): CachedData
|
||||
{
|
||||
$username = $requestParams->get("username");
|
||||
return $this->scraperService->findList(
|
||||
$requestFingerPrint,
|
||||
fn(MalClient $jikan, ?int $page = null) => $jikan->getUserFriends(new UserFriendsRequest($username, $page)),
|
||||
$requestParams->get("page", 1)
|
||||
);
|
||||
}
|
||||
}
|
24
app/Features/UserFullLookupHandler.php
Normal file
24
app/Features/UserFullLookupHandler.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserFullLookupCommand;
|
||||
use App\Http\Resources\V4\ProfileFullResource;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @extends UserLookupHandler<UserFullLookupCommand>
|
||||
*/
|
||||
final class UserFullLookupHandler extends UserLookupHandler
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserFullLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function resource(Collection $results): JsonResource
|
||||
{
|
||||
return new ProfileFullResource($results->first());
|
||||
}
|
||||
}
|
39
app/Features/UserHistoryLookupHandler.php
Normal file
39
app/Features/UserHistoryLookupHandler.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserHistoryLookupCommand;
|
||||
use App\Http\Resources\V4\ProfileHistoryResource;
|
||||
use App\Support\CachedData;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Collection;
|
||||
use Jikan\MyAnimeList\MalClient;
|
||||
use Jikan\Request\User\UserHistoryRequest;
|
||||
|
||||
/**
|
||||
* @extends RequestHandlerWithScraperCache<UserHistoryLookupCommand>
|
||||
*/
|
||||
final class UserHistoryLookupHandler extends RequestHandlerWithScraperCache
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserHistoryLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function resource(Collection $results): JsonResource
|
||||
{
|
||||
return new ProfileHistoryResource($results->first());
|
||||
}
|
||||
|
||||
protected function getScraperData(string $requestFingerPrint, Collection $requestParams): CachedData
|
||||
{
|
||||
$type = $requestParams->get("type");
|
||||
$username = $requestParams->get("username");
|
||||
return $this->scraperService->findList(
|
||||
$requestFingerPrint,
|
||||
fn(MalClient $jikan, ?int $page = null) => ["history" => $jikan->getUserHistory(new UserHistoryRequest(
|
||||
$username, $type
|
||||
))]
|
||||
);
|
||||
}
|
||||
}
|
26
app/Features/UserLookupHandler.php
Normal file
26
app/Features/UserLookupHandler.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Collection;
|
||||
use App\Support\CachedData;
|
||||
use Jikan\MyAnimeList\MalClient;
|
||||
|
||||
/**
|
||||
* @template TRequest
|
||||
* @extends RequestHandlerWithScraperCache<TRequest, JsonResponse>
|
||||
*/
|
||||
abstract class UserLookupHandler extends RequestHandlerWithScraperCache
|
||||
{
|
||||
protected function getScraperData(string $requestFingerPrint, Collection $requestParams): CachedData
|
||||
{
|
||||
$username = $requestParams->get("username");
|
||||
return $this->scraperService->findByKey(
|
||||
"username",
|
||||
$username,
|
||||
$requestFingerPrint,
|
||||
);
|
||||
}
|
||||
}
|
24
app/Features/UserProfileLookupHandler.php
Normal file
24
app/Features/UserProfileLookupHandler.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserProfileLookupCommand;
|
||||
use App\Http\Resources\V4\ProfileResource;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @extends UserLookupHandler<UserProfileLookupCommand>
|
||||
*/
|
||||
final class UserProfileLookupHandler extends UserLookupHandler
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserProfileLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function resource(Collection $results): JsonResource
|
||||
{
|
||||
return new ProfileResource($results->first());
|
||||
}
|
||||
}
|
31
app/Features/UserRecommendationsLookupHandler.php
Normal file
31
app/Features/UserRecommendationsLookupHandler.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserRecommendationsLookupCommand;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use App\Support\CachedData;
|
||||
use Jikan\MyAnimeList\MalClient;
|
||||
use Jikan\Request\User\UserRecommendationsRequest;
|
||||
|
||||
/**
|
||||
* @extends RequestHandlerWithScraperCache<UserRecommendationsLookupCommand, JsonResponse>
|
||||
*/
|
||||
final class UserRecommendationsLookupHandler extends RequestHandlerWithScraperCache
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserRecommendationsLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function getScraperData(string $requestFingerPrint, Collection $requestParams): CachedData
|
||||
{
|
||||
$username = $requestParams->get("username");
|
||||
return $this->scraperService->findList(
|
||||
$requestFingerPrint,
|
||||
fn(MalClient $jikan, ?int $page = null) => $jikan->getUserRecommendations(new UserRecommendationsRequest($username, $page)),
|
||||
$requestParams->get("page", 1)
|
||||
);
|
||||
}
|
||||
}
|
36
app/Features/UserReviewsLookupHandler.php
Normal file
36
app/Features/UserReviewsLookupHandler.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserReviewsLookupCommand;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use App\Support\CachedData;
|
||||
use Jikan\MyAnimeList\MalClient;
|
||||
use Jikan\Request\User\UserReviewsRequest;
|
||||
|
||||
/**
|
||||
* @extends RequestHandlerWithScraperCache<UserReviewsLookupCommand, JsonResponse>
|
||||
*/
|
||||
final class UserReviewsLookupHandler extends RequestHandlerWithScraperCache
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserReviewsLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function getScraperData(string $requestFingerPrint, Collection $requestParams): CachedData
|
||||
{
|
||||
$username = $requestParams->get("username");
|
||||
return $this->scraperService->findList(
|
||||
$requestFingerPrint,
|
||||
fn(MalClient $jikan, ?int $page = null) => $jikan->getUserReviews(
|
||||
new UserReviewsRequest(
|
||||
$username,
|
||||
$page,
|
||||
)
|
||||
),
|
||||
$requestParams->get("page", 1)
|
||||
);
|
||||
}
|
||||
}
|
24
app/Features/UserStatisticsLookupHandler.php
Normal file
24
app/Features/UserStatisticsLookupHandler.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserStatisticsLookupCommand;
|
||||
use App\Http\Resources\V4\ProfileStatisticsResource;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @extends UserLookupHandler<UserStatisticsLookupCommand>
|
||||
*/
|
||||
final class UserStatisticsLookupHandler extends UserLookupHandler
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserStatisticsLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function resource(Collection $results): JsonResource
|
||||
{
|
||||
return new ProfileStatisticsResource($results->first());
|
||||
}
|
||||
}
|
24
app/Features/UserUpdatesLookupHandler.php
Normal file
24
app/Features/UserUpdatesLookupHandler.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Dto\UserUpdatesLookupCommand;
|
||||
use App\Http\Resources\V4\ProfileLastUpdatesResource;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @extends UserLookupHandler<UserUpdatesLookupCommand>
|
||||
*/
|
||||
final class UserUpdatesLookupHandler extends UserLookupHandler
|
||||
{
|
||||
public function requestClass(): string
|
||||
{
|
||||
return UserUpdatesLookupCommand::class;
|
||||
}
|
||||
|
||||
protected function resource(Collection $results): JsonResource
|
||||
{
|
||||
return new ProfileLastUpdatesResource($results->first());
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\V4DB\Traits;
|
||||
|
||||
use App\Providers\SearchQueryBuilderProvider;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
trait JikanApiQueryBuilder
|
||||
{
|
||||
private SearchQueryBuilderProvider $searchQueryBuilderProvider;
|
||||
|
||||
protected function getQueryBuilder(string $name, Request $request): \Illuminate\Database\Eloquent\Builder|\Laravel\Scout\Builder
|
||||
{
|
||||
$queryBuilder = $this->searchQueryBuilderProvider->getQueryBuilder($name);
|
||||
return $queryBuilder->query($request);
|
||||
}
|
||||
|
||||
protected function getPaginator(string $name, Request $request, \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $results): \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
{
|
||||
$queryBuilder = $this->searchQueryBuilderProvider->getQueryBuilder($name);
|
||||
return $queryBuilder->paginateBuilder($request, $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param class-string<T> $resourceCollectionClass
|
||||
* @param string $resourceTypeName
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return T
|
||||
*/
|
||||
protected function preparePaginatedResponse(string $resourceCollectionClass, string $resourceTypeName, Request $request)
|
||||
{
|
||||
$results = $this->getQueryBuilder($resourceTypeName, $request);
|
||||
$paginator = $this->getPaginator($resourceTypeName, $request, $results);
|
||||
return new $resourceCollectionClass($paginator);
|
||||
}
|
||||
}
|
@ -2,29 +2,20 @@
|
||||
|
||||
namespace App\Http\Controllers\V4DB;
|
||||
|
||||
use App\Http\HttpResponse;
|
||||
use App\Http\QueryBuilder\UserListQueryBuilder;
|
||||
use App\Http\Resources\V4\ExternalLinksResource;
|
||||
use App\Http\Resources\V4\ProfileHistoryResource;
|
||||
use App\Http\Resources\V4\ResultsResource;
|
||||
use App\Http\Resources\V4\UserProfileAnimeListCollection;
|
||||
use App\Http\Resources\V4\UserProfileAnimeListResource;
|
||||
use App\Http\Resources\V4\UserProfileMangaListCollection;
|
||||
use App\Http\Resources\V4\UserProfileMangaListResource;
|
||||
use App\Profile;
|
||||
use App\Dto\QueryRecentlyOnlineUsersCommand;
|
||||
use App\Dto\UserAboutLookupCommand;
|
||||
use App\Dto\UserClubsLookupCommand;
|
||||
use App\Dto\UserExternalLookupCommand;
|
||||
use App\Dto\UserFavoritesLookupCommand;
|
||||
use App\Dto\UserFriendsLookupCommand;
|
||||
use App\Dto\UserFullLookupCommand;
|
||||
use App\Dto\UserHistoryLookupCommand;
|
||||
use App\Dto\UserProfileLookupCommand;
|
||||
use App\Dto\UserRecommendationsLookupCommand;
|
||||
use App\Dto\UserReviewsLookupCommand;
|
||||
use App\Dto\UserStatisticsLookupCommand;
|
||||
use App\Dto\UserUpdatesLookupCommand;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Jikan\Helper\Constants;
|
||||
use Jikan\Request\User\RecentlyOnlineUsersRequest;
|
||||
use Jikan\Request\User\UserAnimeListRequest;
|
||||
use Jikan\Request\User\UserClubsRequest;
|
||||
use Jikan\Request\User\UserFriendsRequest;
|
||||
use Jikan\Request\User\UserHistoryRequest;
|
||||
use Jikan\Request\User\UserMangaListRequest;
|
||||
use Jikan\Request\User\UserRecommendationsRequest;
|
||||
use Jikan\Request\User\UserReviewsRequest;
|
||||
use MongoDB\BSON\UTCDateTime;
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
|
||||
/**
|
||||
* Class Controller
|
||||
@ -62,61 +53,9 @@ class UserController extends Controller
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
public function full(Request $request, string $username)
|
||||
public function full(UserFullLookupCommand $command)
|
||||
{
|
||||
$username = strtolower($username);
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$response = Profile::scrape($username);
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
$meta = [
|
||||
'createdAt' => new UTCDateTime(),
|
||||
'modifiedAt' => new UTCDateTime(),
|
||||
'request_hash' => $this->fingerprint,
|
||||
'internal_username' => $username
|
||||
];
|
||||
}
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
$response = $meta + $response;
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
Profile::query()
|
||||
->insert($response);
|
||||
}
|
||||
|
||||
if ($this->isExpired($request, $results)) {
|
||||
Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->update($response);
|
||||
}
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
$response = (new \App\Http\Resources\V4\ProfileFullResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,61 +87,9 @@ class UserController extends Controller
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
public function profile(Request $request, string $username)
|
||||
public function profile(UserProfileLookupCommand $command)
|
||||
{
|
||||
$username = strtolower($username);
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$response = Profile::scrape($username);
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
$meta = [
|
||||
'createdAt' => new UTCDateTime(),
|
||||
'modifiedAt' => new UTCDateTime(),
|
||||
'request_hash' => $this->fingerprint,
|
||||
'internal_username' => $username
|
||||
];
|
||||
}
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
$response = $meta + $response;
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
Profile::query()
|
||||
->insert($response);
|
||||
}
|
||||
|
||||
if ($this->isExpired($request, $results)) {
|
||||
Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->update($response);
|
||||
}
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
$response = (new \App\Http\Resources\V4\ProfileResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,62 +118,9 @@ class UserController extends Controller
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
public function statistics(Request $request, string $username)
|
||||
public function statistics(UserStatisticsLookupCommand $command)
|
||||
{
|
||||
|
||||
$username = strtolower($username);
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$response = Profile::scrape($username);
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
$meta = [
|
||||
'createdAt' => new UTCDateTime(),
|
||||
'modifiedAt' => new UTCDateTime(),
|
||||
'request_hash' => $this->fingerprint,
|
||||
'internal_username' => $username
|
||||
];
|
||||
}
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
$response = $meta + $response;
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
Profile::query()
|
||||
->insert($response);
|
||||
}
|
||||
|
||||
if ($this->isExpired($request, $results)) {
|
||||
Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->update($response);
|
||||
}
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
$response = (new \App\Http\Resources\V4\ProfileStatisticsResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
|
||||
@ -319,62 +153,9 @@ class UserController extends Controller
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
public function favorites(Request $request, string $username)
|
||||
public function favorites(UserFavoritesLookupCommand $command)
|
||||
{
|
||||
|
||||
$username = strtolower($username);
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$response = Profile::scrape($username);
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
$meta = [
|
||||
'createdAt' => new UTCDateTime(),
|
||||
'modifiedAt' => new UTCDateTime(),
|
||||
'request_hash' => $this->fingerprint,
|
||||
'internal_username' => $username
|
||||
];
|
||||
}
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
$response = $meta + $response;
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
Profile::query()
|
||||
->insert($response);
|
||||
}
|
||||
|
||||
if ($this->isExpired($request, $results)) {
|
||||
Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->update($response);
|
||||
}
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
$response = (new \App\Http\Resources\V4\ProfileFavoritesResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -403,62 +184,9 @@ class UserController extends Controller
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
public function userupdates(Request $request, string $username)
|
||||
public function userupdates(UserUpdatesLookupCommand $command)
|
||||
{
|
||||
|
||||
$username = strtolower($username);
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$response = Profile::scrape($username);
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
$meta = [
|
||||
'createdAt' => new UTCDateTime(),
|
||||
'modifiedAt' => new UTCDateTime(),
|
||||
'request_hash' => $this->fingerprint,
|
||||
'internal_username' => $username
|
||||
];
|
||||
}
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
$response = $meta + $response;
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
Profile::query()
|
||||
->insert($response);
|
||||
}
|
||||
|
||||
if ($this->isExpired($request, $results)) {
|
||||
Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->update($response);
|
||||
}
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
$response = (new \App\Http\Resources\V4\ProfileLastUpdatesResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -487,62 +215,9 @@ class UserController extends Controller
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
public function about(Request $request, string $username)
|
||||
public function about(UserAboutLookupCommand $command)
|
||||
{
|
||||
|
||||
$username = strtolower($username);
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$response = Profile::scrape($username);
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
$meta = [
|
||||
'createdAt' => new UTCDateTime(),
|
||||
'modifiedAt' => new UTCDateTime(),
|
||||
'request_hash' => $this->fingerprint,
|
||||
'internal_username' => $username
|
||||
];
|
||||
}
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
$response = $meta + $response;
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
Profile::query()
|
||||
->insert($response);
|
||||
}
|
||||
|
||||
if ($this->isExpired($request, $results)) {
|
||||
Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->update($response);
|
||||
}
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
$response = (new \App\Http\Resources\V4\ProfileAboutResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -578,45 +253,9 @@ class UserController extends Controller
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
public function history(Request $request, string $username, ?string $type = null)
|
||||
public function history(UserHistoryLookupCommand $command)
|
||||
{
|
||||
$filter = $request->get('filter') ?? null;
|
||||
|
||||
if (!is_null($type)) {
|
||||
$type = strtolower($type);
|
||||
}
|
||||
|
||||
if (!is_null($filter) && is_null($type)) {
|
||||
$type = strtolower($filter);
|
||||
}
|
||||
|
||||
if (!is_null($type) && !\in_array($type, ['anime', 'manga'])) {
|
||||
return HttpResponse::badRequest($request);
|
||||
}
|
||||
|
||||
$results = DB::table($this->getRouteTable($request))
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$data = ['history'=>$this->jikan->getUserHistory(new UserHistoryRequest($username, $type))];
|
||||
$response = \json_decode($this->serializer->serialize($data, 'json'), true);
|
||||
|
||||
$results = $this->updateCache($request, $results, $response);
|
||||
}
|
||||
|
||||
$response = (new ProfileHistoryResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -690,32 +329,9 @@ class UserController extends Controller
|
||||
* }
|
||||
* ),
|
||||
*/
|
||||
public function friends(Request $request, string $username)
|
||||
public function friends(UserFriendsLookupCommand $command)
|
||||
{
|
||||
$results = DB::table($this->getRouteTable($request))
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$page = $request->get('page') ?? 1;
|
||||
$data = $this->jikan->getUserFriends(new UserFriendsRequest($username, $page));
|
||||
$response = \json_decode($this->serializer->serialize($data, 'json'), true);
|
||||
|
||||
$results = $this->updateCache($request, $results, $response);
|
||||
}
|
||||
|
||||
$response = (new ResultsResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -748,51 +364,8 @@ class UserController extends Controller
|
||||
*/
|
||||
public function animelist(Request $request, string $username, ?string $status = null)
|
||||
{
|
||||
if (!is_null($status)) {
|
||||
$status = strtolower($status);
|
||||
|
||||
if (!\in_array($status, ['all', 'watching', 'completed', 'onhold', 'dropped', 'plantowatch'])) {
|
||||
return HttpResponse::badRequest($request);
|
||||
}
|
||||
}
|
||||
$status = $this->listStatusToId($status);
|
||||
|
||||
|
||||
$results = DB::table($this->getRouteTable($request))
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$page = $request->get('page') ?? 1;
|
||||
$data = $this->jikan->getUserAnimeList(
|
||||
UserListQueryBuilder::create(
|
||||
$request,
|
||||
new UserAnimeListRequest($username, $page, $status)
|
||||
)
|
||||
);
|
||||
$response = ['anime' => \json_decode($this->serializer->serialize($data, 'json'), true)];
|
||||
|
||||
$results = $this->updateCache($request, $results, $response);
|
||||
}
|
||||
|
||||
$listResults = $results->first()['anime'];
|
||||
|
||||
foreach ($listResults as &$result) {
|
||||
$result = (new UserProfileAnimeListResource($result));
|
||||
}
|
||||
|
||||
$response = (new UserProfileAnimeListCollection(
|
||||
$listResults
|
||||
))->response($request);
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
// noop, intentionally left blank
|
||||
// todo: remove as this is obsolete
|
||||
}
|
||||
|
||||
/**
|
||||
@ -825,52 +398,8 @@ class UserController extends Controller
|
||||
*/
|
||||
public function mangalist(Request $request, string $username, ?string $status = null)
|
||||
{
|
||||
if (!is_null($status)) {
|
||||
$status = strtolower($status);
|
||||
|
||||
if (!\in_array($status, ['all', 'reading', 'completed', 'onhold', 'dropped', 'plantoread', 'ptr'])) {
|
||||
return response()->json([
|
||||
'error' => 'Bad Request'
|
||||
])->setStatusCode(400);
|
||||
}
|
||||
}
|
||||
$status = $this->listStatusToId($status);
|
||||
|
||||
$results = DB::table($this->getRouteTable($request))
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$page = $request->get('page') ?? 1;
|
||||
$data = $this->jikan->getUserMangaList(
|
||||
UserListQueryBuilder::create(
|
||||
$request,
|
||||
new UserMangaListRequest($username, $page, $status)
|
||||
)
|
||||
);
|
||||
$response = ['manga' => \json_decode($this->serializer->serialize($data, 'json'), true)];
|
||||
|
||||
$results = $this->updateCache($request, $results, $response);
|
||||
}
|
||||
|
||||
$listResults = $results->first()['manga'];
|
||||
|
||||
foreach ($listResults as &$result) {
|
||||
$result = (new UserProfileMangaListResource($result));
|
||||
}
|
||||
|
||||
$response = (new UserProfileMangaListCollection(
|
||||
$listResults
|
||||
))->response($request);
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
// noop, intentionally left blank
|
||||
// todo: remove as this is obsolete
|
||||
}
|
||||
|
||||
/**
|
||||
@ -955,39 +484,9 @@ class UserController extends Controller
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
public function reviews(Request $request, string $username)
|
||||
public function reviews(UserReviewsLookupCommand $command)
|
||||
{
|
||||
$results = DB::table($this->getRouteTable($request))
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$page = $request->get('page') ?? 1;
|
||||
|
||||
$data = $this->jikan
|
||||
->getUserReviews(
|
||||
new UserReviewsRequest(
|
||||
$username,
|
||||
$page,
|
||||
)
|
||||
);
|
||||
|
||||
$response = \json_decode($this->serializer->serialize($data, 'json'), true);
|
||||
$results = $this->updateCache($request, $results, $response);
|
||||
}
|
||||
|
||||
$response = (new ResultsResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1017,32 +516,9 @@ class UserController extends Controller
|
||||
* ),
|
||||
*
|
||||
*/
|
||||
public function recommendations(Request $request, string $username)
|
||||
public function recommendations(UserRecommendationsLookupCommand $command)
|
||||
{
|
||||
$results = DB::table($this->getRouteTable($request))
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$page = $request->get('page') ?? 1;
|
||||
$data = $this->jikan->getUserRecommendations(new UserRecommendationsRequest($username, $page));
|
||||
$response = \json_decode($this->serializer->serialize($data, 'json'), true);
|
||||
|
||||
$results = $this->updateCache($request, $results, $response);
|
||||
}
|
||||
|
||||
$response = (new ResultsResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1106,31 +582,9 @@ class UserController extends Controller
|
||||
* }
|
||||
* ),
|
||||
*/
|
||||
public function clubs(Request $request, string $username)
|
||||
public function clubs(UserClubsLookupCommand $command)
|
||||
{
|
||||
$results = DB::table($this->getRouteTable($request))
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$data = ['results' => $this->jikan->getUserClubs(new UserClubsRequest($username))];
|
||||
$response = \json_decode($this->serializer->serialize($data, 'json'), true);
|
||||
|
||||
$results = $this->updateCache($request, $results, $response);
|
||||
}
|
||||
|
||||
$response = (new ResultsResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1160,125 +614,13 @@ class UserController extends Controller
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
public function external(Request $request, string $username)
|
||||
public function external(UserExternalLookupCommand $command)
|
||||
{
|
||||
$username = strtolower($username);
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$response = Profile::scrape($username);
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
$meta = [
|
||||
'createdAt' => new UTCDateTime(),
|
||||
'modifiedAt' => new UTCDateTime(),
|
||||
'request_hash' => $this->fingerprint,
|
||||
'internal_username' => $username
|
||||
];
|
||||
}
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
$response = $meta + $response;
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
Profile::query()
|
||||
->insert($response);
|
||||
}
|
||||
|
||||
if ($this->isExpired($request, $results)) {
|
||||
Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->update($response);
|
||||
}
|
||||
|
||||
$results = Profile::query()
|
||||
->where('internal_username', $username)
|
||||
->get();
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
$response = (new ExternalLinksResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
* @throws \Jikan\Exception\BadResponseException
|
||||
* @throws \Jikan\Exception\ParserException
|
||||
*/
|
||||
public function recentlyOnline(Request $request)
|
||||
public function recentlyOnline(QueryRecentlyOnlineUsersCommand $command)
|
||||
{
|
||||
$results = DB::table($this->getRouteTable($request))
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$data = ['results'=>$this->jikan->getRecentOnlineUsers(new RecentlyOnlineUsersRequest())];
|
||||
$response = \json_decode($this->serializer->serialize($data, 'json'), true);
|
||||
|
||||
$results = $this->updateCache($request, $results, $response);
|
||||
}
|
||||
|
||||
$response = (new ResultsResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $status
|
||||
* @return int
|
||||
*/
|
||||
private function listStatusToId(?string $status) : int
|
||||
{
|
||||
if (is_null($status)) {
|
||||
return 7;
|
||||
}
|
||||
|
||||
switch ($status) {
|
||||
case 'all':
|
||||
return 7;
|
||||
case 'watching':
|
||||
case 'reading':
|
||||
return 1;
|
||||
case 'completed':
|
||||
return 2;
|
||||
case 'onhold':
|
||||
return 3;
|
||||
case 'dropped':
|
||||
return 4;
|
||||
case 'plantowatch':
|
||||
case 'ptw':
|
||||
case 'plantoread':
|
||||
case 'ptr':
|
||||
return 6;
|
||||
default:
|
||||
return 7;
|
||||
}
|
||||
return $this->mediator->send($command);
|
||||
}
|
||||
}
|
||||
|
33
app/Http/Middleware/EndpointCacheTtlMiddleware.php
Normal file
33
app/Http/Middleware/EndpointCacheTtlMiddleware.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Http\HttpHelper;
|
||||
use App\Support\CacheOptions;
|
||||
use App\Support\JikanConfig;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Middleware which sets the cache ttl globally based on the endpoint's name
|
||||
*/
|
||||
final class EndpointCacheTtlMiddleware
|
||||
{
|
||||
// CacheOptions instance is singleton, so we set the ttl globally
|
||||
public function __construct(private readonly CacheOptions $cacheOptions,
|
||||
private readonly JikanConfig $jikanConfig)
|
||||
{
|
||||
}
|
||||
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$routeName = HttpHelper::getRouteName($request);
|
||||
$ttl = $this->jikanConfig->cacheTtlForEndpoint($routeName);
|
||||
$this->cacheOptions->setTtl($ttl);
|
||||
|
||||
$response = $next($request);
|
||||
|
||||
$this->cacheOptions->setTtl(null);
|
||||
return $response;
|
||||
}
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Macros;
|
||||
|
||||
use App\Concerns\ScraperCacheTtl;
|
||||
use App\Support\CachedData;
|
||||
use App\Support\CacheOptions;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
@ -12,8 +12,6 @@ use Illuminate\Support\Carbon;
|
||||
*/
|
||||
final class ResponseJikanCacheFlags
|
||||
{
|
||||
use ScraperCacheTtl;
|
||||
|
||||
public function __invoke(): \Closure
|
||||
{
|
||||
return function (string $cacheKey, CachedData $scraperResults) {
|
||||
@ -22,7 +20,7 @@ final class ResponseJikanCacheFlags
|
||||
*/
|
||||
return $this
|
||||
->header("X-Request-Fingerprint", $cacheKey)
|
||||
->setTtl(ResponseJikanCacheFlags::cacheTtl())
|
||||
->setTtl(app(CacheOptions::class)->ttl())
|
||||
->setExpires(Carbon::createFromTimestamp($scraperResults->expiry()))
|
||||
->setLastModified(Carbon::createFromTimestamp($scraperResults->lastModified()));
|
||||
};
|
||||
|
@ -15,22 +15,11 @@ use App\Contracts\Repository;
|
||||
use App\Contracts\RequestHandler;
|
||||
use App\Contracts\UnitOfWork;
|
||||
use App\Contracts\UserRepository;
|
||||
use App\GenreAnime;
|
||||
use App\GenreManga;
|
||||
use App\Http\QueryBuilder\AnimeSearchQueryBuilder;
|
||||
use App\Http\QueryBuilder\CharacterSearchQueryBuilder;
|
||||
use App\Http\QueryBuilder\ClubSearchQueryBuilder;
|
||||
use App\Http\QueryBuilder\PeopleSearchQueryBuilder;
|
||||
use App\Http\QueryBuilder\SimpleSearchQueryBuilder;
|
||||
use App\Http\QueryBuilder\MangaSearchQueryBuilder;
|
||||
use App\Http\QueryBuilder\TopAnimeQueryBuilder;
|
||||
use App\Http\QueryBuilder\TopMangaQueryBuilder;
|
||||
use App\Http\Middleware\EndpointCacheTtlMiddleware;
|
||||
use App\Macros\CollectionOffsetGetFirst;
|
||||
use App\Macros\ResponseJikanCacheFlags;
|
||||
use App\Macros\To2dArrayWithDottedKeys;
|
||||
use App\Magazine;
|
||||
use App\Mixins\ScoutBuilderMixin;
|
||||
use App\Producers;
|
||||
use App\Repositories\AnimeGenresRepository;
|
||||
use App\Repositories\DefaultAnimeRepository;
|
||||
use App\Repositories\DefaultCharacterRepository;
|
||||
@ -53,7 +42,9 @@ use App\Services\ScoutSearchService;
|
||||
use App\Services\SearchEngineSearchService;
|
||||
use App\Services\SearchService;
|
||||
use App\Services\TypeSenseScoutSearchService;
|
||||
use App\Support\CacheOptions;
|
||||
use App\Support\DefaultMediator;
|
||||
use App\Support\JikanConfig;
|
||||
use App\Support\JikanUnitOfWork;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@ -87,6 +78,9 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->singleton(JikanConfig::class, fn() => new JikanConfig(config("jikan")));
|
||||
// cache options class is used to share the request scope level cache settings
|
||||
$this->app->singleton(CacheOptions::class);
|
||||
$this->app->singleton(CachedScraperService::class, DefaultCachedScraperService::class);
|
||||
if ($this->getSearchIndexesEnabledConfig($this->app)) {
|
||||
$this->app->bind(QueryBuilderPaginatorService::class, ScoutBuilderPaginatorService::class);
|
||||
@ -268,7 +262,20 @@ class AppServiceProvider extends ServiceProvider
|
||||
Features\QueryMangaRecommendationsHandler::class => $unitOfWorkInstance->documents("recommendations"),
|
||||
Features\QueryAnimeReviewsHandler::class => $unitOfWorkInstance->documents("reviews"),
|
||||
Features\QueryMangaReviewsHandler::class => $unitOfWorkInstance->documents("reviews"),
|
||||
Features\QueryAnimeSeasonListHandler::class => $unitOfWorkInstance->documents("season_archive")
|
||||
Features\QueryAnimeSeasonListHandler::class => $unitOfWorkInstance->documents("season_archive"),
|
||||
Features\UserFullLookupHandler::class => $unitOfWorkInstance->users(),
|
||||
Features\UserProfileLookupHandler::class => $unitOfWorkInstance->users(),
|
||||
Features\UserStatisticsLookupHandler::class => $unitOfWorkInstance->users(),
|
||||
Features\UserFavoritesLookupHandler::class => $unitOfWorkInstance->users(),
|
||||
Features\UserUpdatesLookupHandler::class => $unitOfWorkInstance->users(),
|
||||
Features\UserAboutLookupHandler::class => $unitOfWorkInstance->users(),
|
||||
Features\UserHistoryLookupHandler::class => $unitOfWorkInstance->documents("users_history"),
|
||||
Features\UserFriendsLookupHandler::class => $unitOfWorkInstance->documents("users_friends"),
|
||||
Features\UserReviewsLookupHandler::class => $unitOfWorkInstance->documents("users_reviews"),
|
||||
Features\UserRecommendationsLookupHandler::class => $unitOfWorkInstance->documents("users_recommendations"),
|
||||
Features\UserClubsLookupHandler::class => $unitOfWorkInstance->documents("users_clubs"),
|
||||
Features\UserExternalLookupHandler::class => $unitOfWorkInstance->users(),
|
||||
Features\QueryRecentlyOnlineUsersHandler::class => $unitOfWorkInstance->documents("users_recently_online")
|
||||
];
|
||||
|
||||
foreach ($requestHandlersWithScraperService as $handlerClass => $repositoryInstance) {
|
||||
@ -347,15 +354,11 @@ class AppServiceProvider extends ServiceProvider
|
||||
|
||||
public static function servicesToWarm(): array
|
||||
{
|
||||
// todo: test again with roadrunner -- specific issue: typesense driver not loaded in time
|
||||
$services = [
|
||||
ScoutSearchService::class,
|
||||
AnimeSearchQueryBuilder::class,
|
||||
MangaSearchQueryBuilder::class,
|
||||
ClubSearchQueryBuilder::class,
|
||||
CharacterSearchQueryBuilder::class,
|
||||
PeopleSearchQueryBuilder::class,
|
||||
TopAnimeQueryBuilder::class,
|
||||
TopMangaQueryBuilder::class
|
||||
UnitOfWork::class,
|
||||
CachedScraperService::class
|
||||
];
|
||||
|
||||
if (Env::get("SCOUT_DRIVER") === "typesense") {
|
||||
@ -366,6 +369,12 @@ class AppServiceProvider extends ServiceProvider
|
||||
$services[] = \Elastic\Elasticsearch\Client::class;
|
||||
}
|
||||
|
||||
if (Env::get("SCOUT_DRIVER") !== "none" && Env::get("SCOUT_DRIVER")) {
|
||||
$services[] = ScoutBuilderPaginatorService::class;
|
||||
} else {
|
||||
$services[] = EloquentBuilderPaginatorService::class;
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,13 @@ namespace App\Repositories;
|
||||
use App\Character;
|
||||
use App\Contracts\CharacterRepository;
|
||||
use App\Contracts\Repository;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Contracts\Database\Query\Builder as EloquentBuilder;
|
||||
use Laravel\Scout\Builder as ScoutBuilder;
|
||||
|
||||
/**
|
||||
* @implements Repository<Character>
|
||||
*/
|
||||
class DefaultCharacterRepository extends DatabaseRepository implements CharacterRepository
|
||||
final class DefaultCharacterRepository extends DatabaseRepository implements CharacterRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ use App\Contracts\Repository;
|
||||
/**
|
||||
* @implements Repository<Club>
|
||||
*/
|
||||
class DefaultClubRepository extends DatabaseRepository implements ClubRepository
|
||||
final class DefaultClubRepository extends DatabaseRepository implements ClubRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ use App\Magazine;
|
||||
/**
|
||||
* @implements Repository<Magazine>
|
||||
*/
|
||||
class DefaultMagazineRepository extends DatabaseRepository implements MagazineRepository
|
||||
final class DefaultMagazineRepository extends DatabaseRepository implements MagazineRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ use App\Manga;
|
||||
use Illuminate\Contracts\Database\Query\Builder as EloquentBuilder;
|
||||
use Laravel\Scout\Builder as ScoutBuilder;
|
||||
|
||||
class DefaultMangaRepository extends DatabaseRepository implements MangaRepository
|
||||
final class DefaultMangaRepository extends DatabaseRepository implements MangaRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -5,7 +5,7 @@ namespace App\Repositories;
|
||||
use App\Contracts\PeopleRepository;
|
||||
use App\Contracts\Repository;
|
||||
use App\Person;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Contracts\Database\Query\Builder as EloquentBuilder;
|
||||
use Laravel\Scout\Builder as ScoutBuilder;
|
||||
|
||||
/**
|
||||
|
@ -9,7 +9,7 @@ use App\Producers;
|
||||
/**
|
||||
* @implements Repository<Producers>
|
||||
*/
|
||||
class DefaultProducerRepository extends DatabaseRepository implements ProducerRepository
|
||||
final class DefaultProducerRepository extends DatabaseRepository implements ProducerRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ use App\Profile;
|
||||
/**
|
||||
* @implements Repository<Profile>
|
||||
*/
|
||||
class DefaultUserRepository extends DatabaseRepository implements UserRepository
|
||||
final class DefaultUserRepository extends DatabaseRepository implements UserRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Concerns\ScraperCacheTtl;
|
||||
use App\Contracts\CachedScraperService;
|
||||
use App\Contracts\Repository;
|
||||
use App\Http\HttpHelper;
|
||||
@ -19,8 +18,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
*/
|
||||
final class DefaultCachedScraperService implements CachedScraperService
|
||||
{
|
||||
use ScraperCacheTtl;
|
||||
|
||||
public function __construct(
|
||||
private readonly Repository $repository,
|
||||
private readonly MalClient $jikan,
|
||||
@ -133,7 +130,7 @@ final class DefaultCachedScraperService implements CachedScraperService
|
||||
$this->repository->queryByMalId($id)->update($response->toArray());
|
||||
}
|
||||
|
||||
return new CachedData(collect($this->repository->getAllByMalId($id)));
|
||||
return CachedData::from(collect($this->repository->getAllByMalId($id)));
|
||||
}
|
||||
|
||||
private function updateCacheByKey(string $cacheKey, CachedData $results, array $scraperResponse): CachedData
|
||||
@ -149,7 +146,7 @@ final class DefaultCachedScraperService implements CachedScraperService
|
||||
$this->getQueryableByCacheKey($cacheKey)->update($response->toArray());
|
||||
}
|
||||
|
||||
return new CachedData($this->getByCacheKey($cacheKey));
|
||||
return CachedData::from($this->getByCacheKey($cacheKey));
|
||||
}
|
||||
|
||||
private function prepareScraperResponse(string $cacheKey, bool $resultsEmpty, array $scraperResponse): CachedData
|
||||
@ -166,7 +163,7 @@ final class DefaultCachedScraperService implements CachedScraperService
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
// join meta data with response
|
||||
return new CachedData(collect($meta + $scraperResponse));
|
||||
return CachedData::from(collect($meta + $scraperResponse));
|
||||
}
|
||||
|
||||
private function getByCacheKey(string $cacheKey): Collection
|
||||
@ -179,7 +176,7 @@ final class DefaultCachedScraperService implements CachedScraperService
|
||||
return $this->repository->where("request_hash", $cacheKey);
|
||||
}
|
||||
|
||||
private function serializeScraperResult(array $data): array
|
||||
private function serializeScraperResult(mixed $data): array
|
||||
{
|
||||
return $this->serializer->toArray($data);
|
||||
}
|
||||
|
22
app/Support/CacheOptions.php
Normal file
22
app/Support/CacheOptions.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Support;
|
||||
|
||||
final class CacheOptions
|
||||
{
|
||||
private ?int $ttl = null;
|
||||
|
||||
public function __construct(private readonly JikanConfig $jikanConfig)
|
||||
{
|
||||
}
|
||||
|
||||
public function ttl(): int
|
||||
{
|
||||
return $this->ttl ?? $this->jikanConfig->defaultCacheExpire();
|
||||
}
|
||||
|
||||
public function setTtl(?int $ttl): void
|
||||
{
|
||||
$this->ttl = $ttl;
|
||||
}
|
||||
}
|
@ -5,20 +5,23 @@ namespace App\Support;
|
||||
use App\Concerns\ScraperCacheTtl;
|
||||
use App\JikanApiModel;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Env;
|
||||
|
||||
final class CachedData
|
||||
{
|
||||
use ScraperCacheTtl;
|
||||
private int $cacheTimeToLive;
|
||||
|
||||
public function __construct(
|
||||
private readonly Collection $scraperResult
|
||||
private function __construct(
|
||||
private readonly Collection $scraperResult,
|
||||
int $cacheTtl
|
||||
)
|
||||
{
|
||||
$this->cacheTimeToLive = $cacheTtl;
|
||||
}
|
||||
|
||||
public static function from(Collection $scraperResult): self
|
||||
{
|
||||
return new self($scraperResult);
|
||||
return new self($scraperResult, app(CacheOptions::class)->ttl());
|
||||
}
|
||||
|
||||
public function collect(): Collection
|
||||
@ -62,10 +65,15 @@ final class CachedData
|
||||
public function expiry(): int
|
||||
{
|
||||
$modifiedAt = $this->lastModified();
|
||||
$ttl = $this->cacheTtl();
|
||||
$ttl = $this->cacheTimeToLive;
|
||||
return $modifiedAt !== null ? $ttl + $modifiedAt : $ttl;
|
||||
}
|
||||
|
||||
public function cacheTtl(): int
|
||||
{
|
||||
return $this->cacheTimeToLive;
|
||||
}
|
||||
|
||||
public function lastModified(): ?int
|
||||
{
|
||||
if ($this->scraperResult->isEmpty()) {
|
||||
|
35
app/Support/JikanConfig.php
Normal file
35
app/Support/JikanConfig.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Support;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Jikan behavior config
|
||||
*/
|
||||
final class JikanConfig
|
||||
{
|
||||
/**
|
||||
* @var array<string, int> $perEndpointCacheTtl
|
||||
*/
|
||||
private array $perEndpointCacheTtl;
|
||||
|
||||
private int $defaultCacheExpire;
|
||||
|
||||
public function __construct(array $config)
|
||||
{
|
||||
$config = collect($config);
|
||||
$this->perEndpointCacheTtl = $config->get("per_endpoint_cache_ttl", []);
|
||||
$this->defaultCacheExpire = $config->get("default_cache_expire", 0);
|
||||
}
|
||||
|
||||
public function cacheTtlForEndpoint(string $endpoint): ?int
|
||||
{
|
||||
return collect($this->perEndpointCacheTtl)->get($endpoint);
|
||||
}
|
||||
|
||||
public function defaultCacheExpire(): int
|
||||
{
|
||||
return $this->defaultCacheExpire;
|
||||
}
|
||||
}
|
@ -6,8 +6,8 @@ use Illuminate\Contracts\Database\Query\Builder;
|
||||
|
||||
class RepositoryQueryBase
|
||||
{
|
||||
private ?Builder $queryableBuilder;
|
||||
private ?ScoutBuilder $searchableBuilder;
|
||||
private ?Builder $queryableBuilder = null;
|
||||
private ?ScoutBuilder $searchableBuilder = null;
|
||||
|
||||
public function __construct(
|
||||
private readonly \Closure $getQueryable,
|
||||
|
@ -41,7 +41,6 @@ $app->instance('path.config', app()->basePath() . DIRECTORY_SEPARATOR . 'config'
|
||||
$app->instance('path.storage', app()->basePath() . DIRECTORY_SEPARATOR . 'storage');
|
||||
|
||||
$app->withEloquent();
|
||||
|
||||
$app->configure('swagger-lume');
|
||||
$app->configure('scout');
|
||||
|
||||
@ -88,6 +87,7 @@ $app->middleware($globalMiddleware);
|
||||
$app->routeMiddleware([
|
||||
'microcaching' => \App\Http\Middleware\MicroCaching::class,
|
||||
'source-health-monitor' => SourceHeartbeatMonitor::class,
|
||||
'cache-ttl' => \App\Http\Middleware\EndpointCacheTtlMiddleware::class
|
||||
]);
|
||||
|
||||
/*
|
||||
@ -109,6 +109,7 @@ $app->configure('controller-to-table-mapping');
|
||||
$app->configure('controller');
|
||||
$app->configure('roadrunner');
|
||||
$app->configure('data');
|
||||
$app->configure('jikan');
|
||||
|
||||
$app->register(\pushrbx\LumenRoadRunner\ServiceProvider::class);
|
||||
$app->register(\SwaggerLume\ServiceProvider::class);
|
||||
@ -169,6 +170,7 @@ if (env("SCOUT_DRIVER") === "Matchish\ScoutElasticSearch\Engines\ElasticSearchEn
|
||||
$commonMiddleware = [
|
||||
'source-health-monitor',
|
||||
'microcaching',
|
||||
'cache-ttl'
|
||||
];
|
||||
|
||||
|
||||
|
143
config/jikan.php
Normal file
143
config/jikan.php
Normal file
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'default_cache_expire' => env('CACHE_DEFAULT_EXPIRE', 86400),
|
||||
'per_endpoint_cache_ttl' => [
|
||||
/**
|
||||
* Anime
|
||||
*/
|
||||
'AnimeController@main' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@characters_staff' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@characters' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@staff' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@episodes' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@episode' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@news' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@forum' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@videos' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@videosEpisodes' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@pictures' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@stats' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@moreInfo' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@recommendations' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@userupdates' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'AnimeController@reviews' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
/**
|
||||
* Manga
|
||||
*/
|
||||
'MangaController@main' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'MangaController@characters' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'MangaController@news' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'MangaController@forum' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'MangaController@pictures' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'MangaController@stats' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'MangaController@moreInfo' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'MangaController@recommendations' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'MangaController@userupdates' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'MangaController@reviews' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
/**
|
||||
* Characters
|
||||
*/
|
||||
'CharacterController@main' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'CharacterController@anime' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'CharacterController@manga' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'CharacterController@voices' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'CharacterController@pictures' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
/**
|
||||
* Person
|
||||
*/
|
||||
'PersonController@main' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'PersonController@anime' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'PersonController@manga' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'PersonController@seiyuu' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'PersonController@pictures' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
/**
|
||||
* Season
|
||||
*/
|
||||
'SeasonController@archive' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'SeasonController@later' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'SeasonController@main' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
/**
|
||||
* Schedule
|
||||
*/
|
||||
'ScheduleController@main' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
/**
|
||||
* Producers
|
||||
*/
|
||||
'ProducerController@main' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
/**
|
||||
* Magazines
|
||||
*/
|
||||
'MagazineController@main' => env('CACHE_MAGAZINE_EXPIRE'),
|
||||
'MagazineController@resource' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
/**
|
||||
* Users
|
||||
*/
|
||||
'UserController@recentlyOnline' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'UserController@profile' => env('CACHE_USER_EXPIRE'),
|
||||
'UserController@statistics' => env('CACHE_USER_EXPIRE'),
|
||||
'UserController@favorites' => env('CACHE_USER_EXPIRE'),
|
||||
'UserController@about' => env('CACHE_USER_EXPIRE'),
|
||||
'UserController@history' => env('CACHE_USER_EXPIRE'),
|
||||
'UserController@friends' => env('CACHE_USER_EXPIRE'),
|
||||
'UserController@recommendations' => env('CACHE_USER_EXPIRE'),
|
||||
'UserController@reviews' => env('CACHE_USER_EXPIRE'),
|
||||
'UserController@clubs' => env('CACHE_USER_EXPIRE'),
|
||||
|
||||
/**
|
||||
* User Lists
|
||||
*/
|
||||
'UserController@animelist' => env('CACHE_USERLIST_EXPIRE'),
|
||||
'UserController@mangalist' => env('CACHE_USERLIST_EXPIRE'),
|
||||
|
||||
/**
|
||||
* Genre
|
||||
*/
|
||||
'GenreController@mainAnime' => env('CACHE_GENRE_EXPIRE'),
|
||||
'GenreController@mainManga' => env('CACHE_GENRE_EXPIRE'),
|
||||
'GenreController@anime' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'GenreController@manga' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
/**
|
||||
* Top
|
||||
*/
|
||||
'TopController@anime' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'TopController@manga' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'TopController@characters' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'TopController@people' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'TopController@reviews' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
/**
|
||||
* Search
|
||||
*/
|
||||
'SearchController@anime' => env('CACHE_SEARCH_EXPIRE'),
|
||||
'SearchController@manga' => env('CACHE_SEARCH_EXPIRE'),
|
||||
'SearchController@character' => env('CACHE_SEARCH_EXPIRE'),
|
||||
'SearchController@people' => env('CACHE_SEARCH_EXPIRE'),
|
||||
'SearchController@users' => env('CACHE_SEARCH_EXPIRE'),
|
||||
'SearchController@userById' => env('CACHE_SEARCH_EXPIRE'),
|
||||
'SearchController@producers' => env('CACHE_SEARCH_EXPIRE'),
|
||||
|
||||
'ClubController@main' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'ClubController@members' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
'ReviewsController@anime' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'ReviewsController@manga' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
'RecommendationsController@anime' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'RecommendationsController@manga' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
|
||||
'WatchController@recentEpisodes' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'WatchController@popularEpisodes' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'WatchController@recentPromos' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
'WatchController@popularPromos' => env('CACHE_DEFAULT_EXPIRE'),
|
||||
]
|
||||
];
|
@ -15,7 +15,7 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media
|
||||
{
|
||||
use JikanDataGenerator;
|
||||
|
||||
protected ?MediaModelFactoryDescriptor $descriptor;
|
||||
protected ?MediaModelFactoryDescriptor $descriptor = null;
|
||||
|
||||
public function __construct(
|
||||
MediaModelFactoryDescriptor $descriptor,
|
||||
|
Loading…
x
Reference in New Issue
Block a user