the browser-facing portion of osu!
at master 127 lines 4.1 kB view raw
1<?php 2 3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4// See the LICENCE file in the repository root for full licence text. 5 6namespace App\Transformers; 7 8use App\Models\Beatmap; 9use App\Models\UserStatistics; 10use League\Fractal\Resource\ResourceInterface; 11 12class UserStatisticsTransformer extends TransformerAbstract 13{ 14 protected array $availableIncludes = [ 15 'country_rank', 16 'rank', 17 'rank_change_since_30_days', 18 'user', 19 'variants', 20 ]; 21 22 public function transform(UserStatistics\Model $stats = null) 23 { 24 if ($stats === null) { 25 $stats = new UserStatistics\Osu(); 26 } 27 28 if (!$GLOBALS['cfg']['osu']['scores']['experimental_rank_as_default'] && $GLOBALS['cfg']['osu']['scores']['experimental_rank_as_extra']) { 29 $globalRankExp = $stats->globalRankExp(); 30 $ppExp = $stats->rank_score_exp; 31 } 32 33 return [ 34 'count_100' => $stats->count100, 35 'count_300' => $stats->count300, 36 'count_50' => $stats->count50, 37 'count_miss' => $stats->countMiss, 38 'level' => [ 39 'current' => $stats->currentLevel(), 40 'progress' => $stats->currentLevelProgressPercent(), 41 ], 42 'global_rank' => $stats->globalRank(), 43 'global_rank_exp' => $globalRankExp ?? null, 44 'pp' => $stats->pp(), 45 'pp_exp' => $ppExp ?? 0, 46 'ranked_score' => $stats->ranked_score, 47 'hit_accuracy' => $stats->hit_accuracy, 48 'play_count' => $stats->playcount, 49 'play_time' => $stats->total_seconds_played, 50 'total_score' => $stats->total_score, 51 'total_hits' => $stats->totalHits(), 52 'maximum_combo' => $stats->max_combo, 53 'replays_watched_by_others' => $stats->replay_popularity, 54 'is_ranked' => $stats->isRanked(), 55 'grade_counts' => [ 56 'ss' => $stats->x_rank_count, 57 'ssh' => $stats->xh_rank_count ?? 0, // osu_charts tables don't have the `h` columns 58 's' => $stats->s_rank_count, 59 'sh' => $stats->sh_rank_count ?? 0, 60 'a' => $stats->a_rank_count, 61 ], 62 ]; 63 } 64 65 public function includeCountryRank(UserStatistics\Model $stats = null) 66 { 67 if ($stats !== null) { 68 return $this->primitive($stats->countryRank()); 69 } 70 } 71 72 // TODO: remove this after country_rank is deployed 73 public function includeRank(UserStatistics\Model $stats = null) 74 { 75 if ($stats === null) { 76 $stats = new UserStatistics\Osu(); 77 } 78 79 return $this->primitive(['country' => $stats->countryRank()]); 80 } 81 82 public function includeRankChangeSince30Days(UserStatistics\Model $stats): ResourceInterface 83 { 84 return $this->primitive($stats->rankHistory?->rankChangeSince30Days()); 85 } 86 87 public function includeUser(UserStatistics\Model $stats = null) 88 { 89 if ($stats === null) { 90 $stats = new UserStatistics\Osu(); 91 } 92 93 return $this->item($stats->user, new UserCompactTransformer()); 94 } 95 96 public function includeVariants(UserStatistics\Model $stats = null) 97 { 98 if ($stats === null) { 99 return; 100 } 101 102 $mode = $stats->getMode(); 103 $variants = Beatmap::VARIANTS[$mode] ?? null; 104 105 if ($variants === null) { 106 return; 107 } 108 109 $data = []; 110 111 foreach ($variants as $variant) { 112 // User should be preloaded in cases where this is used. 113 $entry = $stats->user->statistics($mode, false, $variant) ?? new (UserStatistics\Model::getClass($mode, $variant)); 114 115 $data[] = [ 116 'mode' => $mode, 117 'variant' => $variant, 118 119 'country_rank' => $entry->countryRank(), 120 'global_rank' => $entry->globalRank(), 121 'pp' => $entry->rank_score, 122 ]; 123 } 124 125 return $this->primitive($data); 126 } 127}