diff --git a/.env.dist b/.env.dist index 9387f7a..9e0f57e 100644 --- a/.env.dist +++ b/.env.dist @@ -99,7 +99,6 @@ QUEUE_DELAY_PER_JOB=5 # Scout config ### # For TypeSense use: typesense -# For ElasticSearch use: Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine #SCOUT_DRIVER=typesense #SCOUT_QUEUE=false @@ -112,22 +111,6 @@ QUEUE_DELAY_PER_JOB=5 #TYPESENSE_SEARCH_EXHAUSTIVE=true #TYPESENSE_SEARCH_CUTTOFF_MS=450 -### -# ElasticSearch Config -### -# Host -- required -# ELASTICSEARCH_HOST=host:port -# you can use commas as sperator for additional nodes: -# ELASTICSEARCH_HOST=host:port,host:port -# username (optional) -# ELASTICSEARCH_USER=user -# password (optional) -# ELASTICSEARCH_PASSWORD=password -# api key (optional) -# ELASTICSEARCH_API_KEY=apikey -# cloud id (optional) -# ELASTICSEARCH_CLOUD_ID=cloudid - ### # GitHub generate report URL on fatal errors ### diff --git a/app/Anime.php b/app/Anime.php index addc00f..6e9dcb2 100644 --- a/app/Anime.php +++ b/app/Anime.php @@ -11,6 +11,7 @@ use Carbon\CarbonImmutable; use Database\Factories\AnimeFactory; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Log; +use Jikan\Helper\Constants; use Jikan\Jikan; use Jikan\Request\Anime\AnimeRequest; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -19,7 +20,10 @@ class Anime extends JikanApiSearchableModel { use HasFactory, MediaFilters, FilteredByLetter; - protected array $filters = ["order_by", "status", "type", "sort", "max_score", "min_score", "score", "rating", "start_date", "end_date", "producer", "producers", "letter", "genres", "genres_exclude"]; + protected array $filters = [ + "order_by", "status", "type", "sort", "max_score", "min_score", "score", "rating", "start_date", "end_date", + "producer", "producers", "letter", "genres", "genres_exclude", "sfw", "unapproved", "kids" + ]; /** * The attributes that are mass assignable. * @@ -191,6 +195,29 @@ class Anime extends JikanApiSearchableModel return $query; } + /** @noinspection PhpUnused */ + public function scopeExceptItemsWithAdultRating(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder + { + return $query + ->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_HENTAI) + ->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_EROTICA) + ->where("rating", "!=", AnimeRatingEnum::rx()->label); + } + + /** @noinspection PhpUnused */ + public function scopeExceptKidsItems(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder + { + return $query + ->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_KIDS); + } + + /** @noinspection PhpUnused */ + public function scopeOnlyKidsItems(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder + { + return $query + ->where("demographics.mal_id", Constants::GENRE_ANIME_KIDS); + } + public static function scrape(int $id) { $data = app('JikanParser')->getAnime(new AnimeRequest($id)); @@ -237,6 +264,7 @@ class Anime extends JikanApiSearchableModel 'synopsis' => $this->synopsis, 'season' => $this->season, 'year' => $this->year, + 'approved' => $this->approved ?? false, 'producers' => $this->getMalIdsOfField($this->producers), 'studios' => $this->getMalIdsOfField($this->studios), 'licensors' => $this->getMalIdsOfField($this->licensors), diff --git a/app/Concerns/MediaFilters.php b/app/Concerns/MediaFilters.php index 0236f23..f437440 100644 --- a/app/Concerns/MediaFilters.php +++ b/app/Concerns/MediaFilters.php @@ -45,10 +45,15 @@ trait MediaFilters foreach ($genres as $genreItem) { $genre = (int) $genreItem; - $query = $query->orWhere('genres.mal_id', $genre) - ->orWhere('demographics.mal_id', $genre) - ->orWhere('themes.mal_id', $genre) - ->orWhere('explicit_genres.mal_id', $genre); + // here we need a nested where clause + // this logically looks like: (genre = x OR demographic = x OR theme = x) + // so: (any other where clauses from before) AND (genre = x OR demographic = x OR theme = x) + $query = $query->where(function ($q) use ($genre) { + return $q->where('genres.mal_id', $genre) + ->orWhere('demographics.mal_id', $genre) + ->orWhere('themes.mal_id', $genre) + ->orWhere('explicit_genres.mal_id', $genre); + }); } return $query; @@ -72,4 +77,26 @@ trait MediaFilters return $query; } + + public function filterBySfw(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, bool $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder + { + // call scopeExceptItemsWithAdultRating method via $query->exceptItemsWithAdultRating() + /** @noinspection PhpUndefinedMethodInspection */ + return $value ? $query->exceptItemsWithAdultRating() : $query; + } + + public function filterByUnapproved(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, ?bool $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder + { + return !$value ? $query->where("approved", true) : $query; + } + + public function filterByKids(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, ?bool $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder + { + if (is_null($value)) { + return $query; + } + // call scopeOnlyKidsItems method via $query->onlyKidsItems() + /** @noinspection PhpUndefinedMethodInspection */ + return $value ? $query->onlyKidsItems() : $query->exceptKidsItems(); + } } diff --git a/app/Console/Commands/Indexer/AnimeScheduleIndexer.php b/app/Console/Commands/Indexer/AnimeScheduleIndexer.php index 4a5b4a0..7484cc7 100644 --- a/app/Console/Commands/Indexer/AnimeScheduleIndexer.php +++ b/app/Console/Commands/Indexer/AnimeScheduleIndexer.php @@ -37,12 +37,11 @@ class AnimeScheduleIndexer extends Command /** * Execute the console command. * - * @return mixed */ public function handle() { - echo "Note: AnimeScheduleIndexer makes sure anime currently airing are upto update so the schedules endpoint returns fresh information\n\n"; + echo "Note: AnimeScheduleIndexer makes sure anime currently airing are up to date so the schedules endpoint returns fresh information\n\n"; /** * Schedule @@ -80,10 +79,6 @@ class AnimeScheduleIndexer extends Command sleep(3); // prevent rate-limit echo "Updating {$i}/{$itemCount} \r"; - try { - } catch (\Exception $e) { - echo "[SKIPPED] Failed to fetch {$url}"; - } $i++; } diff --git a/app/Dto/AnimeSearchCommand.php b/app/Dto/AnimeSearchCommand.php index bdd9ad8..98b0d3e 100644 --- a/app/Dto/AnimeSearchCommand.php +++ b/app/Dto/AnimeSearchCommand.php @@ -25,8 +25,6 @@ use Spatie\LaravelData\Optional; */ final class AnimeSearchCommand extends MediaSearchCommand implements DataRequest { - use HasSfwParameter; - #[WithCast(EnumCast::class, AnimeStatusEnum::class), EnumValidation(AnimeStatusEnum::class)] public AnimeStatusEnum|Optional $status; diff --git a/app/Dto/Concerns/HasKidsParameter.php b/app/Dto/Concerns/HasKidsParameter.php index 1360152..8597a47 100644 --- a/app/Dto/Concerns/HasKidsParameter.php +++ b/app/Dto/Concerns/HasKidsParameter.php @@ -22,5 +22,5 @@ trait HasKidsParameter use PreparesData; #[BooleanType, WithCast(ContextualBooleanCast::class)] - public bool|Optional $kids = false; + public bool|Optional $kids; } diff --git a/app/Dto/MediaSearchCommand.php b/app/Dto/MediaSearchCommand.php index 4029b7b..b633600 100644 --- a/app/Dto/MediaSearchCommand.php +++ b/app/Dto/MediaSearchCommand.php @@ -3,6 +3,7 @@ namespace App\Dto; use App\Dto\Concerns\HasSfwParameter; +use App\Dto\Concerns\HasUnapprovedParameter; use Carbon\CarbonImmutable; use Illuminate\Validation\Validator; use Spatie\LaravelData\Attributes\MapInputName; @@ -23,7 +24,7 @@ use Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer; class MediaSearchCommand extends SearchCommand { - use HasSfwParameter; + use HasSfwParameter, HasUnapprovedParameter; #[MapInputName("min_score"), MapOutputName("min_score"), Between(0.00, 10.00), Numeric] public float|Optional $minScore; diff --git a/app/Dto/QueryAnimeSchedulesCommand.php b/app/Dto/QueryAnimeSchedulesCommand.php index b4ebc49..a52ab2b 100644 --- a/app/Dto/QueryAnimeSchedulesCommand.php +++ b/app/Dto/QueryAnimeSchedulesCommand.php @@ -2,8 +2,6 @@ namespace App\Dto; - -use App\Casts\ContextualBooleanCast; use App\Casts\EnumCast; use App\Concerns\HasRequestFingerprint; use App\Contracts\DataRequest; @@ -17,10 +15,8 @@ use App\Dto\Concerns\PreparesData; use App\Enums\AnimeScheduleFilterEnum; use App\Rules\Attributes\EnumValidation; use Illuminate\Http\JsonResponse; -use Spatie\LaravelData\Attributes\Validation\BooleanType; use Spatie\LaravelData\Attributes\WithCast; use Spatie\LaravelData\Data; -use Spatie\LaravelData\Optional; /** * @implements DataRequest diff --git a/app/Dto/QueryRandomMangaCommand.php b/app/Dto/QueryRandomMangaCommand.php index 730f187..e24b158 100644 --- a/app/Dto/QueryRandomMangaCommand.php +++ b/app/Dto/QueryRandomMangaCommand.php @@ -6,9 +6,7 @@ use App\Contracts\DataRequest; use App\Dto\Concerns\HasSfwParameter; use App\Dto\Concerns\HasUnapprovedParameter; use App\Http\Resources\V4\MangaResource; -use Spatie\LaravelData\Attributes\Validation\BooleanType; use Spatie\LaravelData\Data; -use Spatie\LaravelData\Optional; /** * @implements DataRequest diff --git a/app/Enums/MediaReviewsSortEnum.php b/app/Enums/MediaReviewsSortEnum.php index 1c185bd..f3e3ff5 100644 --- a/app/Enums/MediaReviewsSortEnum.php +++ b/app/Enums/MediaReviewsSortEnum.php @@ -17,7 +17,8 @@ final class MediaReviewsSortEnum extends Enum return [ "mostVoted" => Constants::REVIEWS_SORT_MOST_VOTED, "newest" => Constants::REVIEWS_SORT_NEWEST, - "oldest" => Constants::REVIEWS_SORT_OLDEST + "oldest" => Constants::REVIEWS_SORT_OLDEST, + "suggested" => "suggested", ]; } } diff --git a/app/Features/QueryAnimeSchedulesHandler.php b/app/Features/QueryAnimeSchedulesHandler.php index dbf31df..3363d02 100644 --- a/app/Features/QueryAnimeSchedulesHandler.php +++ b/app/Features/QueryAnimeSchedulesHandler.php @@ -23,8 +23,12 @@ final class QueryAnimeSchedulesHandler implements RequestHandler */ public function handle($request) { - $limit = intval($request->limit ?? Env::get("MAX_RESULTS_PER_PAGE", 25)); - $results = $this->repository->getCurrentlyAiring($request->dayFilter, $request->kids, $request->sfw, $request->unapproved); + $requestParams = collect($request->all()); + $limit = $requestParams->get("limit"); + $results = $this->repository->getCurrentlyAiring($request->dayFilter); + // apply sfw, kids and unapproved filters + /** @noinspection PhpUndefinedMethodInspection */ + $results = $results->filter($requestParams); $results = $results->paginate( $limit, ["*"], diff --git a/app/Features/QueryAnimeSeasonHandlerBase.php b/app/Features/QueryAnimeSeasonHandlerBase.php index 9f9a7dc..304f178 100644 --- a/app/Features/QueryAnimeSeasonHandlerBase.php +++ b/app/Features/QueryAnimeSeasonHandlerBase.php @@ -33,23 +33,9 @@ abstract class QueryAnimeSeasonHandlerBase implements RequestHandler $requestParams = collect($request->all()); $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); - } - + // apply sfw, kids and unapproved filters + /** @noinspection PhpUndefinedMethodInspection */ + $results = $results->filter($requestParams); $results = $results->paginate($request->limit, ["*"], null, $request->page); $animeCollection = new AnimeCollection($results); diff --git a/app/Features/QueryCurrentAnimeSeasonHandler.php b/app/Features/QueryCurrentAnimeSeasonHandler.php index d3f41b1..9235303 100644 --- a/app/Features/QueryCurrentAnimeSeasonHandler.php +++ b/app/Features/QueryCurrentAnimeSeasonHandler.php @@ -2,7 +2,6 @@ namespace App\Features; -use App\Contracts\AnimeRepository; use App\Contracts\RequestHandler; use App\Dto\QueryCurrentAnimeSeasonCommand; use App\Enums\AnimeSeasonEnum; @@ -28,7 +27,7 @@ final class QueryCurrentAnimeSeasonHandler extends QueryAnimeSeasonHandlerBase */ private function getCurrentSeason() : array { - $date = new \DateTime(null, new \DateTimeZone('Asia/Tokyo')); + $date = new \DateTime('now', new \DateTimeZone('Asia/Tokyo')); $year = (int) $date->format('Y'); $month = (int) $date->format('n'); diff --git a/app/Features/QueryRandomAnimeHandler.php b/app/Features/QueryRandomAnimeHandler.php index 829c99c..e635ed6 100644 --- a/app/Features/QueryRandomAnimeHandler.php +++ b/app/Features/QueryRandomAnimeHandler.php @@ -2,47 +2,28 @@ namespace App\Features; -use App\Contracts\AnimeRepository; +use App\Anime; use App\Contracts\RequestHandler; use App\Dto\QueryRandomAnimeCommand; use App\Http\Resources\V4\AnimeResource; -use Illuminate\Support\Collection; -use Spatie\LaravelData\Optional; /** * @implements RequestHandler */ final class QueryRandomAnimeHandler implements RequestHandler { - public function __construct( - private readonly AnimeRepository $repository - ) - { - } - /** * @inheritDoc */ public function handle($request): AnimeResource { - $sfw = Optional::create() !== $request->sfw ? $request->sfw : null; - $unapproved = Optional::create() !== $request->unapproved ? $request->unapproved : null; - - /** - * @var Collection $results; - */ - $results = $this->repository; - - if (!$unapproved) { - $results->excludeUnapprovedItems($results); - } - - if ($sfw) { - $results->excludeNsfwItems($results); - } + $queryable = Anime::query(); + // apply sfw, kids and unapproved filters + /** @noinspection PhpUndefinedMethodInspection */ + $queryable = $queryable->filter(collect($request->all())); return new AnimeResource( - $results->random()->first() + $queryable->random()->first() ); } diff --git a/app/Features/QueryRandomMangaHandler.php b/app/Features/QueryRandomMangaHandler.php index c20146e..56f5832 100644 --- a/app/Features/QueryRandomMangaHandler.php +++ b/app/Features/QueryRandomMangaHandler.php @@ -2,47 +2,28 @@ namespace App\Features; -use App\Contracts\MangaRepository; use App\Contracts\RequestHandler; use App\Dto\QueryRandomMangaCommand; use App\Http\Resources\V4\MangaResource; -use Illuminate\Support\Collection; -use Spatie\LaravelData\Optional; +use App\Manga; /** * @implements RequestHandler */ final class QueryRandomMangaHandler implements RequestHandler { - public function __construct( - private readonly MangaRepository $repository - ) - { - } - /** * @inheritDoc */ public function handle($request) { - $sfw = Optional::create() !== $request->sfw ? $request->sfw : null; - $unapproved = Optional::create() !== $request->unapproved ? $request->unapproved : null; - - /** - * @var Collection $results; - */ - $results = $this->repository; - - if (!$unapproved) { - $results->excludeUnapprovedItems($results); - } - - if ($sfw) { - $results->excludeNsfwItems($results); - } + $queryable = Manga::query(); + // apply sfw, kids and unapproved filters + /** @noinspection PhpUndefinedMethodInspection */ + $queryable = $queryable->filter(collect($request->all())); return new MangaResource( - $results->random()->first() + $queryable->random()->first() ); } diff --git a/app/Filters/FilterQueryString.php b/app/Filters/FilterQueryString.php index c73308c..cd799dd 100644 --- a/app/Filters/FilterQueryString.php +++ b/app/Filters/FilterQueryString.php @@ -62,7 +62,7 @@ trait FilterQueryString }; $result = collect(array_filter($queryParameters->all(), $filter, ARRAY_FILTER_USE_KEY)) - ->filter(fn ($v, $k) => !empty($v)) ?? Collection::empty(); + ->filter(fn ($v, $k) => $v !== "" && $v !== null && !(is_float($v) && is_nan($v))) ?? Collection::empty(); return $this->_normalizeOrderBy($result); } diff --git a/app/JikanApiSearchableModel.php b/app/JikanApiSearchableModel.php index b2f5fe3..21d0810 100644 --- a/app/JikanApiSearchableModel.php +++ b/app/JikanApiSearchableModel.php @@ -83,6 +83,9 @@ abstract class JikanApiSearchableModel extends JikanApiModel implements Typesens protected function simplifyStringForSearch($val): string { + if (!$val) { + return ""; + } return preg_replace("/[^[:alnum:][:space:]]/u", ' ', $val) ?? ""; } } diff --git a/app/Manga.php b/app/Manga.php index 1f81d00..9499d0a 100644 --- a/app/Manga.php +++ b/app/Manga.php @@ -4,10 +4,12 @@ namespace App; use App\Concerns\FilteredByLetter; use App\Concerns\MediaFilters; +use App\Enums\MangaTypeEnum; use App\Http\HttpHelper; use Carbon\CarbonImmutable; use Database\Factories\MangaFactory; use Illuminate\Support\Facades\App; +use Jikan\Helper\Constants; use Jikan\Jikan; use Jikan\Request\Manga\MangaRequest; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -16,7 +18,10 @@ class Manga extends JikanApiSearchableModel { use HasFactory, MediaFilters, FilteredByLetter; - protected array $filters = ["order_by", "status", "type", "sort", "max_score", "min_score", "score", "start_date", "end_date", "magazine", "magazines", "letter", "genres", "genres_exclude"]; + protected array $filters = [ + "order_by", "status", "type", "sort", "max_score", "min_score", "score", "start_date", "end_date", "magazine", + "magazines", "letter", "genres", "genres_exclude", "sfw", "unapproved", "kids" + ]; /** * The attributes that are mass assignable. @@ -28,7 +33,7 @@ class Manga extends JikanApiSearchableModel 'images', 'status', 'type', 'volumes', 'chapters', 'publishing', 'published', 'rank', 'score', 'scored_by', 'popularity', 'members', 'favorites', 'synopsis', 'background', 'related', 'genres', 'explicit_genres', 'themes', 'demographics', 'authors', 'serializations', - 'createdAt', 'modifiedAt' + 'createdAt', 'modifiedAt', 'approved' ]; /** @@ -102,6 +107,29 @@ class Manga extends JikanApiSearchableModel return $query; } + /** @noinspection PhpUnused */ + public function scopeExceptItemsWithAdultRating(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder + { + return $query + ->where("type", "!=", MangaTypeEnum::doujin()->label) + ->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_HENTAI) + ->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_EROTICA); + } + + /** @noinspection PhpUnused */ + public function scopeExceptKidsItems(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder + { + return $query + ->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_KIDS); + } + + /** @noinspection PhpUnused */ + public function scopeOnlyKidsItems(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder + { + return $query + ->where("demographics.mal_id", Constants::GENRE_MANGA_KIDS); + } + public static function scrape(int $id) { $data = app('JikanParser')->getManga(new MangaRequest($id)); @@ -145,7 +173,7 @@ class Manga extends JikanApiSearchableModel 'members' => $this->members, 'favorites' => $this->favorites, 'synopsis' => $this->synopsis, - 'season' => $this->season, + 'approved' => $this->approved ?? false, 'magazines' => $this->getMalIdsOfField($this->magazines), 'genres' => $this->getMalIdsOfField($this->genres), 'explicit_genres' => $this->getMalIdsOfField($this->explicit_genres) diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 6ad4843..e3e42ac 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -96,6 +96,7 @@ class AppServiceProvider extends ServiceProvider $scoutDriver = static::getSearchIndexDriver($this->app); $serviceClass = match ($scoutDriver) { "typesense" => TypeSenseScoutSearchService::class, + // experimental "Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine" => ElasticScoutSearchService::class, default => DefaultScoutSearchService::class }; @@ -360,6 +361,7 @@ class AppServiceProvider extends ServiceProvider $services[] = Typesense::class; } + // experimental if (Env::get("SCOUT_DRIVER") === "Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine") { $services[] = \Elastic\Elasticsearch\Client::class; } diff --git a/app/Repositories/DefaultAnimeRepository.php b/app/Repositories/DefaultAnimeRepository.php index 5b1315f..27573f2 100644 --- a/app/Repositories/DefaultAnimeRepository.php +++ b/app/Repositories/DefaultAnimeRepository.php @@ -45,8 +45,7 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe public function exceptItemsWithAdultRating(): EloquentBuilder|ScoutBuilder { - $builder = $this->queryable() - ->where("rating", "!=", AnimeRatingEnum::rx()->label); + $builder = $this->queryable(); $this->excludeNsfwItems($builder); return $builder; @@ -54,9 +53,7 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe public function excludeNsfwItems($builder): EloquentBuilder|ScoutBuilder { - return $builder - ->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_HENTAI) - ->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_EROTICA); + return $builder->exceptItemsWithAdultRating(); } public function excludeUnapprovedItems($builder): Collection|EloquentBuilder|ScoutBuilder @@ -67,8 +64,7 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe public function excludeKidsItems($builder): EloquentBuilder|ScoutBuilder { - return $builder - ->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_KIDS); + return $builder->exceptKidsItems(); } public function orderByPopularity(): EloquentBuilder|ScoutBuilder @@ -121,9 +117,17 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe ?AnimeTypeEnum $type = null ): EloquentBuilder { - $queryable = $this->queryable(true)->whereBetween("aired.from", [ - $from->toAtomString(), - $to->modify("last day of this month")->toAtomString() +// $queryable = $this->queryable(true)->whereBetween("aired.from", [ +// $from->toAtomString(), +// $to->modify("last day of this month")->toAtomString() +// ]); + + /** @noinspection PhpParamsInspection */ + $queryable = $this->queryable(true)->whereRaw([ + "aired.from" => [ + '$gte' => $from->toAtomString(), + '$lte' => $to->modify("last day of this month")->toAtomString() + ] ]); if (!is_null($type)) { diff --git a/app/Repositories/DefaultMangaRepository.php b/app/Repositories/DefaultMangaRepository.php index 84e665a..7d6b598 100644 --- a/app/Repositories/DefaultMangaRepository.php +++ b/app/Repositories/DefaultMangaRepository.php @@ -50,9 +50,7 @@ final class DefaultMangaRepository extends DatabaseRepository implements MangaRe public function exceptItemsWithAdultRating(): EloquentBuilder|ScoutBuilder { - return $this->queryable() - ->where("type", "!=", MangaTypeEnum::doujin()->label) - ->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_HENTAI) - ->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_EROTICA); + /** @noinspection PhpUndefinedMethodInspection */ + return $this->queryable()->exceptItemsWithAdultRating(); } } diff --git a/bootstrap/app.php b/bootstrap/app.php index c19ae45..b5218ad 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -143,11 +143,12 @@ $app->instance('JikanParser', $jikan); $app->instance('SerializerV4', SerializerFactory::createV4()); $app->register(Laravel\Scout\ScoutServiceProvider::class); -// we support TypeSense and ElasticSearch as search indexes. +// we support TypeSense search index. if (env("SCOUT_DRIVER") === "typesense") { // in this case the TYPESENSE_HOST env var should be set too $app->register(\Typesense\LaravelTypesense\TypesenseServiceProvider::class); } +// experimental support for ElasticSearch search index if (env("SCOUT_DRIVER") === "Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine") { // in this case the ELASTICSEARCH_HOST env var should be set too $app->register(\Matchish\ScoutElasticSearch\ElasticSearchServiceProvider::class); diff --git a/composer.json b/composer.json index 2102d2d..8e12168 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "fabpot/goutte": "^4.0", "flipbox/lumen-generator": "^9.0", "illuminate/redis": "^9.0", - "jenssegers/mongodb": "^3.8", + "jenssegers/mongodb": "^3.9", "jikan-me/jikan": "^4", "jms/serializer": "^3.0", "laravel/legacy-factories": "^1.1", diff --git a/composer.lock b/composer.lock index 08a0696..07a878a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8aae72ff5c407ed2db0de3d15ef88c6d", + "content-hash": "bd75cf3fe6348185584fa3cbde3754e7", "packages": [ { "name": "amphp/amp", @@ -4286,16 +4286,16 @@ }, { "name": "jenssegers/mongodb", - "version": "v3.9.4", + "version": "v3.9.5", "source": { "type": "git", "url": "https://github.com/jenssegers/laravel-mongodb.git", - "reference": "0b03010682e5041ea80177a3db2d6509da92a9a5" + "reference": "6ce35ace85a5946f943d7f493f93aebb9a6d129d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jenssegers/laravel-mongodb/zipball/0b03010682e5041ea80177a3db2d6509da92a9a5", - "reference": "0b03010682e5041ea80177a3db2d6509da92a9a5", + "url": "https://api.github.com/repos/jenssegers/laravel-mongodb/zipball/6ce35ace85a5946f943d7f493f93aebb9a6d129d", + "reference": "6ce35ace85a5946f943d7f493f93aebb9a6d129d", "shasum": "" }, "require": { @@ -4352,7 +4352,7 @@ ], "support": { "issues": "https://github.com/jenssegers/laravel-mongodb/issues", - "source": "https://github.com/jenssegers/laravel-mongodb/tree/v3.9.4" + "source": "https://github.com/jenssegers/laravel-mongodb/tree/v3.9.5" }, "funding": [ { @@ -4364,7 +4364,7 @@ "type": "tidelift" } ], - "time": "2023-02-10T13:18:35+00:00" + "time": "2023-02-16T12:20:36+00:00" }, { "name": "jetbrains/phpstorm-stubs", diff --git a/database/factories/AnimeFactory.php b/database/factories/AnimeFactory.php index 611c3c3..f167422 100644 --- a/database/factories/AnimeFactory.php +++ b/database/factories/AnimeFactory.php @@ -66,6 +66,7 @@ class AnimeFactory extends JikanMediaModelFactory "members" => $this->faker->randomDigitNotnull(), "favorites" => $this->faker->randomDigitNotnull(), "synopsis" => "test", + "approved" => true, "background" => "test", "premiered" => $this->faker->randomElement(["Winter", "Spring", "Fall", "Summer"]), "broadcast" => [ diff --git a/database/factories/MangaFactory.php b/database/factories/MangaFactory.php index 8cb6a73..f8b2c66 100644 --- a/database/factories/MangaFactory.php +++ b/database/factories/MangaFactory.php @@ -57,6 +57,7 @@ class MangaFactory extends JikanMediaModelFactory "members" => $this->faker->randomDigitNotNull(), "favorites" => $this->faker->randomDigitNotNull(), "synopsis" => "test", + "approved" => true, "background" => "test", "authors" => [ [