Passed
Pull Request — master (#88)
by Chenyi
04:29
created

RankModel::getProfessionalRanking()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 15
nc 2
nop 0
dl 0
loc 19
rs 9.7666
c 0
b 0
f 0
1
<?php
2
3
namespace App\Models;
4
5
use GrahamCampbell\Markdown\Facades\Markdown;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Support\Facades\DB;
8
use Illuminate\Support\Arr;
9
use Cache,Redis;
10
11
class RankModel extends Model
12
{
13
    private static $professionalRanking=[
14
        "Legendary Grandmaster"=>"cm-colorful-text",
15
        "International Grandmaster"=>"wemd-pink-text",
16
        "Grandmaster"=>"wemd-red-text",
17
        "International Master"=>"wemd-amber-text",
18
        "Master"=>"wemd-orange-text",
19
        "Candidate Master"=>"wemd-purple-text",
20
        "Expert"=>"wemd-blue-text",
21
        "Specialist"=>"wemd-cyan-text",
22
        "Pupil"=>"wemd-green-text",
23
        "Newbie"=>"wemd-gray-text",
24
    ];
25
26
    public $professionalRankingPer=[
27
        "Legendary Grandmaster"=>3000,
28
        "International Grandmaster"=>2600,
29
        "Grandmaster"=>2400,
30
        "International Master"=>2300,
31
        "Master"=>2100,
32
        "Candidate Master"=>1900,
33
        "Expert"=>1600,
34
        "Specialist"=>1400,
35
        "Pupil"=>1200,
36
        "Newbie"=>1,
37
    ];
38
39
    private static $casualRanking=[
40
        "Legendary Grandmaster"=>"cm-colorful-text",
41
        "International Grandmaster"=>"wemd-pink-text",
42
        "Grandmaster"=>"wemd-red-text",
43
        "International Master"=>"wemd-amber-text",
44
        "Master"=>"wemd-orange-text",
45
        "Candidate Master"=>"wemd-purple-text",
46
        "Expert"=>"wemd-blue-text",
47
        "Specialist"=>"wemd-cyan-text",
48
        "Pupil"=>"wemd-green-text",
49
        "Newbie"=>"wemd-gray-text",
50
    ];
51
52
    public $casualRankingPer=[
53
        "Legendary Grandmaster"=>1,
54
        "International Grandmaster"=>5,
55
        "Grandmaster"=>10,
56
        "International Master"=>10,
57
        "Master"=>50,
58
        "Candidate Master"=>100,
59
        "Expert"=>300,
60
        "Specialist"=>700,
61
        "Pupil"=>1000,
62
        "Newbie"=>400,
63
    ];
64
65
    public static function getColor($rankTitle)
66
    {
67
        if(is_null($rankTitle)) return "";
68
        return self::$casualRanking[$rankTitle];
69
    }
70
71
    public static function getProfessionalColor($rankTitle)
72
    {
73
        if(is_null($rankTitle)) return self::$professionalRanking["None"];
74
        return self::$professionalRanking[$rankTitle];
75
    }
76
77
    public function list()
78
    {
79
        $rankList=Cache::tags(['rank'])->get('general');
80
        $userInfoRaw=DB::table("users")->select("id as uid","avatar","name")->get()->all();
81
        $userInfo=[];
82
        foreach($userInfoRaw as $u){
83
            $userInfo[$u["uid"]]=$u;
84
        }
85
        foreach($rankList as &$r){
86
            $r["details"]=isset($userInfo[$r["uid"]])?$userInfo[$r["uid"]]:[];
87
        }
88
        // var_dump($rankList); exit();
89
        return $rankList;
90
    }
91
92
    public function rankList()
93
    {
94
        Cache::tags(['rank'])->flush();
95
        $totUsers=DB::table("submission")->where(["verdict"=>"Accepted"])->select(DB::raw("count(distinct uid) as res"))->get()->first()["res"];
96
        if ($totUsers>0) {
97
            $rankList=DB::select("SELECT *,solvedCount+communityCount as totValue FROM (SELECT uid,sum(solvedCount) as solvedCount,sum(communityCount) as communityCount FROM ((SELECT uid,count(DISTINCT submission.pid) as solvedCount,0 as communityCount from submission where verdict=\"Accepted\" group by uid) UNION (SELECT uid,0 as solvedCount,count(DISTINCT pid) from problem_solution where audit=1 group by uid)) as temp GROUP BY uid) as temp2 ORDER BY solvedCount+communityCount DESC");
98
            $rankIter=1;
99
            $rankValue=1;
100
            $rankSolved=-1;
101
            $rankListCached=[];
102
            $this->procRankingPer();
103
            foreach ($rankList as $rankItem) {
104
                if ($rankSolved!=$rankItem["totValue"]) {
105
                    $rankValue=$rankIter;
106
                    $rankSolved=$rankItem["totValue"];
107
                }
108
                $rankTitle=$this->getRankTitle($rankValue);
109
                Cache::tags(['rank',$rankItem["uid"]])->put("rank", $rankValue, 86400);
110
                Cache::tags(['rank',$rankItem["uid"]])->put("title", $rankTitle, 86400);
111
                $rankListCached[]=[
112
                    "uid"=>$rankItem["uid"],
113
                    "rank"=>$rankValue,
114
                    "title"=>$rankTitle,
115
                    "titleColor"=>self::getColor($rankTitle),
116
                    "solved"=>$rankItem["solvedCount"],
117
                    "community"=>$rankItem["communityCount"]
118
                ];
119
                $rankIter++;
120
            }
121
            Cache::tags(['rank'])->put("general", $rankListCached, 86400);
122
        }
123
    }
124
125
    private function getProfessionalRanking()
0 ignored issues
show
Unused Code introduced by
The method getProfessionalRanking() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
126
    {
127
        $professionalRankList = [];
128
        $verifiedUsers = DB::table("users")->select("professional_rate","id as uid","avatar","name")->get()->all();
129
        $rankIter = 0;
130
        foreach($verifiedUsers as $user) {
131
            $rankVal = $user['professional_rate'];
132
            $rankTitle = $this->getProfessionalTitle($rankVal);
133
            $titleColor = self::getProfessionalColor($rankTitle);
134
            $professionalRankList[$rankIter++] = [
135
                "name"=>$user["name"],
136
                "uid"=>$user["uid"],
137
                "avatar"=>$user["avatar"],
138
                "professionalRate"=>$user["professional_rate"],
139
                "rankTitle"=>$rankTitle,
140
                "titleColor"=>$titleColor
141
            ];
142
        }
143
        return $rankList;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $rankList seems to be never defined.
Loading history...
144
    }
145
146
    private function procRankingPer()
147
    {
148
        $totUsers=DB::table("submission")->where(["verdict"=>"Accepted"])->select(DB::raw("count(distinct uid) as res"))->get()->first()["res"];
149
        if ($totUsers>0) {
150
            $tot=0;
151
            $cur=0;
152
            foreach ($this->casualRankingPer as $c) {
153
                $tot+=$c;
154
            }
155
            foreach ($this->casualRankingPer as &$c) {
156
                $c=round($c*$totUsers/$tot);
157
                $cur+=$c;
158
                $c=$cur;
159
            }
160
            $c=$totUsers;
161
            unset($c);
162
        }
163
    }
164
165
    private function getRankTitle($rankVal)
166
    {
167
        foreach($this->casualRankingPer as $title=>$c){
168
            if($rankVal<=$c) return $title;
169
        }
170
        return Arr::last($this->casualRankingPer);
171
    }
172
173
    private function getProfessionalTitle($rankVal)
174
    {
175
        foreach($this->professionalRankingPer as $title=>$point) {
176
            if($rankVal >= $point) return $title;
177
        }
178
        return Arr::last($this->professionalRankingPer);
179
    }
180
}
181