*/ use HasFactory, HasAchievements, HasApiTokens, HasRoles; protected $casts = [ 'email_verified_at' => 'datetime', 'password' => 'hashed', 'settings' => 'array', ]; protected $appends = ['resolved_settings']; public function achievements(): HasMany { return $this->hasMany(UserAchievement::class); } public function getSetting(string $key): mixed { $defaults = SettingsRegistry::defaults(); return $this->settings[$key] ?? $defaults[$key] ?? null; } public function updateSettings(array $values): void { $current = array_merge(SettingsRegistry::defaults(), $this->settings ?? []); $this->update(['settings' => array_merge($current, $values)]); } function updateSetting($settingName, $value) : void{ $this->updateSettings([$settingName => $value]); } protected function resolvedSettings(): Attribute { return Attribute::make( get: fn() => array_merge(SettingsRegistry::defaults(), $this->settings ?? []) ); } public function unlockedAchievements(): HasMany { return $this->achievements() ->join('achievements', 'achievements.id', '=', 'user_achievements.achievement_id') ->where(function ($query) { $query // Non-progressive achievements: always count ->where(function ($q) { $q->where('achievements.progressive', false) ->orWhereNull('achievements.progressive'); }) // Progressive achievements: only if progress >= threshold ->orWhere(function ($q) { $q->where('achievements.progressive', true) ->whereNotNull('achievements.threshold') ->whereColumn('user_achievements.progress', '>=', 'achievements.threshold'); }); }); } public function resolveRouteBinding($value, $field = null): ?User { return $this->where('name', 'ilike', $value)->firstOrFail(); } public function flights(): HasMany { return $this->hasMany(UserFlight::class); } public function departedFlights() : HasMany { return $this->flights()->where('departure_date', '<=', now('UTC')); } public function upcomingFlights() : HasMany { return $this->flights()->where('departure_date', '>=', now('UTC')); } public function ImportedFlights(): HasMany { return $this->hasMany(ImportedFlight::class); } public function following(): HasMany { return $this->hasMany(Followee::class, 'user_id'); } public function followers(): HasMany { return $this->hasMany(Followee::class, 'followee_id'); } public function isFollowing(User $user): bool { return $this->following() ->where('followee_id', $user->id) ->verified() ->exists(); } public function followStatus(User $user): string { $followee = $this->following()->where('followee_id', $user->id)->first(); if (!$followee) { return 'none'; } return $followee->verified ? 'following' : 'requested'; } public function notifications(): HasMany { return $this->hasMany(Notification::class); } }