displayNameFieldName = "title"; } /** @noinspection PhpUnused */ public function filterByStartDate(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, CarbonImmutable $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder { return $query ->where("published.from", ">=", $value->setTime(0, 0) ->setTimezone(new \DateTimeZone('UTC')) ->toAtomString() ); } /** @noinspection PhpUnused */ public function filterByType(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, MangaTypeEnum $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder { return $query->where("type", $value->label); } /** @noinspection PhpUnused */ public function filterByEndDate(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, CarbonImmutable $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder { return $query ->where("published.to", "<=", $value->setTime(0, 0) ->setTimezone(new \DateTimeZone('UTC')) ->toAtomString() ); } public function filterByMagazine(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, string $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder { if (empty($value)) { return $query; } $magazine = (int)$value; return $query ->where('serializations.mal_id', $magazine); } /** @noinspection PhpUnused */ public function filterByMagazines(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, string $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder { if (empty($value)) { return $query; } /** @var \Illuminate\Support\Collection $magazines */ $magazines = collect(explode(',', $value))->filter()->map(fn($x) => (int)$x)->toArray(); return $query->whereIn("serializations.mal_id", $magazines); } /** @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) ->where("genres.mal_id", "!=", Constants::GENRE_MANGA_HENTAI); } /** @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)); return HttpHelper::serializeEmptyObjectsControllerLevel( json_decode( app('SerializerV4') ->serialize($data, 'json'), true ) ); } /** * Converts the model to an index-able data array. * * @return array */ public function toSearchableArray(): array { return [ 'id' => (string) $this->mal_id, 'mal_id' => (int) $this->mal_id, 'start_date' => $this->convertToTimestamp($this->published['from']), 'end_date' => $this->convertToTimestamp($this->published['to']), 'title' => $this->title, 'title_transformed' => $this->simplifyStringForSearch($this->title), 'title_english' => $this->title_english ?? "", 'title_english_transformed' => $this->simplifyStringForSearch($this->title_english), 'title_japanese' => $this->title_japanese, 'title_japanese_transformed' => $this->simplifyStringForSearch($this->title_japanese), 'title_synonyms' => collect($this->titles ?? []) ->filter(fn($v, $k) => !in_array($v["type"], ["Default", "English", "Japanese"])) ->pluck("title") ->values() ->all(), 'type' => $this->type, 'chapters' => $this->chapters, 'volumes' => $this->volumes, 'status' => $this->status, 'publishing' => $this->publishing, 'score' => $this->score, 'rank' => $this->rank, 'popularity' => $this->popularity, 'members' => $this->members, 'favorites' => $this->favorites, 'synopsis' => $this->synopsis, 'approved' => $this->approved ?? false, 'magazines' => $this->getMalIdsOfField($this->magazines), 'genres' => $this->getMalIdsOfField($this->genres), 'explicit_genres' => $this->getMalIdsOfField($this->explicit_genres) ]; } public function getCollectionSchema(): array { return [ 'name' => $this->searchableAs(), 'fields' => [ [ 'name' => '.*', 'type' => 'auto', ], [ 'name' => 'title', 'type' => 'string', 'optional' => false, 'infix' => true, 'sort' => true ], [ 'name' => 'title_transformed', 'type' => 'string', 'optional' => false, 'infix' => true, 'sort' => true ], [ 'name' => 'title_japanese', 'type' => 'string', 'optional' => true, 'locale' => 'jp', 'infix' => true, 'sort' => false ], [ 'name' => 'title_japanese_transformed', 'type' => 'string', 'optional' => true, 'locale' => 'jp', 'infix' => true, 'sort' => false ], [ 'name' => 'title_english', 'type' => 'string', 'optional' => true, 'infix' => true, 'sort' => true ], [ 'name' => 'title_english_transformed', 'type' => 'string', 'optional' => true, 'infix' => true, 'sort' => true ], [ 'name' => 'title_synonyms', 'type' => 'string[]', 'optional' => true, 'infix' => true, 'sort' => false ] ] ]; } /** @noinspection PhpUnused */ public function getThemesAttribute() { $result = []; if (array_key_exists("themes", $this->attributes)) { $result = $this->attributes["themes"]; } return $result; } public function typesenseQueryBy(): array { return [ 'title', 'title_transformed', 'title_english', 'title_english_transformed', 'title_japanese', 'title_japanese_transformed', 'title_synonyms', ]; } public function getTypeSenseQueryByWeights(): string|null { return "2,2,1,1,3,3,1"; } /** * Returns which fields the search index should sort on when searching * @return array|null */ public function getSearchIndexSortBy(): array|null { return [ [ "field" => "_text_match(buckets:".text_match_buckets().")", "direction" => "desc" ], [ "field" => "popularity", "direction" => "asc" ], [ "field" => "rank", "direction" => "asc" ] ]; } protected static function newFactory() { return App::make(MangaFactory::class); } }