Passed
Push — master ( bb1f48...f98417 )
by John
03:26
created

ContestModel::getPcode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
rs 10
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 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 getClarificationList($cid)
534
    {
535
        return DB::table("contest_clarification")->where([
536
            "cid"=>$cid,
537
            "public"=>1
538
        ])->orderBy('create_time', 'desc')->get()->all();
539
    }
540
541
    public function fetchClarification($cid)
542
    {
543
        return DB::table("contest_clarification")->where([
544
            "cid"=>$cid,
545
            "type"=>0,
546
            "public"=>1
547
        ])->whereBetween(
548
            'create_time', [
549
                date("Y-m-d H:i:s",time()-59),
550
                date("Y-m-d H:i:s")
551
            ]
552
        )->first();
553
    }
554
555
    public function getlatestClarification($cid)
556
    {
557
        return DB::table("contest_clarification")->where([
558
            "cid"=>$cid,
559
            "type"=>0,
560
            "public"=>1
561
        ])->orderBy('create_time', 'desc')->first();
562
    }
563
564
    public function getClarificationDetail($ccid)
565
    {
566
        return DB::table("contest_clarification")->where([
567
            "ccid"=>$ccid,
568
            "public"=>1
569
        ])->first();
570
    }
571
572
    public function requestClarification($cid, $title, $content)
573
    {
574
        return DB::table("contest_clarification")->insertGetId([
575
            "cid"=>$cid,
576
            "title"=>$title,
577
            "content"=>$content
578
        ]);
579
    }
580
581
    public function isContestEnded($cid)
582
    {
583
        return DB::table("contest")->where("cid", $cid)->where("end_time", "<", date("Y-m-d H:i:s"))->count();
584
    }
585
586
    public function formatSubmitTime($date)
587
    {
588
        $periods=["second", "minute", "hour", "day", "week", "month", "year", "decade"];
589
        $lengths=["60", "60", "24", "7", "4.35", "12", "10"];
590
591
        $now=time();
592
        $unix_date=strtotime($date);
593
594
        if (empty($unix_date)) {
595
            return "Bad date";
596
        }
597
598
        if ($now>$unix_date) {
599
            $difference=$now-$unix_date;
600
            $tense="ago";
601
        } else {
602
            $difference=$unix_date-$now;
603
            $tense="from now";
604
        }
605
606
        for ($j=0; $difference>=$lengths[$j] && $j<count($lengths)-1; $j++) {
607
            $difference/=$lengths[$j];
608
        }
609
610
        $difference=round($difference);
611
612
        if ($difference!=1) {
613
            $periods[$j].="s";
614
        }
615
616
        return "$difference $periods[$j] {$tense}";
617
    }
618
619
    public function formatAbsTime($sec)
620
    {
621
        $periods=["second", "minute", "hour", "day", "week", "month", "year", "decade"];
622
        $lengths=["60", "60", "24", "7", "4.35", "12", "10"];
623
624
625
        $difference=$sec;
626
627
        for ($j=0; $difference>=$lengths[$j] && $j<count($lengths)-1; $j++) {
628
            $difference/=$lengths[$j];
629
        }
630
631
        $difference=round($difference);
632
633
        if ($difference!=1) {
634
            $periods[$j].="s";
635
        }
636
637
        return "$difference $periods[$j]";
638
    }
639
640
    public function frozenTime($cid)
641
    {
642
        $basicInfo=$this->basic($cid);
643
        return $this->formatAbsTime($basicInfo["froze_length"]);
644
    }
645
646
647
    public function getContestRecord($cid)
648
    {
649
        $basicInfo=$this->basic($cid);
650
        $problemSet_temp=DB::table("contest_problem")->join("problem", "contest_problem.pid", "=", "problem.pid")->where([
651
            "cid"=>$cid
652
        ])->orderBy('ncode', 'asc')->select("ncode", "alias", "contest_problem.pid as pid", "title", "points", "tot_score")->get()->all();
653
        $problemSet=[];
654
        foreach ($problemSet_temp as $p) {
655
            $problemSet[(string) $p["pid"]]=["ncode"=>$p["ncode"], "points"=>$p["points"], "tot_score"=>$p["tot_score"]];
656
        }
657
658
        $frozen_time=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
659
        $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
660
661
        if ($basicInfo["status_visibility"]==2) {
662
            // View all
663
            $paginator=DB::table("submission")->where([
664
                'cid'=>$cid
665
            ])->where(
666
                "submission_date",
667
                "<",
668
                $end_time
669
            )->join(
670
                "users",
671
                "users.id",
672
                "=",
673
                "submission.uid"
674
            )->where(function($query) use ($frozen_time) {
675
                $query->where(
676
                    "submission_date",
677
                    "<",
678
                    $frozen_time
679
                )->orWhere(
680
                    'uid',
681
                    Auth::user()->id
682
                );
683
            })->select(
684
                "sid",
685
                "uid",
686
                "pid",
687
                "name",
688
                "color",
689
                "verdict",
690
                "time",
691
                "memory",
692
                "language",
693
                "score",
694
                "submission_date"
695
            )->orderBy(
696
                'submission_date',
697
                'desc'
698
            )->paginate(50);
699
        } elseif ($basicInfo["status_visibility"]==1) {
700
            $paginator=DB::table("submission")->where([
701
                'cid'=>$cid,
702
                'uid'=>Auth::user()->id
703
            ])->where(
704
                "submission_date",
705
                "<",
706
                $end_time
707
            )->join(
708
                "users",
709
                "users.id",
710
                "=",
711
                "submission.uid"
712
            )->select(
713
                "sid",
714
                "uid",
715
                "pid",
716
                "name",
717
                "color",
718
                "verdict",
719
                "time",
720
                "memory",
721
                "language",
722
                "score",
723
                "submission_date"
724
            )->orderBy(
725
                'submission_date',
726
                'desc'
727
            )->paginate(50);
728
        } else {
729
            return [
730
                "paginator"=>null,
731
                "records"=>[]
732
            ];
733
        }
734
735
        $records= $paginator->all();
736
        foreach ($records as &$r) {
737
            $r["submission_date_parsed"]=$this->formatSubmitTime(date('Y-m-d H:i:s', $r["submission_date"]));
738
            $r["submission_date"]=date('Y-m-d H:i:s', $r["submission_date"]);
739
            $r["nick_name"]="";
740
            $r["ncode"]=$problemSet[(string) $r["pid"]]["ncode"];
741
            if ($r["verdict"]=="Partially Accepted") {
742
                $score_parsed=round($r["score"] / $problemSet[(string) $r["pid"]]["tot_score"] * $problemSet[(string) $r["pid"]]["points"], 1);
743
                $r["verdict"].=" ($score_parsed)";
744
            }
745
        }
746
        return [
747
            "paginator"=>$paginator,
748
            "records"=>$records
749
        ];
750
    }
751
752
    public function judgeClearance($cid, $uid=0)
753
    {
754
        if ($uid==0) {
755
            return 0;
756
        }
757
758
        $contest_started=DB::table("contest")->where("cid", $cid)->where("begin_time", "<", date("Y-m-d H:i:s"))->count();
759
        $contest_ended=DB::table("contest")->where("cid", $cid)->where("end_time", "<", date("Y-m-d H:i:s"))->count();
760
        $contest_info=DB::table("contest")->where("cid", $cid)->first();
761
762
        if (!$contest_started) {
763
            // not started or do not exist
764
            return 0;
765
        }
766
767
        if ($contest_info["public"]) {
768
            //public
769
            if ($contest_ended) {
770
                return 1;
771
            } else {
772
                if ($contest_info["registration"]) {
773
                    // check if uid in registration, temp return 3
774
                    $isParticipant=DB::table("contest_participant")->where([
775
                        "cid" => $cid,
776
                        "uid" => $uid,
777
                        "audit" => 1
778
                    ])->count();
779
                    if ($isParticipant) {
780
                        return 2;
781
                    } else {
782
                        return 0;
783
                    }
784
                } else {
785
                    return 2;
786
                }
787
            }
788
        } else {
789
            //private
790
            $isMember=DB::table("group_member")->where([
791
                "gid"=> $contest_info["gid"],
792
                "uid"=> $uid
793
            ])->where("role", ">", 0)->count();
794
            if (!$isMember) {
795
                return 0;
796
            } else {
797
                if ($contest_info["registration"]) {
798
                    // check if uid in registration, temp return 3
799
                    $isParticipant=DB::table("contest_participant")->where([
800
                        "cid" => $cid,
801
                        "uid" => $uid,
802
                        "audit" => 1
803
                    ])->count();
804
                    if ($isParticipant) {
805
                        return 2;
806
                    } else {
807
                        return 0;
808
                    }
809
                } else {
810
                    return 2;
811
                }
812
            }
813
        }
814
    }
815
816
    public function judgeOutsideClearance($cid, $uid=0)
817
    {
818
        $contest_info=DB::table("contest")->where("cid", $cid)->first();
819
        if (empty($contest_info)) {
820
            return 0;
821
        }
822
        if ($contest_info["public"]) {
823
            return 1;
824
        } else {
825
            if ($uid==0) {
826
                return 0;
827
            }
828
            return DB::table("group_member")->where([
829
                "gid"=> $contest_info["gid"],
830
                "uid"=> $uid
831
            ])->where("role", ">", 0)->count() ? 1 : 0;
832
        }
833
    }
834
835
    public function contestName($cid)
836
    {
837
        return DB::table("contest")->where("cid", $cid)->select("name")->first()["name"];
838
    }
839
840
    public function contestRule($cid)
841
    {
842
        return DB::table("contest")->where("cid", $cid)->select("rule")->first()["rule"];
843
    }
844
845
    public function arrangeContest($gid, $config, $problems)
846
    {
847
        DB::transaction(function() use ($gid, $config, $problems) {
848
            $cid=DB::table($this->tableName)->insertGetId([
849
                "gid"=>$gid,
850
                "name"=>$config["name"],
851
                "verified"=>0, //todo
852
                "rated"=>0,
853
                "anticheated"=>0,
854
                "featured"=>0,
855
                "description"=>$config["description"],
856
                "rule"=>1, //todo
857
                "begin_time"=>$config["begin_time"],
858
                "end_time"=>$config["end_time"],
859
                "public"=>0, //todo
860
                "registration"=>0, //todo
861
                "registration_due"=>null, //todo
862
                "registant_type"=>0, //todo
863
                "froze_length"=>0, //todo
864
                "status_visibility"=>2, //todo
865
                "create_time"=>date("Y-m-d H:i:s"),
866
                "audit_status"=>1                       //todo
867
            ]);
868
869
            foreach ($problems as $p) {
870
                $pid=DB::table("problem")->where(["pcode"=>$p["pcode"]])->select("pid")->first()["pid"];
871
                DB::table("contest_problem")->insert([
872
                    "cid"=>$cid,
873
                    "number"=>$p["number"],
874
                    "ncode"=>$this->intToChr($p["number"]-1),
875
                    "pid"=>$pid,
876
                    "alias"=>"",
877
                    "points"=>0
878
                ]);
879
            }
880
        }, 5);
881
    }
882
}
883