From c73bb4d4f4f32047121b05b6405dd9c74ea37746 Mon Sep 17 00:00:00 2001 From: Jamiras <32680403+Jamiras@users.noreply.github.com> Date: Fri, 27 Oct 2023 11:24:03 -0600 Subject: [PATCH] use aggregate data for reset progress dropdowns (#1933) --- app/Helpers/database/user.php | 64 -------------------- app/Platform/Actions/ResetPlayerProgress.php | 17 ++---- public/request/user/list-games.php | 23 +++++-- public/request/user/list-unlocks.php | 33 +++++----- 4 files changed, 39 insertions(+), 98 deletions(-) diff --git a/app/Helpers/database/user.php b/app/Helpers/database/user.php index c8609a2327..85316c9927 100644 --- a/app/Helpers/database/user.php +++ b/app/Helpers/database/user.php @@ -63,32 +63,6 @@ function getUserMetadataFromID(int $userID): ?array return null; } -/** - * @param array|null $dataOut - */ -function getUserUnlocksDetailed(string $user, int $gameID, ?array &$dataOut): int -{ - sanitize_sql_inputs($user); - - $query = "SELECT ach.Title, ach.ID, ach.Points, aw.HardcoreMode - FROM Achievements AS ach - LEFT JOIN Awarded AS aw ON ach.ID = aw.AchievementID - WHERE ach.GameID = '$gameID' AND aw.User = '$user' - ORDER BY ach.ID, aw.HardcoreMode "; - - $dbResult = s_mysql_query($query); - - $dataOut = []; - - if ($dbResult !== false) { - while ($data = mysqli_fetch_assoc($dbResult)) { - $dataOut[] = $data; - } - } - - return count($dataOut); -} - function validateUsername(string $userIn): ?string { $user = User::firstWhere('User', $userIn); @@ -170,44 +144,6 @@ function getUserPageInfo(string $user, int $numGames = 0, int $numRecentAchievem return $libraryOut; } -function getControlPanelUserInfo(string $user, ?array &$libraryOut): bool -{ - sanitize_sql_inputs($user); - - $libraryOut = []; - $libraryOut['Played'] = []; - // getUserActivityRange( $user, $firstLogin, $lastLogin ); - // $libraryOut['MemberSince'] = $firstLogin; - // $libraryOut['LastLogin'] = $lastLogin; - - $query = "SELECT gd.ID, c.Name AS ConsoleName, gd.Title AS GameTitle, COUNT(*) AS NumAwarded, Inner1.NumPossible - FROM Awarded AS aw - LEFT JOIN Achievements AS ach ON ach.ID = aw.AchievementID - LEFT JOIN GameData AS gd ON gd.ID = ach.GameID - LEFT JOIN Console AS c ON c.ID = gd.ConsoleID - LEFT JOIN ( - SELECT ach.GameID, COUNT(*) AS NumPossible - FROM Achievements AS ach - WHERE ach.Flags = 3 - GROUP BY ach.GameID ) AS Inner1 ON Inner1.GameID = gd.ID - WHERE aw.User = '$user' AND aw.HardcoreMode = 0 - GROUP BY gd.ID, gd.ConsoleID, gd.Title - ORDER BY gd.Title, gd.ConsoleID"; - - $dbResult = s_mysql_query($query); - if (!$dbResult) { - log_sql_fail(); - - return false; - } - - while ($db_entry = mysqli_fetch_assoc($dbResult)) { - $libraryOut['Played'][] = $db_entry; - } // use as raw array to preserve order! - - return true; -} - function getUserListByPerms(int $sortBy, int $offset, int $count, ?array &$dataOut, ?string $requestedBy = null, int $perms = Permissions::Unregistered, bool $showUntracked = false): int { $whereQuery = null; diff --git a/app/Platform/Actions/ResetPlayerProgress.php b/app/Platform/Actions/ResetPlayerProgress.php index 7736d643d3..0fd2b48c12 100644 --- a/app/Platform/Actions/ResetPlayerProgress.php +++ b/app/Platform/Actions/ResetPlayerProgress.php @@ -21,24 +21,19 @@ public function execute(User $user, ?int $achievementID = null, ?int $gameID = n $clause = "AND ach.GameID=$gameID"; } - // TODO refactor, do not use Awarded $affectedAchievements = legacyDbFetchAll(" SELECT ach.Author, ach.GameID, - aw_ach.HardcoreMode, + CASE WHEN pa.unlocked_hardcore_at THEN 1 ELSE 0 END AS HardcoreMode, COUNT(ach.ID) AS Count, SUM(ach.Points) AS Points, SUM(ach.TrueRatio) AS TruePoints - FROM ( - SELECT aw.AchievementID, MAX(aw.HardcoreMode) as HardcoreMode - FROM Awarded aw - LEFT JOIN Achievements ach ON ach.ID=aw.AchievementID - WHERE aw.User = :username $clause GROUP BY aw.AchievementID - ) as aw_ach - LEFT JOIN Achievements ach ON ach.ID = aw_ach.AchievementID + FROM player_achievements pa + INNER JOIN Achievements ach ON ach.ID = pa.achievement_id WHERE ach.Flags = " . AchievementFlag::OfficialCore . " - GROUP BY ach.Author, ach.GameID, aw_ach.HardcoreMode - ", ['username' => $user->User]); + AND pa.user_id = {$user->id} $clause + GROUP BY ach.Author, ach.GameID, HardcoreMode + "); $affectedGames = collect(); $authorUsernames = collect(); diff --git a/public/request/user/list-games.php b/public/request/user/list-games.php index d3dbbc74c6..c37f83a6c3 100644 --- a/public/request/user/list-games.php +++ b/public/request/user/list-games.php @@ -1,11 +1,26 @@ json($userData['Played']); -} +$dataOut = User::firstWhere('User', $user) + ->games() + ->with('system') + ->where('player_games.achievements_unlocked', '>', 0) + ->orderBy('Title') + ->select(['GameData.ID', 'Title', 'ConsoleID', 'achievements_published', 'player_games.achievements_unlocked']) + ->get() + ->map(function ($game) { + return [ + 'ID' => $game->ID, + 'GameTitle' => $game->Title, + 'ConsoleName' => $game->system->Name, + 'NumAwarded' => $game->achievements_unlocked, + 'NumPossible' => $game->achievements_published, + ]; + }); -abort(400); +return response()->json($dataOut); diff --git a/public/request/user/list-unlocks.php b/public/request/user/list-unlocks.php index d0fc1f8eee..c2ba0e301d 100644 --- a/public/request/user/list-unlocks.php +++ b/public/request/user/list-unlocks.php @@ -1,8 +1,8 @@ 'required|integer', ]); -getUserUnlocksDetailed($user, $input['game'], $dataOut); - -$hardcoreUnlocks = (new Collection($dataOut)) - ->filter(fn ($achievement) => (bool) $achievement['HardcoreMode']) - ->keyBy('ID'); - -$dataOut = (new Collection($dataOut)) - // results in unique IDs - ->keyBy('ID') - ->filter(fn ($achievement) => !$achievement['HardcoreMode']) - // merge on top to make sure hardcore unlocks take precedence - ->merge($hardcoreUnlocks) - ->map(function ($achievement) { - $achievement['HardcoreMode'] = (int) $achievement['HardcoreMode']; - - return $achievement; - }) - ->values(); +$dataOut = User::firstWhere('User', $user) + ->achievements()->where('GameID', $input['game']) + ->withPivot(['unlocked_at', 'unlocked_hardcore_at']) + ->orderBy('Title') + ->get() + ->map(function ($achievementUnlocked) { + return [ + 'ID' => $achievementUnlocked->ID, + 'Title' => $achievementUnlocked->Title, + 'Points' => $achievementUnlocked->Points, + 'HardcoreMode' => $achievementUnlocked->pivot->unlocked_hardcore_at ? 1 : 0, + ]; + }); return response()->json($dataOut);