$animethemes * @property DiscordThread|null $discordthread * @property Collection $externalentries * @property AnimeFormat|null $format * @property Collection $images * @property AnimeMediaFormat|null $media_format * @property string $name * @property Collection $resources * @property AnimeSeason|null $season * @property Collection $series * @property string $slug * @property Collection $studios * @property Collection $synonyms * @property string|null $synopsis * @property int|null $year * * @method static AnimeFactory factory(...$parameters) */ #[ObservedBy(AnimeObserver::class)] #[Table(Anime::TABLE, Anime::ATTRIBUTE_ID)] class Anime extends BaseModel implements Auditable, HasImages, HasResources, HasSynonyms, SoftDeletable { use HasAudits; use HasFactory; use Searchable; use SoftDeletes; use Submitable; final public const string TABLE = 'anime'; final public const string ATTRIBUTE_ID = 'anime_id'; final public const string ATTRIBUTE_MEDIA_FORMAT = 'media_format'; final public const string ATTRIBUTE_FORMAT = 'format'; final public const string ATTRIBUTE_NAME = 'name'; final public const string ATTRIBUTE_SEASON = 'season'; final public const string ATTRIBUTE_SLUG = 'slug'; final public const string ATTRIBUTE_SYNOPSIS = 'synopsis'; final public const string ATTRIBUTE_YEAR = 'year'; final public const string RELATION_ARTISTS = 'animethemes.song.artists'; final public const string RELATION_AUDIO = 'animethemes.animethemeentries.videos.audio'; final public const string RELATION_ENTRIES = 'animethemes.animethemeentries'; final public const string RELATION_EXTERNAL_ENTRIES = 'externalentries'; final public const string RELATION_EXTERNAL_PROFILE = 'externalentries.externalprofile'; final public const string RELATION_GROUPS = 'animethemes.group'; final public const string RELATION_IMAGES = 'images'; final public const string RELATION_PERFORMANCES_ARTIST = 'animethemes.song.performances.artist'; final public const string RELATION_PERFORMANCES_MEMBER = 'animethemes.song.performances.member'; final public const string RELATION_RESOURCES = 'resources'; final public const string RELATION_SCRIPTS = 'animethemes.animethemeentries.videos.videoscript'; final public const string RELATION_SERIES = 'series'; final public const string RELATION_SONG = 'animethemes.song'; final public const string RELATION_STUDIOS = 'studios'; final public const string RELATION_ANIMESYNONYMS = 'animesynonyms'; final public const string RELATION_SYNONYMS = 'synonyms'; final public const string RELATION_THEMES = 'animethemes'; final public const string RELATION_VIDEOS = 'animethemes.animethemeentries.videos'; /** * The event map for the model. * * Allows for object-based events for native Eloquent events. * * @var array */ protected $dispatchesEvents = [ 'created' => AnimeCreated::class, 'deleted' => AnimeDeleted::class, 'deleting' => AnimeDeleting::class, 'restored' => AnimeRestored::class, 'updated' => AnimeUpdated::class, ]; /** * The attributes that are mass assignable. * * @var list */ protected $fillable = [ Anime::ATTRIBUTE_FORMAT, Anime::ATTRIBUTE_NAME, Anime::ATTRIBUTE_SEASON, Anime::ATTRIBUTE_SLUG, Anime::ATTRIBUTE_SYNOPSIS, Anime::ATTRIBUTE_YEAR, Anime::ATTRIBUTE_MEDIA_FORMAT, ]; /** * Get the attributes that should be cast. * * @return array */ protected function casts(): array { return [ Anime::ATTRIBUTE_FORMAT => AnimeFormat::class, Anime::ATTRIBUTE_NAME => 'string', Anime::ATTRIBUTE_MEDIA_FORMAT => AnimeMediaFormat::class, Anime::ATTRIBUTE_SEASON => AnimeSeason::class, Anime::ATTRIBUTE_SLUG => 'string', Anime::ATTRIBUTE_SYNOPSIS => 'string', Anime::ATTRIBUTE_YEAR => 'int', ]; } /** * Modify the query used to retrieve models when making all of the models searchable. */ protected function makeAllSearchableUsing(Builder $query): Builder { return $query->with(Anime::RELATION_SYNONYMS); } /** * Get the indexable data array for the model. */ public function toSearchableArray(): array { return match ($driver = Config::get('scout.driver')) { 'collection', 'elastic' => AnimeElasticModel::toSearchableArray($this), 'typesense' => AnimeTypesenseModel::toSearchableArray($this), default => throw new RuntimeException("Unsupported {$driver} search driver configured."), }; } /** * Get the route key for the model. * * @noinspection PhpMissingParentCallCommonInspection */ public function getRouteKeyName(): string { return Anime::ATTRIBUTE_SLUG; } public function getName(): string { return $this->name; } public function getSubtitle(): string { return $this->slug; } /** * @return HasMany */ #[Deprecated('Use synonyms() instead.')] public function animesynonyms(): HasMany { return $this->hasMany(AnimeSynonym::class, AnimeSynonym::ATTRIBUTE_ANIME); } /** * Get the synonyms for the owner model. * * @return MorphMany */ public function synonyms(): MorphMany { return $this->morphMany(Synonym::class, Synonym::RELATION_SYNONYMABLE); } /** * @return HasOne */ public function discordthread(): HasOne { return $this->hasOne(DiscordThread::class, DiscordThread::ATTRIBUTE_ANIME); } /** * @return BelongsToMany */ public function series(): BelongsToMany { return $this->belongsToMany(Series::class, AnimeSeries::TABLE, AnimeSeries::ATTRIBUTE_ANIME, AnimeSeries::ATTRIBUTE_SERIES) ->using(AnimeSeries::class) ->as(AnimeSeriesJsonResource::$wrap) ->withPivot(AnimeSeries::ATTRIBUTE_ID) ->withTimestamps(); } /** * @return HasMany */ public function animethemes(): HasMany { return $this->hasMany(AnimeTheme::class, AnimeTheme::ATTRIBUTE_ANIME); } /** * @return MorphToMany */ public function resources(): MorphToMany { return $this->morphToMany(ExternalResource::class, Resourceable::RELATION_RESOURCEABLE, Resourceable::TABLE, Resourceable::ATTRIBUTE_RESOURCEABLE_ID, Resourceable::ATTRIBUTE_RESOURCE) ->using(Resourceable::class) ->as('animeresource') ->withPivot([Resourceable::ATTRIBUTE_ID, Resourceable::ATTRIBUTE_AS]) ->withTimestamps(); } /** * @return MorphToMany */ public function images(): MorphToMany { return $this->morphToMany(Image::class, Imageable::RELATION_IMAGEABLE, Imageable::TABLE, Imageable::ATTRIBUTE_IMAGEABLE_ID, Imageable::ATTRIBUTE_IMAGE) ->using(Imageable::class) ->as('animeimage') ->withPivot([Imageable::ATTRIBUTE_ID, Imageable::ATTRIBUTE_DEPTH]) ->withTimestamps(); } /** * @return BelongsToMany */ public function studios(): BelongsToMany { return $this->belongsToMany(Studio::class, AnimeStudio::TABLE, AnimeStudio::ATTRIBUTE_ANIME, AnimeStudio::ATTRIBUTE_STUDIO) ->using(AnimeStudio::class) ->as(AnimeStudioJsonResource::$wrap) ->withPivot(AnimeStudio::ATTRIBUTE_ID) ->withTimestamps(); } /** * @return HasMany */ public function externalentries(): HasMany { return $this->hasMany(ExternalEntry::class, ExternalEntry::ATTRIBUTE_ANIME); } }