$animethemes * @property Collection $artists * @property Collection $performances * @property Collection $resources * @property int $song_id * @property string|null $title * @property string|null $title_native * * @method static SongFactory factory(...$parameters) */ class Song extends BaseModel implements Auditable, HasResources, SoftDeletable { use HasAudits; use HasFactory; use Searchable; use SoftDeletes; use Submitable; final public const string TABLE = 'songs'; final public const string ATTRIBUTE_ID = 'song_id'; final public const string ATTRIBUTE_TITLE = 'title'; final public const string ATTRIBUTE_TITLE_NATIVE = 'title_native'; final public const string RELATION_ANIME = 'animethemes.anime'; final public const string RELATION_ANIMETHEMES = 'animethemes'; final public const string RELATION_ARTISTS = 'artists'; final public const string RELATION_PERFORMANCES = 'performances'; final public const string RELATION_PERFORMANCE_ARTISTS = 'performances.artist'; final public const string RELATION_RESOURCES = 'resources'; final public const string RELATION_THEME_GROUPS = 'animethemes.group'; final public const string RELATION_VIDEOS = 'animethemes.animethemeentries.videos'; /** * The table associated with the model. * * @var string */ protected $table = Song::TABLE; /** * The primary key associated with the table. * * @var string */ protected $primaryKey = Song::ATTRIBUTE_ID; /** * The event map for the model. * * Allows for object-based events for native Eloquent events. * * @var array */ protected $dispatchesEvents = [ 'created' => SongCreated::class, 'deleted' => SongDeleted::class, 'deleting' => SongDeleting::class, 'restored' => SongRestored::class, 'updated' => SongUpdated::class, ]; /** * The attributes that are mass assignable. * * @var list */ protected $fillable = [ Song::ATTRIBUTE_TITLE, Song::ATTRIBUTE_TITLE_NATIVE, ]; public function getName(): string { if (blank($this->title)) { return strval($this->getKey()); } return $this->title; } public function getSubtitle(): string { if ($this->animethemes()->count() !== 0 && $this->animethemes->first()->anime !== null) { return "{$this->animethemes->first()->anime->getName()} {$this->animethemes->first()->slug}"; } return $this->title_native ?? strval($this->getKey()); } /** * @return HasMany */ public function animethemes(): HasMany { return $this->hasMany(AnimeTheme::class, AnimeTheme::ATTRIBUTE_SONG); } /** * @return BelongsToMany */ public function artists(): BelongsToMany { return $this->belongsToMany(Artist::class, ArtistSong::TABLE, ArtistSong::ATTRIBUTE_SONG, ArtistSong::ATTRIBUTE_ARTIST) ->using(ArtistSong::class) ->withPivot([ArtistSong::ATTRIBUTE_ALIAS, ArtistSong::ATTRIBUTE_AS]) ->as(ArtistSongResource::$wrap) ->withTimestamps(); } /** * @return HasMany */ public function performances(): HasMany { return $this->hasMany(Performance::class, Performance::ATTRIBUTE_SONG); } /** * @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) ->withPivot(Resourceable::ATTRIBUTE_AS) ->as('songresource') ->withTimestamps(); } }