hasMany(Album::class); } /** * An artist can have many songs. * Unless he is Rick Astley. */ public function songs(): HasManyThrough { return $this->hasManyThrough(Song::class, Album::class); } public function getIsUnknownAttribute(): bool { return $this->id === self::UNKNOWN_ID; } public function getIsVariousAttribute(): bool { return $this->id === self::VARIOUS_ID; } public static function getVariousArtist(): self { return static::find(self::VARIOUS_ID); } /** * Sometimes the tags extracted from getID3 are HTML entity encoded. * This makes sure they are always sane. */ public function getNameAttribute(string $value): string { return html_entity_decode($value ?: self::UNKNOWN_NAME); } /** * Get an Artist object from their name. * If such is not found, a new artist will be created. */ public static function getOrCreate(?string $name = null): self { // Remove the BOM from UTF-8/16/32, as it will mess up the database constraints. $encoding = Util::detectUTFEncoding($name); if ($encoding) { $name = mb_convert_encoding($name, 'UTF-8', $encoding); } return static::firstOrCreate(['name' => trim($name) ?: self::UNKNOWN_NAME]); } /** * Turn the image name into its absolute URL. */ public function getImageAttribute(?string $value): ?string { return $value ? artist_image_url($value) : null; } public function getImagePathAttribute(): ?string { if (!$this->has_image) { return null; } return artist_image_path(array_get($this->attributes, 'image')); } public function getHasImageAttribute(): bool { $image = array_get($this->attributes, 'image'); if (!$image) { return false; } return file_exists(artist_image_path($image)); } /** @return array */ public function toSearchableArray(): array { return [ 'id' => $this->id, 'name' => $this->name, ]; } }