diff --git a/app/Anime.php b/app/Anime.php index 54d53e3c..a7c39c6e 100644 --- a/app/Anime.php +++ b/app/Anime.php @@ -15,6 +15,7 @@ use Jikan\Jikan; use Jikan\Request\Anime\AnimeRequest; use Illuminate\Database\Eloquent\Factories\HasFactory; +use MongoDB\Model\BSONDocument; class Anime extends JikanApiSearchableModel { @@ -407,7 +408,7 @@ public function getSearchIndexSortBy(): array|null ]; } - private function adaptBroadcastValue(array|string|null $broadcast): array + private function adaptBroadcastValue(array|string|null|BSONDocument $broadcast): array { $null_value = [ 'day' => null, @@ -423,6 +424,10 @@ private function adaptBroadcastValue(array|string|null $broadcast): array return $broadcast; } + if ($broadcast instanceof BSONDocument) { + return $broadcast->getArrayCopy(); + } + if (!preg_match('~(.*) at (.*) \(~', $broadcast, $matches)) { return [ 'day' => null, diff --git a/app/Features/QueryRandomAnimeHandler.php b/app/Features/QueryRandomAnimeHandler.php index e635ed6d..1ad4abbc 100644 --- a/app/Features/QueryRandomAnimeHandler.php +++ b/app/Features/QueryRandomAnimeHandler.php @@ -6,6 +6,7 @@ use App\Contracts\RequestHandler; use App\Dto\QueryRandomAnimeCommand; use App\Http\Resources\V4\AnimeResource; +use Spatie\LaravelData\Optional; /** * @implements RequestHandler @@ -18,12 +19,13 @@ final class QueryRandomAnimeHandler implements RequestHandler public function handle($request): AnimeResource { $queryable = Anime::query(); - // apply sfw, kids and unapproved filters - /** @noinspection PhpUndefinedMethodInspection */ - $queryable = $queryable->filter(collect($request->all())); + + $o = Optional::create(); + $sfwParam = $request->sfw === $o ? false : $request->sfw; + $unapprovedParam = $request->unapproved === $o ? false : $request->unapproved; return new AnimeResource( - $queryable->random()->first() + $queryable->random(1, $sfwParam, $unapprovedParam)->first() ); } diff --git a/app/Features/QueryRandomMangaHandler.php b/app/Features/QueryRandomMangaHandler.php index 56f58325..f4864575 100644 --- a/app/Features/QueryRandomMangaHandler.php +++ b/app/Features/QueryRandomMangaHandler.php @@ -6,6 +6,7 @@ use App\Dto\QueryRandomMangaCommand; use App\Http\Resources\V4\MangaResource; use App\Manga; +use Spatie\LaravelData\Optional; /** * @implements RequestHandler @@ -18,12 +19,13 @@ final class QueryRandomMangaHandler implements RequestHandler public function handle($request) { $queryable = Manga::query(); - // apply sfw, kids and unapproved filters - /** @noinspection PhpUndefinedMethodInspection */ - $queryable = $queryable->filter(collect($request->all())); + + $o = Optional::create(); + $sfwParam = $request->sfw === $o ? false : $request->sfw; + $unapprovedParam = $request->unapproved === $o ? false : $request->unapproved; return new MangaResource( - $queryable->random()->first() + $queryable->random(1, $sfwParam, $unapprovedParam)->first() ); } diff --git a/app/JikanApiModel.php b/app/JikanApiModel.php index 9ae0f561..afaf5e16 100644 --- a/app/JikanApiModel.php +++ b/app/JikanApiModel.php @@ -2,9 +2,12 @@ namespace App; +use App\Enums\AnimeRatingEnum; +use App\Enums\MangaTypeEnum; use App\Filters\FilterQueryString; use Illuminate\Support\Collection; use Jenssegers\Mongodb\Eloquent\Builder; +use Jikan\Helper\Constants; class JikanApiModel extends \Jenssegers\Mongodb\Eloquent\Model { @@ -19,10 +22,44 @@ class JikanApiModel extends \Jenssegers\Mongodb\Eloquent\Model protected array $filters = []; /** @noinspection PhpUnused */ - public function scopeRandom(Builder $query, int $numberOfRandomItems = 1): Collection + public function scopeRandom(Builder $query, int $numberOfRandomItems = 1, bool $sfw = false, bool $unapproved = false): Collection { - return $query->raw(fn(\Jenssegers\Mongodb\Collection $collection) => $collection->aggregate([ - ['$sample' => ['size' => $numberOfRandomItems]] - ])); + return $query->raw(function(\Jenssegers\Mongodb\Collection $collection) use ($numberOfRandomItems, $sfw, $unapproved) { + $sfwFilter = [ + 'demographics.mal_id' => [ + '$nin' => [ + Constants::GENRE_ANIME_HENTAI, + Constants::GENRE_ANIME_EROTICA, + Constants::GENRE_MANGA_HENTAI, + Constants::GENRE_MANGA_EROTICA + ] + ], + 'rating' => ['$ne' => AnimeRatingEnum::rx()->label], + 'type' => ['$ne' => MangaTypeEnum::doujin()->label], + 'genres.mal_id' => ['$nin' => [ + Constants::GENRE_ANIME_HENTAI, + Constants::GENRE_MANGA_HENTAI + ]] + ]; + + $pipelineParams = [ + ['$sample' => ['size' => $numberOfRandomItems]] + ]; + + if ($sfw && $unapproved) { + array_unshift($pipelineParams, [ + '$match' => [ + ...$sfwFilter, + 'approved' => false + ] + ]); + } else if ($sfw) { + array_unshift($pipelineParams, ['$match' => $sfwFilter]); + } else if ($unapproved) { + array_unshift($pipelineParams, ['$match' => ['approved' => false]]); + } + + return $collection->aggregate($pipelineParams); + }); } }