refactoring and code cleanup

This commit is contained in:
pushrbx 2023-04-28 18:45:59 +01:00
parent a637e697e1
commit 6732de1188
9 changed files with 41 additions and 100 deletions

View File

@ -21,11 +21,11 @@ interface AnimeRepository extends Repository
public function exceptItemsWithAdultRating(): EloquentBuilder|ScoutBuilder; public function exceptItemsWithAdultRating(): EloquentBuilder|ScoutBuilder;
public function excludeKidsItems(&$builder): Collection|EloquentBuilder|ScoutBuilder; public function excludeKidsItems($builder): Collection|EloquentBuilder|ScoutBuilder;
public function excludeNsfwItems(&$builder): Collection|EloquentBuilder|ScoutBuilder; public function excludeNsfwItems($builder): Collection|EloquentBuilder|ScoutBuilder;
public function excludeUnapprovedItems(&$builder): Collection|EloquentBuilder|ScoutBuilder; public function excludeUnapprovedItems($builder): Collection|EloquentBuilder|ScoutBuilder;
public function orderByPopularity(): EloquentBuilder|ScoutBuilder; public function orderByPopularity(): EloquentBuilder|ScoutBuilder;
@ -34,19 +34,13 @@ interface AnimeRepository extends Repository
public function orderByRank(): EloquentBuilder|ScoutBuilder; public function orderByRank(): EloquentBuilder|ScoutBuilder;
public function getCurrentlyAiring( public function getCurrentlyAiring(
?AnimeScheduleFilterEnum $filter = null, ?AnimeScheduleFilterEnum $filter = null
bool $kids = false,
bool $sfw = false,
?bool $unapproved = false
): EloquentBuilder; ): EloquentBuilder;
public function getAiredBetween( public function getAiredBetween(
Carbon $from, Carbon $from,
Carbon $to, Carbon $to,
?AnimeTypeEnum $type = null, ?AnimeTypeEnum $type = null
?bool $kids = false,
?bool $sfw = false,
?bool $unapproved = false
): EloquentBuilder; ): EloquentBuilder;
public function getUpcomingSeasonItems(?AnimeTypeEnum $type = null): EloquentBuilder; public function getUpcomingSeasonItems(?AnimeTypeEnum $type = null): EloquentBuilder;

View File

@ -2,7 +2,6 @@
namespace App\Dto; namespace App\Dto;
use App\Casts\ContextualBooleanCast;
use App\Contracts\DataRequest; use App\Contracts\DataRequest;
use App\Dto\Concerns\HasSfwParameter; use App\Dto\Concerns\HasSfwParameter;
use App\Enums\AnimeOrderByEnum; use App\Enums\AnimeOrderByEnum;
@ -13,7 +12,6 @@ use App\Http\Resources\V4\AnimeCollection;
use App\Rules\Attributes\EnumValidation; use App\Rules\Attributes\EnumValidation;
use Spatie\LaravelData\Attributes\MapInputName; use Spatie\LaravelData\Attributes\MapInputName;
use Spatie\LaravelData\Attributes\MapOutputName; use Spatie\LaravelData\Attributes\MapOutputName;
use Spatie\LaravelData\Attributes\Validation\BooleanType;
use Spatie\LaravelData\Attributes\Validation\IntegerType; use Spatie\LaravelData\Attributes\Validation\IntegerType;
use Spatie\LaravelData\Attributes\Validation\Min; use Spatie\LaravelData\Attributes\Validation\Min;
use Spatie\LaravelData\Attributes\Validation\Prohibits; use Spatie\LaravelData\Attributes\Validation\Prohibits;

View File

@ -2,6 +2,7 @@
namespace App\Features; namespace App\Features;
use App\Contracts\AnimeRepository;
use App\Contracts\RequestHandler; use App\Contracts\RequestHandler;
use App\Dto\QueryAnimeSeasonCommand; use App\Dto\QueryAnimeSeasonCommand;
use App\Enums\AnimeSeasonEnum; use App\Enums\AnimeSeasonEnum;
@ -19,14 +20,36 @@ use Symfony\Component\HttpFoundation\Exception\BadRequestException;
*/ */
abstract class QueryAnimeSeasonHandlerBase implements RequestHandler abstract class QueryAnimeSeasonHandlerBase implements RequestHandler
{ {
public function __construct(protected readonly AnimeRepository $repository)
{
}
/** /**
* @param QueryAnimeSeasonCommand $request * @param QueryAnimeSeasonCommand $request
* @return JsonResponse * @return JsonResponse
*/ */
public function handle($request): JsonResponse public function handle($request): JsonResponse
{ {
$type = collect($request->all())->has("filter") ? $request->filter : null; $requestParams = collect($request->all());
$results = $this->getSeasonItems($request, $type, $request->kids, $request->sfw); $type = $requestParams->has("filter") ? $request->filter : null;
$results = $this->getSeasonItems($request, $type);
$includeUnapproved = $requestParams->get("unapproved", false);
$includeKids = $requestParams->get("kids", false);
$shouldBeSfw = $requestParams->get("sfw", false);
if (!$includeUnapproved) {
$results = $this->repository->excludeUnapprovedItems($results);
}
if (!$includeKids) {
$results = $this->repository->excludeKidsItems($results);
}
if ($shouldBeSfw) {
$results = $this->repository->excludeNsfwItems($results);
}
$results = $results->paginate($request->limit, ["*"], null, $request->page); $results = $results->paginate($request->limit, ["*"], null, $request->page);
$animeCollection = new AnimeCollection($results); $animeCollection = new AnimeCollection($results);

View File

@ -17,10 +17,6 @@ use Illuminate\Support\Carbon;
*/ */
final class QueryCurrentAnimeSeasonHandler extends QueryAnimeSeasonHandlerBase final class QueryCurrentAnimeSeasonHandler extends QueryAnimeSeasonHandlerBase
{ {
public function __construct(private readonly AnimeRepository $repository)
{
}
public function requestClass(): string public function requestClass(): string
{ {
return QueryCurrentAnimeSeasonCommand::class; return QueryCurrentAnimeSeasonCommand::class;

View File

@ -2,8 +2,8 @@
namespace App\Features; namespace App\Features;
use App\Contracts\AnimeRepository;
use App\Dto\QuerySpecificAnimeSeasonCommand; use App\Dto\QuerySpecificAnimeSeasonCommand;
use App\Enums\AnimeStatusEnum;
use App\Enums\AnimeTypeEnum; use App\Enums\AnimeTypeEnum;
use Illuminate\Contracts\Database\Query\Builder; use Illuminate\Contracts\Database\Query\Builder;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
@ -13,10 +13,6 @@ use Illuminate\Support\Carbon;
*/ */
final class QuerySpecificAnimeSeasonHandler extends QueryAnimeSeasonHandlerBase final class QuerySpecificAnimeSeasonHandler extends QueryAnimeSeasonHandlerBase
{ {
public function __construct(private readonly AnimeRepository $repository)
{
}
public function requestClass(): string public function requestClass(): string
{ {
return QuerySpecificAnimeSeasonCommand::class; return QuerySpecificAnimeSeasonCommand::class;
@ -30,6 +26,7 @@ final class QuerySpecificAnimeSeasonHandler extends QueryAnimeSeasonHandlerBase
*/ */
[$from, $to] = $this->getSeasonRange($request->year, $request->season); [$from, $to] = $this->getSeasonRange($request->year, $request->season);
return $this->repository->getAiredBetween($from, $to, $type, $request->kids, $request->sfw, $request->unapproved); return $this->repository->getAiredBetween($from, $to, $type)
->where("status", "!=", AnimeStatusEnum::upcoming()->label);
} }
} }

View File

@ -2,7 +2,6 @@
namespace App\Features; namespace App\Features;
use App\Contracts\AnimeRepository;
use App\Dto\QueryUpcomingAnimeSeasonCommand; use App\Dto\QueryUpcomingAnimeSeasonCommand;
use App\Enums\AnimeTypeEnum; use App\Enums\AnimeTypeEnum;
use Illuminate\Contracts\Database\Query\Builder; use Illuminate\Contracts\Database\Query\Builder;
@ -12,10 +11,6 @@ use Illuminate\Contracts\Database\Query\Builder;
*/ */
final class QueryUpcomingAnimeSeasonHandler extends QueryAnimeSeasonHandlerBase final class QueryUpcomingAnimeSeasonHandler extends QueryAnimeSeasonHandlerBase
{ {
public function __construct(private readonly AnimeRepository $repository)
{
}
public function requestClass(): string public function requestClass(): string
{ {
return QueryUpcomingAnimeSeasonCommand::class; return QueryUpcomingAnimeSeasonCommand::class;

View File

@ -52,20 +52,20 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe
return $builder; return $builder;
} }
public function excludeNsfwItems(&$builder): EloquentBuilder|ScoutBuilder public function excludeNsfwItems($builder): EloquentBuilder|ScoutBuilder
{ {
return $builder return $builder
->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_HENTAI) ->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_HENTAI)
->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_EROTICA); ->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_EROTICA);
} }
public function excludeUnapprovedItems(&$builder): Collection|EloquentBuilder|ScoutBuilder public function excludeUnapprovedItems($builder): Collection|EloquentBuilder|ScoutBuilder
{ {
return $builder return $builder
->where("approved", true); ->where("approved", true);
} }
public function excludeKidsItems(&$builder): EloquentBuilder|ScoutBuilder public function excludeKidsItems($builder): EloquentBuilder|ScoutBuilder
{ {
return $builder return $builder
->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_KIDS); ->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_KIDS);
@ -90,10 +90,7 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe
} }
public function getCurrentlyAiring( public function getCurrentlyAiring(
?AnimeScheduleFilterEnum $filter = null, ?AnimeScheduleFilterEnum $filter = null
?bool $kids = false,
?bool $sfw = false,
?bool $unapproved = false
): EloquentBuilder ): EloquentBuilder
{ {
/* /*
@ -106,18 +103,6 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe
->where("type", AnimeTypeEnum::tv()->label) ->where("type", AnimeTypeEnum::tv()->label)
->where("status", AnimeStatusEnum::airing()->label); ->where("status", AnimeStatusEnum::airing()->label);
if (!$unapproved) {
$this->excludeUnapprovedItems($queryable);
}
if (!$kids) {
$this->excludeKidsItems($queryable);
}
if ($sfw) {
$this->excludeNsfwItems($queryable);
}
if (!is_null($filter)) { if (!is_null($filter)) {
if ($filter->isWeekDay()) { if ($filter->isWeekDay()) {
$queryable = $queryable->where("broadcast", "like", "{$filter->label}%"); $queryable = $queryable->where("broadcast", "like", "{$filter->label}%");
@ -133,10 +118,7 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe
public function getAiredBetween( public function getAiredBetween(
Carbon $from, Carbon $from,
Carbon $to, Carbon $to,
?AnimeTypeEnum $type = null, ?AnimeTypeEnum $type = null
?bool $kids = false,
?bool $sfw = false,
?bool $unapproved = false
): EloquentBuilder ): EloquentBuilder
{ {
$queryable = $this->queryable(true)->whereBetween("aired.from", [ $queryable = $this->queryable(true)->whereBetween("aired.from", [
@ -148,26 +130,11 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe
$queryable = $queryable->where("type", $type->label); $queryable = $queryable->where("type", $type->label);
} }
if (!$unapproved) {
$this->excludeUnapprovedItems($queryable);
}
if (!$kids) {
$this->excludeKidsItems($queryable);
}
if ($sfw) {
$this->excludeNsfwItems($queryable);
}
return $queryable->orderBy("members", "desc"); return $queryable->orderBy("members", "desc");
} }
public function getUpcomingSeasonItems( public function getUpcomingSeasonItems(
?AnimeTypeEnum $type = null, ?AnimeTypeEnum $type = null
?bool $kids = false,
?bool $sfw = false,
?bool $unapproved = false
): EloquentBuilder ): EloquentBuilder
{ {
$queryable = $this->queryable(true)->where("status", AnimeStatusEnum::upcoming()->label); $queryable = $this->queryable(true)->where("status", AnimeStatusEnum::upcoming()->label);
@ -176,18 +143,6 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe
$queryable = $queryable->where("type", $type->label); $queryable = $queryable->where("type", $type->label);
} }
if (!$unapproved) {
$this->excludeUnapprovedItems($queryable);
}
if (!$kids) {
$this->excludeKidsItems($queryable);
}
if ($sfw) {
$this->excludeNsfwItems($queryable);
}
return $queryable->orderBy("members", "desc"); return $queryable->orderBy("members", "desc");
} }
} }

View File

@ -55,17 +55,4 @@ final class DefaultMangaRepository extends DatabaseRepository implements MangaRe
->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_HENTAI) ->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_HENTAI)
->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_EROTICA); ->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_EROTICA);
} }
public function excludeNsfwItems(&$builder): EloquentBuilder|ScoutBuilder
{
return $builder
->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_HENTAI)
->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_EROTICA);
}
public function excludeUnapprovedItems(&$builder): Collection|EloquentBuilder|ScoutBuilder
{
return $builder
->where("approved", true);
}
} }

View File

@ -34,7 +34,7 @@ class TypeSenseScoutSearchService implements ScoutSearchService
// which will make Typesense consider all variations of prefixes and typo corrections of the words // which will make Typesense consider all variations of prefixes and typo corrections of the words
// in the query exhaustively, without stopping early when enough results are found. // in the query exhaustively, without stopping early when enough results are found.
$options['exhaustive_search'] = env('TYPESENSE_SEARCH_EXHAUSTIVE', "true"); $options['exhaustive_search'] = env('TYPESENSE_SEARCH_EXHAUSTIVE', "true");
$options['search_cutoff_ms'] = (int) env('TYPESENSE_SEARCH_EXHAUSTIVE', 450); $options['search_cutoff_ms'] = (int) env('TYPESENSE_SEARCH_CUTOFF_MS', 450);
if (array_key_exists('per_page', $options) && $options['per_page'] > 250) { if (array_key_exists('per_page', $options) && $options['per_page'] > 250) {
$options['per_page'] = min($this->maxItemsPerPage, 250); $options['per_page'] = min($this->maxItemsPerPage, 250);
@ -49,6 +49,7 @@ class TypeSenseScoutSearchService implements ScoutSearchService
} }
// if the model specifies search index sort order, use it // if the model specifies search index sort order, use it
// this is the default sort order for the model
$sortByFields = $modelInstance->getSearchIndexSortBy(); $sortByFields = $modelInstance->getSearchIndexSortBy();
if (!is_null($sortByFields)) { if (!is_null($sortByFields)) {
$sortBy = ""; $sortBy = "";
@ -62,11 +63,6 @@ class TypeSenseScoutSearchService implements ScoutSearchService
// override ordering field // override ordering field
if (!is_null($orderByField)) { if (!is_null($orderByField)) {
$options['sort_by'] = "_text_match:desc,$orderByField:" . ($sortDirectionDescending ? "desc" : "asc");
}
// if order_by is a user supplied value make it a priority over _text_match
if ($orderByField !== 'members' && !is_null($orderByField)) {
$options['sort_by'] = "$orderByField:" . ($sortDirectionDescending ? "desc" : "asc") . ",_text_match:desc"; $options['sort_by'] = "$orderByField:" . ($sortDirectionDescending ? "desc" : "asc") . ",_text_match:desc";
} }