Passed
Push — master ( 1d6b7a...19b4ee )
by John
06:00
created

ContestModel::contestRank()   F

Complexity

Conditions 19
Paths 6

Size

Total Lines 127
Code Lines 99

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 19
eloc 99
nc 6
nop 2
dl 0
loc 127
rs 3.6351
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace App\Models;
3
use GrahamCampbell\Markdown\Facades\Markdown;
4
use Illuminate\Database\Eloquent\Model;
5
use Illuminate\Support\Facades\DB;
6
use Auth;
7
class ContestModel extends Model
8
{
9
    protected $tableName='contest';
10
    protected $table='contest';
11
    protected $primaryKey = 'cid';
12
    const DELETED_AT=null;
13
    const UPDATED_AT=null;
14
    const CREATED_AT=null;
15
    public $rule=["Unknown", "ICPC", "OI", "Custom ICPC", "Custom OI"];
16
    public function calcLength($a, $b)
17
    {
18
        $s=strtotime($b)-strtotime($a);
19
        $h=intval($s / 3600);
20
        $m=round(($s-$h * 3600) / 60);
21
        if ($m==60) {
22
            $h++;
23
            $m=0;
24
        }
25
        if ($m==0 && $h==0) {
26
            $text="$s Seconds";
27
        } elseif ($m==0) {
28
            $text="$h Hours";
29
        } elseif ($h==0) {
30
            $text="$m Minutes";
31
        } else {
32
            $text="$h Hours $m Minutes";
33
        }
34
        return $text;
35
    }
36
    public function canViewContest($cid, $uid)
37
    {
38
        $contest_detail=DB::table($this->tableName)->where([
39
            "cid"=>$cid
40
        ])->first();
41
        if ($contest_detail["public"]==1) {
42
            return $contest_detail;
43
        } else {
44
            // group contest
45
            if ($uid==0) {
46
                return [];
47
            }
48
            $group_info=DB::table("group_member")->where([
49
                "uid"=>$uid,
50
                "gid"=>$contest_detail['gid'],
51
                ["role", ">", 0]
52
            ])->first();
53
            return empty($group_info) ? [] : $contest_detail;
54
        }
55
    }
56
    public function basic($cid)
57
    {
58
        return DB::table($this->tableName)->where([
59
            "cid"=>$cid
60
        ])->first();
61
    }
62
    public function detail($cid, $uid=0)
63
    {
64
        $contest_clearance=$this->judgeOutSideClearance($cid, $uid);
65
        $contest_detail=$this->basic($cid);
66
        if ($contest_clearance==0) {
67
            return [
68
                "ret"=>1000,
69
                "desc"=>"You have no right to view this contest.",
70
                "data"=>null
71
            ];
72
        } else {
73
            $contest_detail["rule_parsed"]=$this->rule[$contest_detail["rule"]];
74
            $contest_detail["date_parsed"]=[
75
                "date"=>date_format(date_create($contest_detail["begin_time"]), 'j'),
76
                "month_year"=>date_format(date_create($contest_detail["begin_time"]), 'M, Y'),
77
            ];
78
            $contest_detail["length"]=$this->calcLength($contest_detail["begin_time"], $contest_detail["end_time"]);
79
            $contest_detail["description_parsed"]=clean(Markdown::convertToHtml($contest_detail["description"]));
80
            $contest_detail["group_info"]=DB::table("group")->where(["gid"=>$contest_detail["gid"]])->first();
81
            $contest_detail["problem_count"]=DB::table("contest_problem")->where(["cid"=>$cid])->count();
82
            return [
83
                "ret"=>200,
84
                "desc"=>"succeed",
85
                "data"=>[
86
                    "contest_detail"=>$contest_detail
87
                ]
88
            ];
89
        }
90
    }
91
    public function gid($cid)
92
    {
93
        return DB::table($this->tableName)->where([
94
            "cid"=>$cid
95
        ])->first()["gid"];
96
    }
97
    public function grantAccess($uid, $cid, $audit=0)
98
    {
99
        return DB::table('contest_participant')->insert([
100
            "cid"=>$cid,
101
            "uid"=>$uid,
102
            "audit"=>$audit
103
        ]);
104
    }
105
    public function listByGroup($gid)
106
    {
107
        $contest_list=DB::table($this->tableName)->where([
108
            "gid"=>$gid
109
        ])->orderBy('begin_time', 'desc')->get()->all();
110
        foreach ($contest_list as &$c) {
111
            $c["rule_parsed"]=$this->rule[$c["rule"]];
112
            $c["date_parsed"]=[
113
                "date"=>date_format(date_create($c["begin_time"]), 'j'),
114
                "month_year"=>date_format(date_create($c["begin_time"]), 'M, Y'),
115
            ];
116
            $c["length"]=$this->calcLength($c["begin_time"], $c["end_time"]);
117
        }
118
        return $contest_list;
119
    }
120
    public function rule($cid)
121
    {
122
        return DB::table($this->tableName)->where([
123
            "cid"=>$cid
124
        ])->first()["rule"];
125
    }
126
    public function list()
127
    {
128
        $paginator=DB::table($this->tableName)->where([
129
            "public"=>1,
130
            "audit_status"=>1
131
        ])->orderBy('begin_time', 'desc')->paginate(10);
132
        $contest_list=$paginator->all();
133
        foreach ($contest_list as &$c) {
134
            $c["rule_parsed"]=$this->rule[$c["rule"]];
135
            $c["date_parsed"]=[
136
                "date"=>date_format(date_create($c["begin_time"]), 'j'),
137
                "month_year"=>date_format(date_create($c["begin_time"]), 'M, Y'),
138
            ];
139
            $c["length"]=$this->calcLength($c["begin_time"], $c["end_time"]);
140
        }
141
        return [
142
            'contents' => $contest_list,
143
            'paginator' => $paginator
144
        ];
145
    }
146
    public function featured()
147
    {
148
        $featured=DB::table($this->tableName)->where([
149
            "public"=>1,
150
            "audit_status"=>1,
151
            "featured"=>1
152
        ])->orderBy('begin_time', 'desc')->first();
153
        if (!empty($featured)) {
154
            $featured["rule_parsed"]=$this->rule[$featured["rule"]];
155
            $featured["date_parsed"]=[
156
                "date"=>date_format(date_create($featured["begin_time"]), 'j'),
157
                "month_year"=>date_format(date_create($featured["begin_time"]), 'M, Y'),
158
            ];
159
            $featured["length"]=$this->calcLength($featured["begin_time"], $featured["end_time"]);
160
            return $featured;
161
        } else {
162
            return null;
163
        }
164
    }
165
    public function remainingTime($cid)
166
    {
167
        $end_time=DB::table($this->tableName)->where([
168
            "cid"=>$cid
169
        ])->select("end_time")->first()["end_time"];
170
        $end_time=strtotime($end_time);
171
        $cur_time=time();
172
        return $end_time-$cur_time;
173
    }
174
    public function intToChr($index, $start=65)
175
    {
176
        $str='';
177
        if (floor($index / 26)>0) {
178
            $str.=$this->intToChr(floor($index / 26)-1);
179
        }
180
        return $str.chr($index % 26+$start);
181
    }
182
    public function contestProblems($cid, $uid)
183
    {
184
        $submissionModel=new SubmissionModel();
185
        $contest_rule=$this->contestRule($cid);
186
        $problemSet=DB::table("contest_problem")->join("problem", "contest_problem.pid", "=", "problem.pid")->where([
187
            "cid"=>$cid
188
        ])->orderBy('ncode', 'asc')->select("ncode", "alias", "contest_problem.pid as pid", "title")->get()->all();
189
        $frozen_time=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
190
        $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
0 ignored issues
show
Unused Code introduced by
The assignment to $end_time is dead and can be removed.
Loading history...
191
        foreach ($problemSet as &$p) {
192
            if ($contest_rule==1) {
193
                $prob_stat=DB::table("submission")->select(
194
                    DB::raw("count(sid) as submission_count"),
195
                    DB::raw("sum(verdict='accepted') as passed_count"),
196
                    DB::raw("sum(verdict='accepted')/count(sid)*100 as ac_rate")
197
                )->where([
198
                    "pid"=>$p["pid"],
199
                    "cid"=>$cid
200
                ])->where("submission_date", "<", $frozen_time)->first();
201
                if ($prob_stat["submission_count"]==0) {
202
                    $p["submission_count"]=0;
203
                    $p["passed_count"]=0;
204
                    $p["ac_rate"]=0;
205
                } else {
206
                    $p["submission_count"]=$prob_stat["submission_count"];
207
                    $p["passed_count"]=$prob_stat["passed_count"];
208
                    $p["ac_rate"]=round($prob_stat["ac_rate"], 2);
209
                }
210
            } else {
211
                $prob_stat=$this->contestProblemInfoOI($cid, $p["pid"], $uid);
212
                $p["points"]=$prob_stat["points"];
213
                $p["score"]=empty($prob_stat["score_parsed"]) ? 0 : $prob_stat["score_parsed"];
214
            }
215
            $prob_status=$submissionModel->getProblemStatus($p["pid"], $uid, $cid);
216
            if (empty($prob_status)) {
217
                $p["prob_status"]=[
218
                    "icon"=>"checkbox-blank-circle-outline",
219
                    "color"=>"wemd-grey-text"
220
                ];
221
            } else {
222
                $p["prob_status"]=[
223
                    "icon"=>$prob_status["verdict"]=="Accepted" ? "checkbox-blank-circle" : "cisco-webex",
224
                    "color"=>$prob_status["color"]
225
                ];
226
            }
227
        }
228
        return $problemSet;
229
    }
230
    public function getPid($cid, $ncode)
231
    {
232
        return DB::table("contest_problem")->where([
233
            "cid"=>$cid,
234
            "ncode"=>$ncode
235
        ])->select("contest_problem.pid")->first()["pid"];
236
    }
237
    public function getPcode($cid, $ncode)
0 ignored issues
show
Unused Code introduced by
The parameter $ncode is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

237
    public function getPcode($cid, /** @scrutinizer ignore-unused */ $ncode)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
238
    {
239
        return DB::table("problem")->where([
240
            "cid"=>$cid
241
        ])->select("contest_problem.pid")->first()["pcode"];
242
    }
243
    public function getCustomInfo($cid)
244
    {
245
        $basic_info=DB::table($this->tableName)->where([
246
            "cid"=>$cid
247
        ])->select("verified", "custom_icon", "custom_title")->first();
248
        return $basic_info["verified"] ? ((is_null($basic_info["custom_icon"]) && is_null($basic_info["custom_title"])) ?null:$basic_info) : null;
249
    }
250
    public function formatTime($seconds)
251
    {
252
        if ($seconds>3600) {
253
            $hours=intval($seconds / 3600);
254
            $minutes=$seconds % 3600;
255
            $time=$hours.":".gmstrftime('%M:%S', $minutes);
256
        } else {
257
            $time=gmstrftime('%H:%M:%S', $seconds);
258
        }
259
        return $time;
260
    }
261
    public function contestProblemInfoOI($cid, $pid, $uid)
262
    {
263
        $ret=[
264
            "color"=>"",
265
            "score"=>null,
266
            "score_parsed"=>"",
267
            "solved"=>0,
268
            "points"=>DB::table("contest_problem")->where([
269
                "pid"=>$pid,
270
                "cid"=>$cid
271
            ])->first()["points"]
272
        ];
273
        $frozen_time=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
274
        $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
0 ignored issues
show
Unused Code introduced by
The assignment to $end_time is dead and can be removed.
Loading history...
275
        $highest_record=DB::table("submission")->where([
276
            "cid"=>$cid,
277
            "pid"=>$pid,
278
            "uid"=>$uid
279
        ])->where("submission_date", "<", $frozen_time)->orderBy('score', 'desc')->first();
280
        if (!empty($highest_record)) {
281
            $ret["score"]=$highest_record["score"];
282
            $tot_score=DB::table("problem")->where([
283
                "pid"=>$pid
284
            ])->first()["tot_score"];
285
            $ret["color"]=($ret["score"]==$tot_score) ? "wemd-teal-text" : "wemd-green-text";
286
            $ret["solved"]=($ret["score"]==$tot_score) ? 1 : 0;
287
            $ret["score_parsed"]=$ret["score"] / $tot_score * ($ret["points"]);
288
        }
289
        return $ret;
290
    }
291
    public function isFrozen($cid)
292
    {
293
        $frozen=DB::table("contest")->where(["cid"=>$cid])->select("froze_length", DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first();
294
        if (empty($frozen["froze_length"])) {
295
            return false;
296
        } else {
297
            return time()>$frozen["frozen_time"];
298
        }
299
    }
300
    public function contestProblemInfoACM($cid, $pid, $uid)
301
    {
302
        $ret=[
303
            "color"=>"",
304
            "solved"=>0,
305
            "solved_time"=>"",
306
            "solved_time_parsed"=>"",
307
            "wrong_doings"=>0,
308
            "color"=>"",
309
        ];
310
        $frozen_time=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
311
        $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
0 ignored issues
show
Unused Code introduced by
The assignment to $end_time is dead and can be removed.
Loading history...
312
        $ac_record=DB::table("submission")->where([
313
            "cid"=>$cid,
314
            "pid"=>$pid,
315
            "uid"=>$uid,
316
            "verdict"=>"Accepted"
317
        ])->where("submission_date", "<", $frozen_time)->orderBy('submission_date', 'asc')->first();
318
        if (!empty($ac_record)) {
319
            $ret["solved"]=1;
320
            $ret["solved_time"]=$ac_record["submission_date"]-strtotime(DB::table($this->tableName)->where([
321
                "cid"=>$cid
322
            ])->first()["begin_time"]);
323
            $ret["solved_time_parsed"]=$this->formatTime($ret["solved_time"]);
324
            $ret["wrong_doings"]=DB::table("submission")->where([
325
                "cid"=>$cid,
326
                "pid"=>$pid,
327
                "uid"=>$uid
328
            ])->whereIn('verdict', [
329
                'Runtime Error',
330
                'Wrong Answer',
331
                'Time Limit Exceed',
332
                'Real Time Limit Exceed',
333
                'Memory Limit Exceed',
334
                'Presentation Error',
335
                'Output Limit Exceeded'
336
            ])->where("submission_date", "<", $ac_record["submission_date"])->count();
337
            $others_first=DB::table("submission")->where([
338
                "cid"=>$cid,
339
                "pid"=>$pid,
340
                "verdict"=>"Accepted"
341
            ])->where("submission_date", "<", $ac_record["submission_date"])->count();
342
            $ret["color"]=$others_first ? "wemd-green-text" : "wemd-teal-text";
343
        } else {
344
            $ret["wrong_doings"]=DB::table("submission")->where([
345
                "cid"=>$cid,
346
                "pid"=>$pid,
347
                "uid"=>$uid
348
            ])->whereIn('verdict', [
349
                'Runtime Error',
350
                'Wrong Answer',
351
                'Time Limit Exceed',
352
                'Real Time Limit Exceed',
353
                'Memory Limit Exceed',
354
                'Presentation Error',
355
                'Output Limit Exceeded'
356
            ])->where("submission_date", "<", $frozen_time)->count();
357
        }
358
        return $ret;
359
    }
360
    public function contestRank($cid, $uid)
361
    {
362
        // [ToDo] If the current user's in the organizer group show nick name
363
        // [ToDo] The participants determination
364
        // [ToDo] Frozen Time
365
        // [ToDo] Performance Opt
366
        // [Todo] Ajaxization - Should have done in controller
367
        // [Todo] Authorization ( Public / Private ) - Should have done in controller
368
        $ret=[];
369
        $contest_info=DB::table("contest")->where("cid", $cid)->first();
370
        $user_in_group=!empty(DB::table("group_member")->where([
371
            "uid" => $uid,
372
            "gid" => $contest_info["gid"]
373
        ])->where("role", ">", 0)->first());
374
        if ($contest_info["registration"]) {
375
            $submissionUsers=DB::table("contest_participant")->where([
376
                "cid"=>$cid,
377
                "audit"=>1
378
            ])->select('uid')->get()->all();
379
        } else {
380
            // Those who submitted are participants
381
            $submissionUsers=DB::table("submission")->where([
382
                "cid"=>$cid
383
            ])->select('uid')->groupBy('uid')->get()->all();
384
        }
385
        $problemSet=DB::table("contest_problem")->join("problem", "contest_problem.pid", "=", "problem.pid")->where([
386
            "cid"=>$cid
387
        ])->orderBy('ncode', 'asc')->select("ncode", "alias", "contest_problem.pid as pid", "title")->get()->all();
388
        if ($contest_info["rule"]==1) {
389
            // ACM/ICPC Mode
390
            foreach ($submissionUsers as $s) {
391
                $prob_detail=[];
392
                $totPen=0;
393
                $totScore=0;
394
                foreach ($problemSet as $p) {
395
                    $prob_stat=$this->contestProblemInfoACM($cid, $p["pid"], $s["uid"]);
396
                    $prob_detail[]=[
397
                        "ncode"=>$p["ncode"],
398
                        "pid"=>$p["pid"],
399
                        "color"=>$prob_stat["color"],
400
                        "wrong_doings"=>$prob_stat["wrong_doings"],
401
                        "solved_time_parsed"=>$prob_stat["solved_time_parsed"]
402
                    ];
403
                    if ($prob_stat["solved"]) {
404
                        $totPen+=$prob_stat["wrong_doings"] * 20;
405
                        $totPen+=$prob_stat["solved_time"] / 60;
406
                        $totScore+=$prob_stat["solved"];
407
                    }
408
                }
409
                $ret[]=[
410
                    "uid" => $s["uid"],
411
                    "name" => DB::table("users")->where([
412
                        "id"=>$s["uid"]
413
                    ])->first()["name"],
414
                    "nick_name" => $user_in_group ? DB::table("group_member")->where([
415
                        "uid" => $s["uid"],
416
                        "gid" => $contest_info["gid"]
417
                    ])->where("role", ">", 0)->first()["nick_name"] : "",
418
                    "score" => $totScore,
419
                    "penalty" => $totPen,
420
                    "problem_detail" => $prob_detail
421
                ];
422
            }
423
            usort($ret, function ($a, $b) {
424
                if ($a["score"]==$b["score"]) {
425
                    if ($a["penalty"]==$b["penalty"]) {
426
                        return 0;
427
                    } elseif (($a["penalty"]>$b["penalty"])) {
428
                        return 1;
429
                    } else {
430
                        return -1;
431
                    }
432
                } elseif ($a["score"]>$b["score"]) {
433
                    return -1;
434
                } else {
435
                    return 1;
436
                }
437
            });
438
        } elseif ($contest_info["rule"]==2) {
439
            // OI Mode
440
            foreach ($submissionUsers as $s) {
441
                $prob_detail=[];
442
                $totScore=0;
443
                $totSolved=0;
444
                foreach ($problemSet as $p) {
445
                    $prob_stat=$this->contestProblemInfoOI($cid, $p["pid"], $s["uid"]);
446
                    $prob_detail[]=[
447
                        "ncode"=>$p["ncode"],
448
                        "pid"=>$p["pid"],
449
                        "color"=>$prob_stat["color"],
450
                        "score"=>$prob_stat["score"],
451
                        "score_parsed"=>$prob_stat["score_parsed"]
452
                    ];
453
                    $totSolved+=$prob_stat["solved"];
454
                    $totScore+=intval($prob_stat["score_parsed"]);
455
                }
456
                $ret[]=[
457
                    "uid" => $s["uid"],
458
                    "name" => DB::table("users")->where([
459
                        "id"=>$s["uid"]
460
                    ])->first()["name"],
461
                    "nick_name" => $user_in_group ? DB::table("group_member")->where([
462
                        "uid" => $s["uid"],
463
                        "gid" => $contest_info["gid"]
464
                    ])->where("role", ">", 0)->first()["nick_name"] : "",
465
                    "score" => $totScore,
466
                    "solved" => $totSolved,
467
                    "problem_detail" => $prob_detail
468
                ];
469
            }
470
            usort($ret, function ($a, $b) {
471
                if ($a["score"]==$b["score"]) {
472
                    if ($a["solved"]==$b["solved"]) {
473
                        return 0;
474
                    } elseif (($a["solved"]<$b["solved"])) {
475
                        return 1;
476
                    } else {
477
                        return -1;
478
                    }
479
                } elseif ($a["score"]>$b["score"]) {
480
                    return -1;
481
                } else {
482
                    return 1;
483
                }
484
            });
485
        }
486
        return $ret;
487
    }
488
    public function getRejudgeQueue($cid)
489
    {
490
        $problemModel=new ProblemModel();
491
        $submissionModel=new SubmissionModel();
0 ignored issues
show
Unused Code introduced by
The assignment to $submissionModel is dead and can be removed.
Loading history...
492
        $compilerModel=new CompilerModel();
493
        $tempQueue=DB::table("submission")->where([
494
            "cid"=>$cid
495
        ])->whereIn('verdict', [
496
            'Runtime Error',
497
            'Wrong Answer',
498
            'Time Limit Exceed',
499
            'Real Time Limit Exceed',
500
            'Memory Limit Exceed',
501
            'Presentation Error',
502
            'Output Limit Exceeded'
503
        ])->get()->all();
504
        foreach ($tempQueue as &$t) {
505
            $lang=$compilerModel->detail($t["coid"]);
506
            $probBasic=$problemModel->basic($t["pid"]);
507
            $t["oj"]=$problemModel->ocode($t["pid"]);
508
            $t["lang"]=$lang['lcode'];
509
            $t["cid"]=$probBasic["contest_id"];
510
            $t["iid"]=$probBasic["index_id"];
511
            $t["pcode"]=$probBasic["pcode"];
512
            $t["contest"]=$cid;
513
        }
514
        return $tempQueue;
515
    }
516
    public function getClarificationList($cid)
517
    {
518
        return DB::table("contest_clarification")->where([
519
            "cid"=>$cid
520
        ])->where(function ($query) {
521
            $query->where([
522
                "public"=>1
523
            ])->orWhere([
524
                "uid" => Auth::user()->id
525
            ]);
526
        })->orderBy('create_time', 'desc')->get()->all();
527
    }
528
    public function fetchClarification($cid)
529
    {
530
        return DB::table("contest_clarification")->where([
531
            "cid"=>$cid,
532
            "type"=>0,
533
            "public"=>1
534
        ])->whereBetween(
535
            'create_time', [
536
                date("Y-m-d H:i:s", time()-59),
537
                date("Y-m-d H:i:s")
538
            ]
539
        )->first();
540
    }
541
    public function getlatestClarification($cid)
542
    {
543
        return DB::table("contest_clarification")->where([
544
            "cid"=>$cid,
545
            "type"=>0,
546
            "public"=>1
547
        ])->orderBy('create_time', 'desc')->first();
548
    }
549
    public function getClarificationDetail($ccid)
550
    {
551
        return DB::table("contest_clarification")->where([
552
            "ccid"=>$ccid,
553
            "public"=>1
554
        ])->first();
555
    }
556
    public function requestClarification($cid, $title, $content, $uid)
557
    {
558
        return DB::table("contest_clarification")->insertGetId([
559
            "cid"=>$cid,
560
            "type"=>1,
561
            "title"=>$title,
562
            "content"=>$content,
563
            "public"=>"0",
564
            "uid"=>$uid,
565
            "create_time"=>date("Y-m-d H:i:s")
566
        ]);
567
    }
568
    public function isContestEnded($cid)
569
    {
570
        return DB::table("contest")->where("cid", $cid)->where("end_time", "<", date("Y-m-d H:i:s"))->count();
571
    }
572
    public function formatSubmitTime($date)
573
    {
574
        $periods=["second", "minute", "hour", "day", "week", "month", "year", "decade"];
575
        $lengths=["60", "60", "24", "7", "4.35", "12", "10"];
576
        $now=time();
577
        $unix_date=strtotime($date);
578
        if (empty($unix_date)) {
579
            return "Bad date";
580
        }
581
        if ($now>$unix_date) {
582
            $difference=$now-$unix_date;
583
            $tense="ago";
584
        } else {
585
            $difference=$unix_date-$now;
586
            $tense="from now";
587
        }
588
        for ($j=0; $difference>=$lengths[$j] && $j<count($lengths)-1; $j++) {
589
            $difference/=$lengths[$j];
590
        }
591
        $difference=round($difference);
592
        if ($difference!=1) {
593
            $periods[$j].="s";
594
        }
595
        return "$difference $periods[$j] {$tense}";
596
    }
597
    public function formatAbsTime($sec)
598
    {
599
        $periods=["second", "minute", "hour", "day", "week", "month", "year", "decade"];
600
        $lengths=["60", "60", "24", "7", "4.35", "12", "10"];
601
        $difference=$sec;
602
        for ($j=0; $difference>=$lengths[$j] && $j<count($lengths)-1; $j++) {
603
            $difference/=$lengths[$j];
604
        }
605
        $difference=round($difference);
606
        if ($difference!=1) {
607
            $periods[$j].="s";
608
        }
609
        return "$difference $periods[$j]";
610
    }
611
    public function frozenTime($cid)
612
    {
613
        $basicInfo=$this->basic($cid);
614
        return $this->formatAbsTime($basicInfo["froze_length"]);
615
    }
616
    public function getContestRecord($cid)
617
    {
618
        $basicInfo=$this->basic($cid);
619
        $problemSet_temp=DB::table("contest_problem")->join("problem", "contest_problem.pid", "=", "problem.pid")->where([
620
            "cid"=>$cid
621
        ])->orderBy('ncode', 'asc')->select("ncode", "alias", "contest_problem.pid as pid", "title", "points", "tot_score")->get()->all();
622
        $problemSet=[];
623
        foreach ($problemSet_temp as $p) {
624
            $problemSet[(string) $p["pid"]]=["ncode"=>$p["ncode"], "points"=>$p["points"], "tot_score"=>$p["tot_score"]];
625
        }
626
        $frozen_time=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
627
        $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
628
        if ($basicInfo["status_visibility"]==2) {
629
            // View all
630
            $paginator=DB::table("submission")->where([
631
                'cid'=>$cid
632
            ])->where(
633
                "submission_date",
634
                "<",
635
                $end_time
636
            )->join(
637
                "users",
638
                "users.id",
639
                "=",
640
                "submission.uid"
641
            )->where(function ($query) use ($frozen_time) {
642
                $query->where(
643
                    "submission_date",
644
                    "<",
645
                    $frozen_time
646
                )->orWhere(
647
                    'uid',
648
                    Auth::user()->id
649
                );
650
            })->select(
651
                "sid",
652
                "uid",
653
                "pid",
654
                "name",
655
                "color",
656
                "verdict",
657
                "time",
658
                "memory",
659
                "language",
660
                "score",
661
                "submission_date"
662
            )->orderBy(
663
                'submission_date',
664
                'desc'
665
            )->paginate(50);
666
        } elseif ($basicInfo["status_visibility"]==1) {
667
            $paginator=DB::table("submission")->where([
668
                'cid'=>$cid,
669
                'uid'=>Auth::user()->id
670
            ])->where(
671
                "submission_date",
672
                "<",
673
                $end_time
674
            )->join(
675
                "users",
676
                "users.id",
677
                "=",
678
                "submission.uid"
679
            )->select(
680
                "sid",
681
                "uid",
682
                "pid",
683
                "name",
684
                "color",
685
                "verdict",
686
                "time",
687
                "memory",
688
                "language",
689
                "score",
690
                "submission_date"
691
            )->orderBy(
692
                'submission_date',
693
                'desc'
694
            )->paginate(50);
695
        } else {
696
            return [
697
                "paginator"=>null,
698
                "records"=>[]
699
            ];
700
        }
701
        $records=$paginator->all();
702
        foreach ($records as &$r) {
703
            $r["submission_date_parsed"]=$this->formatSubmitTime(date('Y-m-d H:i:s', $r["submission_date"]));
704
            $r["submission_date"]=date('Y-m-d H:i:s', $r["submission_date"]);
705
            $r["nick_name"]="";
706
            $r["ncode"]=$problemSet[(string) $r["pid"]]["ncode"];
707
            if ($r["verdict"]=="Partially Accepted") {
708
                $score_parsed=round($r["score"] / $problemSet[(string) $r["pid"]]["tot_score"] * $problemSet[(string) $r["pid"]]["points"], 1);
709
                $r["verdict"].=" ($score_parsed)";
710
            }
711
        }
712
        return [
713
            "paginator"=>$paginator,
714
            "records"=>$records
715
        ];
716
    }
717
    public function registration($cid, $uid=0)
718
    {
719
        if ($uid==0) {
720
            return [];
721
        }
722
        return DB::table("contest_participant")->where([
723
            "cid" => $cid,
724
            "uid" => $uid,
725
            "audit" => 1
726
        ])->first();
727
    }
728
    public function judgeClearance($cid, $uid=0)
729
    {
730
        if ($uid==0) {
731
            return 0;
732
        }
733
        $contest_started=DB::table("contest")->where("cid", $cid)->where("begin_time", "<", date("Y-m-d H:i:s"))->count();
734
        $contest_ended=DB::table("contest")->where("cid", $cid)->where("end_time", "<", date("Y-m-d H:i:s"))->count();
735
        $contest_info=DB::table("contest")->where("cid", $cid)->first();
736
        if (!$contest_started) {
737
            // not started or do not exist
738
            return 0;
739
        }
740
        if ($contest_info["public"]) {
741
            //public
742
            if ($contest_ended) {
743
                return 1;
744
            } else {
745
                if ($contest_info["registration"]) {
746
                    // check if uid in registration, temp return 3
747
                    $isParticipant=DB::table("contest_participant")->where([
748
                        "cid" => $cid,
749
                        "uid" => $uid,
750
                        "audit" => 1
751
                    ])->count();
752
                    if ($isParticipant) {
753
                        return 2;
754
                    } else {
755
                        return 0;
756
                    }
757
                } else {
758
                    return 2;
759
                }
760
            }
761
        } else {
762
            //private
763
            $isMember=DB::table("group_member")->where([
764
                "gid"=> $contest_info["gid"],
765
                "uid"=> $uid
766
            ])->where("role", ">", 0)->count();
767
            if (!$isMember) {
768
                return 0;
769
            } else {
770
                if ($contest_info["registration"]) {
771
                    // check if uid in registration, temp return 3
772
                    $isParticipant=DB::table("contest_participant")->where([
773
                        "cid" => $cid,
774
                        "uid" => $uid,
775
                        "audit" => 1
776
                    ])->count();
777
                    if ($isParticipant) {
778
                        return 2;
779
                    } else {
780
                        return 0;
781
                    }
782
                } else {
783
                    return 2;
784
                }
785
            }
786
        }
787
    }
788
    public function judgeOutsideClearance($cid, $uid=0)
789
    {
790
        $contest_info=DB::table("contest")->where("cid", $cid)->first();
791
        if (empty($contest_info)) {
792
            return 0;
793
        }
794
        if ($contest_info["public"]) {
795
            return 1;
796
        } else {
797
            if ($uid==0) {
798
                return 0;
799
            }
800
            return DB::table("group_member")->where([
801
                "gid"=> $contest_info["gid"],
802
                "uid"=> $uid
803
            ])->where("role", ">", 0)->count() ? 1 : 0;
804
        }
805
    }
806
    public function contestName($cid)
807
    {
808
        return DB::table("contest")->where("cid", $cid)->select("name")->first()["name"];
809
    }
810
    public function contestRule($cid)
811
    {
812
        return DB::table("contest")->where("cid", $cid)->select("rule")->first()["rule"];
813
    }
814
    public function arrangeContest($gid, $config, $problems)
815
    {
816
        DB::transaction(function () use ($gid, $config, $problems) {
817
            $cid=DB::table($this->tableName)->insertGetId([
818
                "gid"=>$gid,
819
                "name"=>$config["name"],
820
                "verified"=>0, //todo
821
                "rated"=>0,
822
                "anticheated"=>0,
823
                "featured"=>0,
824
                "description"=>$config["description"],
825
                "rule"=>1, //todo
826
                "begin_time"=>$config["begin_time"],
827
                "end_time"=>$config["end_time"],
828
                "public"=>0, //todo
829
                "registration"=>0, //todo
830
                "registration_due"=>null, //todo
831
                "registant_type"=>0, //todo
832
                "froze_length"=>0, //todo
833
                "status_visibility"=>2, //todo
834
                "create_time"=>date("Y-m-d H:i:s"),
835
                "audit_status"=>1                       //todo
836
            ]);
837
            foreach ($problems as $p) {
838
                $pid=DB::table("problem")->where(["pcode"=>$p["pcode"]])->select("pid")->first()["pid"];
839
                DB::table("contest_problem")->insert([
840
                    "cid"=>$cid,
841
                    "number"=>$p["number"],
842
                    "ncode"=>$this->intToChr($p["number"]-1),
843
                    "pid"=>$pid,
844
                    "alias"=>"",
845
                    "points"=>$p["points"]
846
                ]);
847
            }
848
        }, 5);
849
    }
850
}
851