id)->pluck('achievement_id')->toArray(); $newlyEarned = []; foreach ($allAchievements as $ach) { if (in_array($ach->id, $earned)) continue; $met = match ($ach->condition_type) { 'episodes_watched' => self::episodesWatched($user) >= $ach->condition_value, 'hours_watched' => self::hoursWatched($user) >= $ach->condition_value, 'watchlist_count' => Watchlist::where('user_id', $user->id)->count() >= $ach->condition_value, 'anime_rated' => DB::table('anime_ratings')->where('user_id', $user->id)->count() >= $ach->condition_value, 'request_sent' => DB::table('anime_requests')->where('user_id', $user->id)->count() >= $ach->condition_value, 'first_login' => true, default => false, }; if ($met) { UserAchievement::firstOrCreate([ 'user_id' => $user->id, 'achievement_id' => $ach->id, ], ['earned_at' => now()]); $newlyEarned[] = $ach; } } return $newlyEarned; } private static function episodesWatched(User $user): int { return ContinueWatching::where('user_id', $user->id) ->where('percent_complete', '>=', 70) ->count(); } private static function hoursWatched(User $user): float { return round( ContinueWatching::where('user_id', $user->id)->sum('seconds_watched') / 3600, 1 ); } }