diff --git a/app/Http/Controllers/UsersController.php b/app/Http/Controllers/UsersController.php index f3f1156d9b7..06ebfb69eab 100644 --- a/app/Http/Controllers/UsersController.php +++ b/app/Http/Controllers/UsersController.php @@ -178,7 +178,7 @@ public function extraPages($_id, $page) 'monthly_playcounts' => json_collection($this->user->monthlyPlaycounts, new UserMonthlyPlaycountTransformer()), 'recent' => $this->getExtraSection( 'scoresRecent', - $this->user->scores($this->mode, true)->includeFails(false)->count() + $this->user->recentScoreCount($this->mode) ), 'replays_watched_counts' => json_collection($this->user->replaysWatchedCounts, new UserReplaysWatchedCountTransformer()), ]; @@ -816,9 +816,12 @@ private function getExtra($page, array $options, int $perPage = 10, int $offset case 'scoresRecent': $transformer = new ScoreTransformer(); $includes = ScoreTransformer::USER_PROFILE_INCLUDES; - $query = $this->user->scores($this->mode, true) + $query = $this->user->soloScores() + ->default() + ->forRuleset($this->mode) ->includeFails($options['includeFails'] ?? false) - ->with([...ScoreTransformer::USER_PROFILE_INCLUDES_PRELOAD, 'best']); + ->reorderBy('id', 'desc') + ->with(ScoreTransformer::USER_PROFILE_INCLUDES_PRELOAD); $userRelationColumn = 'user'; break; } diff --git a/app/Models/Solo/Score.php b/app/Models/Solo/Score.php index 2be4ed1074f..9a688db4c15 100644 --- a/app/Models/Solo/Score.php +++ b/app/Models/Solo/Score.php @@ -106,6 +106,18 @@ public function scopeDefault(Builder $query): Builder return $query->whereHas('beatmap'); } + public function scopeForRuleset(Builder $query, string $ruleset): Builder + { + return $query->where('ruleset_id', Beatmap::MODES[$ruleset]); + } + + public function scopeIncludeFails(Builder $query, bool $includeFails): Builder + { + return $includeFails + ? $query + : $query->where('data->passed', true); + } + /** * This should match the one used in osu-elastic-indexer. */ diff --git a/app/Models/User.php b/app/Models/User.php index 91753b37777..afe9a3185c5 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -916,6 +916,7 @@ public function getAttribute($key) 'scoresMania', 'scoresOsu', 'scoresTaiko', + 'soloScores', 'statisticsFruits', 'statisticsMania', 'statisticsOsu', @@ -1427,6 +1428,11 @@ public function scoresBest(string $mode, bool $returnQuery = false) return $returnQuery ? $this->$relation() : $this->$relation; } + public function soloScores(): HasMany + { + return $this->hasMany(Solo\Score::class); + } + public function topicWatches() { return $this->hasMany(TopicWatch::class); @@ -1776,6 +1782,18 @@ public function authHash(): string return hash('sha256', $this->user_email).':'.hash('sha256', $this->user_password); } + public function recentScoreCount(string $ruleset): int + { + return $this->soloScores() + ->default() + ->forRuleset($ruleset) + ->includeFails(false) + ->select('id') + ->limit(100) + ->get() + ->count(); + } + public function resetSessions(?string $excludedSessionId = null): void { SessionStore::destroy($this->getKey(), $excludedSessionId); diff --git a/app/Transformers/UserCompactTransformer.php b/app/Transformers/UserCompactTransformer.php index f1f3603d0ba..56d91c3cede 100644 --- a/app/Transformers/UserCompactTransformer.php +++ b/app/Transformers/UserCompactTransformer.php @@ -383,7 +383,7 @@ public function includeScoresPinnedCount(User $user) public function includeScoresRecentCount(User $user) { - return $this->primitive($user->scores($this->mode, true)->includeFails(false)->count()); + return $this->primitive($user->recentScoreCount($this->mode)); } public function includeStatistics(User $user)