*/ use Billable, HasFactory, HasMedia, HasUuids, HasWorkspace, Notifiable; /** * The attributes that are mass assignable. * * @var list */ protected $fillable = [ 'name', 'email', 'password', 'setup', 'persona', 'current_workspace_id', 'language_id', 'email_verified_at', ]; /** * The attributes that should be hidden for serialization. * * @var list */ protected $hidden = [ 'password', 'two_factor_secret', 'two_factor_recovery_codes', 'remember_token', ]; protected $appends = [ 'has_photo', 'photo_url', ]; public function getHasPhotoAttribute(): bool { return $this->getFirstMedia('avatar') !== null; } public function getPhotoUrlAttribute(): ?string { return $this->getFirstMediaUrl('avatar'); } /** * Get the attributes that should be cast. * * @return array */ protected function casts(): array { return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', 'two_factor_confirmed_at' => 'datetime', 'setup' => Setup::class, 'persona' => Persona::class, ]; } /** * Get the user's language. */ public function language(): BelongsTo { return $this->belongsTo(Language::class); } /** * Check if user has an active subscription. * In self-hosted mode, always returns true (no subscription required). */ public function hasActiveSubscription(): bool { if (config('trypost.self_hosted')) { return true; } return $this->subscribed('default'); } /** * Check if user has ever had a subscription (for trial eligibility). */ public function hasEverSubscribed(): bool { return $this->subscriptions()->exists(); } }