$externalentries * @property ExternalToken|null $externaltoken * @property int|null $external_user_id * @property string $name * @property ExternalProfileSite $site * @property Carbon|null $synced_at * @property int|null $user_id * @property User|null $user * @property ExternalProfileVisibility $visibility * * @method static ExternalProfileFactory factory(...$parameters) */ #[Table(ExternalProfile::TABLE, ExternalProfile::ATTRIBUTE_ID)] class ExternalProfile extends BaseModel { use HasFactory; use Prunable; use Searchable; final public const string TABLE = 'external_profiles'; final public const string ATTRIBUTE_ID = 'profile_id'; final public const string ATTRIBUTE_EXTERNAL_USER_ID = 'external_user_id'; final public const string ATTRIBUTE_NAME = 'name'; final public const string ATTRIBUTE_SITE = 'site'; final public const string ATTRIBUTE_VISIBILITY = 'visibility'; final public const string ATTRIBUTE_USER = 'user_id'; final public const string ATTRIBUTE_SYNCED_AT = 'synced_at'; final public const string RELATION_ANIMES = 'externalentries.anime'; final public const string RELATION_EXTERNAL_ENTRIES = 'externalentries'; final public const string RELATION_EXTERNAL_TOKEN = 'externaltoken'; final public const string RELATION_USER = 'user'; /** * The event map for the model. * * Allows for object-based events for native Eloquent events. * * @var array */ protected $dispatchesEvents = [ 'created' => ExternalProfileCreated::class, 'deleted' => ExternalProfileDeleted::class, 'updated' => ExternalProfileUpdated::class, ]; /** * The attributes that are mass assignable. * * @var list */ protected $fillable = [ ExternalProfile::ATTRIBUTE_EXTERNAL_USER_ID, ExternalProfile::ATTRIBUTE_NAME, ExternalProfile::ATTRIBUTE_SITE, ExternalProfile::ATTRIBUTE_SYNCED_AT, ExternalProfile::ATTRIBUTE_VISIBILITY, ExternalProfile::ATTRIBUTE_USER, ]; /** * Get the attributes that should be cast. * * @return array */ protected function casts(): array { return [ ExternalProfile::ATTRIBUTE_EXTERNAL_USER_ID => 'int', ExternalProfile::ATTRIBUTE_NAME => 'string', ExternalProfile::ATTRIBUTE_SITE => ExternalProfileSite::class, ExternalProfile::ATTRIBUTE_SYNCED_AT => 'datetime', ExternalProfile::ATTRIBUTE_VISIBILITY => ExternalProfileVisibility::class, ExternalProfile::ATTRIBUTE_USER => 'int', ]; } public function getName(): string { return $this->name; } public function getSubtitle(): string { return $this->user === null ? $this->getName() : $this->user->getName(); } /** * Get the indexable data array for the model. */ public function toSearchableArray(): array { return match ($driver = Config::get('scout.driver')) { 'collection', 'elastic' => ExternalProfileElasticModel::toSearchableArray($this), 'typesense' => ExternalProfileTypesenseModel::toSearchableArray($this), default => throw new RuntimeException("Unsupported {$driver} search driver configured."), }; } /** * Get the index name for the model when searching. */ public function searchableAs(): string { return 'profiles'; } /** * Determine if the model should be searchable. */ public function shouldBeSearchable(): bool { return $this->visibility === ExternalProfileVisibility::PUBLIC; } /** * Check if the profile was created through username case. */ public function isClaimed(): bool { return (bool) $this->user_id; } public function canBeSynced(): bool { return ! $this->synced_at || $this->synced_at->addHours(3)->isPast(); } public function dispatchSyncJob(): void { SyncExternalProfileJob::dispatch($this); } /** * Format: https://animethemes.moe/external/{mal|anilist}/{profile_name}. */ public function getClientUrl(): Uri { return Uri::of(Config::get('wiki.external_profile')) ->withPath(Str::lower($this->site->name).'/'.$this->getName()); } /** * @return HasMany */ public function externalentries(): HasMany { return $this->hasMany(ExternalEntry::class, ExternalEntry::ATTRIBUTE_PROFILE); } /** * @return BelongsTo */ public function user(): BelongsTo { return $this->belongsTo(User::class, ExternalProfile::ATTRIBUTE_USER); } /** * @return HasOne */ public function externaltoken(): HasOne { return $this->hasOne(ExternalToken::class, ExternalToken::ATTRIBUTE_PROFILE); } /** * Get the prunable model query. */ public function prunable(): Builder { return static::query() ->whereDoesntHave(ExternalProfile::RELATION_USER) ->where( BaseModel::ATTRIBUTE_CREATED_AT, ComparisonOperator::LTE->value, Date::now()->subWeek() ); } }