Passed
Push — master ( ffef04...f14232 )
by John
03:37
created

ContestModel::contestProblems()   B

Complexity

Conditions 7
Paths 13

Size

Total Lines 53
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 39
nc 13
nop 2
dl 0
loc 53
rs 8.3626
c 0
b 0
f 0

How to fix   Long Method   

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

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