ContestModel::contestRule()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace App\Models;
4
5
use App\Models\Eloquent\Contest;
6
use GrahamCampbell\Markdown\Facades\Markdown;
7
use App\Models\Submission\SubmissionModel;
8
use App\Models\Eloquent\User;
9
use Illuminate\Database\Eloquent\Model;
10
use Illuminate\Support\Facades\DB;
11
use App\Models\Rating\RatingCalculator;
12
use Illuminate\Support\Facades\Storage;
13
use Illuminate\Contracts\Cache\LockTimeoutException;
14
use Auth;
15
use Cache;
16
use Log;
17
18
class ContestModel extends Model
19
{
20
    protected $tableName='contest';
21
    protected $table='contest';
22
    protected $primaryKey='cid';
23
    const DELETED_AT=null;
24
    const UPDATED_AT=null;
25
    const CREATED_AT=null;
26
27
    public $rule=["Unknown", "ICPC", "IOI", "Custom ICPC", "Custom IOI"];
28
29
    public function calcLength($a, $b)
30
    {
31
        $s=strtotime($b)-strtotime($a);
32
        $h=intval($s / 3600);
33
        $m=round(($s-$h * 3600) / 60);
34
        if ($m==60) {
35
            $h++;
36
            $m=0;
37
        }
38
        if ($m==0 && $h==0) {
39
            $text=trans_choice("contest.lengthformatter.seconds", $s);
40
        } elseif ($m==0) {
41
            $text=trans_choice("contest.lengthformatter.hours", $h);
42
        } elseif ($h==0) {
43
            $text=trans_choice("contest.lengthformatter.minutes", $m);
0 ignored issues
show
Bug introduced by
It seems like $m can also be of type double; however, parameter $number of trans_choice() does only seem to accept Countable|array|integer, maybe add an additional type check? ( Ignorable by Annotation )

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

43
            $text=trans_choice("contest.lengthformatter.minutes", /** @scrutinizer ignore-type */ $m);
Loading history...
44
        } else {
45
            $text=trans_choice("contest.lengthformatter.hours", $h).' '.trans_choice("contest.lengthformatter.minutes", $m);
46
        }
47
        return $text;
48
    }
49
50
    public function canViewContest($cid, $uid)
51
    {
52
        $contest_detail=DB::table($this->tableName)->where([
53
            "cid"=>$cid
54
        ])->first();
55
56
        if ($contest_detail["public"]==1) {
57
            return $contest_detail;
58
        } else {
59
            // group contest
60
            if ($uid==0) {
61
                return [];
62
            }
63
            $group_info=DB::table("group_member")->where([
64
                "uid"=>$uid,
65
                "gid"=>$contest_detail['gid'],
66
                ["role", ">", 0]
67
            ])->first();
68
            return empty($group_info) ? [] : $contest_detail;
69
        }
70
    }
71
72
    public function basic($cid)
73
    {
74
        return DB::table($this->tableName)->where([
75
            "cid"=>$cid
76
        ])->first();
77
    }
78
79
    public function detail($cid, $uid=0)
80
    {
81
        $contest_clearance=$this->judgeOutSideClearance($cid, $uid);
82
        $contest_detail=$this->basic($cid);
83
84
        if ($contest_clearance==0) {
85
            return [
86
                "ret"=>1000,
87
                "desc"=>"You have no right to view this contest.",
88
                "data"=>null
89
            ];
90
        } else {
91
            $contest_detail["rule_parsed"]=$this->rule[$contest_detail["rule"]];
92
            $contest_detail["date_parsed"]=[
93
                "date"=>date_format(date_create($contest_detail["begin_time"]), 'j'),
94
                "month_year"=>date_format(date_create($contest_detail["begin_time"]), 'M, Y'),
95
            ];
96
            $contest_detail["length"]=$this->calcLength($contest_detail["begin_time"], $contest_detail["end_time"]);
97
            $contest_detail["description_parsed"]=clean(convertMarkdownToHtml($contest_detail["description"]));
98
            $contest_detail["group_info"]=DB::table("group")->where(["gid"=>$contest_detail["gid"]])->first();
99
            $contest_detail["problem_count"]=DB::table("contest_problem")->where(["cid"=>$cid])->count();
100
            return [
101
                "ret"=>200,
102
                "desc"=>"succeed",
103
                "data"=>[
104
                    "contest_detail"=>$contest_detail
105
                ]
106
            ];
107
        }
108
    }
109
110
    public function gid($cid)
111
    {
112
        return DB::table($this->tableName)->where([
113
            "cid"=>$cid
114
        ])->first()["gid"];
115
    }
116
117
    public function gcode($cid)
118
    {
119
        $gid=$this->gid($cid);
120
        return DB::table('group')->where('gid', '=', $gid)->first()["gcode"];
121
    }
122
123
    public function runningContest()
124
    {
125
        return DB::select("select * from contest where begin_time < SYSDATE() and end_time > SYSDATE()");
126
    }
127
128
    public function updateCrawlStatus($cid) {
129
        return DB::table("contest")->where("cid", $cid)->update([
130
            "crawled"=>1,
131
        ]);
132
    }
133
134
    public function grantAccess($uid, $cid, $audit=0)
135
    {
136
        return DB::table('contest_participant')->insert([
137
            "cid"=>$cid,
138
            "uid"=>$uid,
139
            "audit"=>$audit
140
        ]);
141
    }
142
143
    public function listForSetting($gid)
144
    {
145
        $uid=Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
146
        $group_contests=DB::table('contest')
147
            ->where('gid', $gid)
148
            ->orderBy('begin_time', 'desc')
149
            ->get()->all();
150
        $groupModel=new GroupModel();
151
        $group_clearance=$groupModel->judgeClearance($gid, $uid);
152
        foreach ($group_contests as &$contest) {
153
            $contest['is_admin']=($contest['assign_uid']==$uid || $group_clearance==3);
154
            $contest['begin_stamps']=strtotime($contest['begin_time']);
155
            $contest['end_stamps']=strtotime($contest['end_time']);
156
            $contest['status']=time()>=$contest['end_stamps'] ? 1
157
                : (time()<=$contest['begin_stamps'] ? -1 : 0);
158
            $contest["rule_parsed"]=$this->rule[$contest["rule"]];
159
            $contest["date_parsed"]=[
160
                "date"=>date_format(date_create($contest["begin_time"]), 'j'),
161
                "month_year"=>date_format(date_create($contest["begin_time"]), 'M, Y'),
162
            ];
163
            $contest["length"]=$this->calcLength($contest["begin_time"], $contest["end_time"]);
164
        }
165
        usort($group_contests, function($a, $b) {
166
            if ($a['is_admin']==$b['is_admin']) {
167
                return $b['begin_stamps']-$a['begin_stamps'];
168
            }
169
            return $b['is_admin']-$a['is_admin'];
170
        });
171
        return $group_contests;
172
    }
173
174
    public function listByGroup($gid)
175
    {
176
        // $contest_list=DB::table($this->tableName)->where([
177
        //     "gid"=>$gid
178
        // ])->orderBy('begin_time', 'desc')->get()->all();
179
        $preQuery=DB::table($this->tableName);
180
        $paginator=$preQuery->where('gid', '=', $gid)->orderBy('begin_time', 'desc')->paginate(10);
181
        $contest_list=$paginator->all();
182
        if (empty($contest_list)) {
183
            return null;
184
        }
185
186
        foreach ($contest_list as &$c) {
187
            $c["rule_parsed"]=$this->rule[$c["rule"]];
188
            $c["date_parsed"]=[
189
                "date"=>date_format(date_create($c["begin_time"]), 'j'),
190
                "month_year"=>date_format(date_create($c["begin_time"]), 'M, Y'),
191
            ];
192
            $c["length"]=$this->calcLength($c["begin_time"], $c["end_time"]);
193
        }
194
        return [
195
            'paginator' => $paginator,
196
            'contest_list' => $contest_list,
197
        ];
198
    }
199
200
    public function rule($cid)
201
    {
202
        return DB::table($this->tableName)->where([
203
            "cid"=>$cid
204
        ])->first()["rule"];
205
    }
206
207
    public function list($filter, $uid)
208
    {
209
        if ($uid) {
210
            //$paginator=DB::select('SELECT DISTINCT contest.* FROM group_member inner join contest on group_member.gid=contest.gid left join contest_participant on contest.cid=contest_participant.cid where (public=1 and audit=1) or (group_member.uid=:uid and group_member.role>0 and (contest_participant.uid=:uidd or ISNULL(contest_participant.uid)) and (registration=0 or (registration=1 and not ISNULL(contest_participant.uid))))',["uid"=>$uid,"uidd"=>$uid])->paginate(10);
211
            if ($filter['public']=='1') {
212
                $paginator=DB::table($this->tableName)->where([
213
                    "public"=>1,
214
                    "audit_status"=>1
215
                ])->orderBy('begin_time', 'desc');
216
                if ($filter['rule']) {
217
                    $paginator=$paginator->where(["rule"=>$filter['rule']]);
218
                }
219
                if ($filter['verified']) {
220
                    $paginator=$paginator->where(["verified"=>$filter['verified']]);
221
                }
222
                if ($filter['rated']) {
223
                    $paginator=$paginator->where(["rated"=>$filter['rated']]);
224
                }
225
                if ($filter['anticheated']) {
226
                    $paginator=$paginator->where(["anticheated"=>$filter['anticheated']]);
227
                }
228
                if ($filter['practice']) {
229
                    $paginator=$paginator->where(["practice"=>$filter['practice']]);
230
                }
231
                $paginator=$paginator ->paginate(10);
232
            } elseif ($filter['public']=='0') {
233
                $paginator=DB::table('group_member')
234
                ->groupBy('contest.cid')
235
                ->select('contest.*')
236
                ->join('contest', 'group_member.gid', '=', 'contest.gid')
237
                ->leftJoin('contest_participant', 'contest.cid', '=', 'contest_participant.cid')
238
                ->where(
239
                    function($query) use ($filter, $uid) {
240
                        if ($filter['rule']) {
241
                            $query=$query->where(["rule"=>$filter['rule']]);
242
                        }
243
                        if ($filter['verified']) {
244
                            $query=$query->where(["verified"=>$filter['verified']]);
245
                        }
246
                        if ($filter['rated']) {
247
                            $query=$query->where(["rated"=>$filter['rated']]);
248
                        }
249
                        if ($filter['anticheated']) {
250
                            $query=$query->where(["anticheated"=>$filter['anticheated']]);
251
                        }
252
                        if ($filter['practice']) {
253
                            $query=$query->where(["practice"=>$filter['practice']]);
254
                        }
255
                        $query->where('group_member.uid', $uid)
256
                                ->where('group_member.role', '>', 0)
257
                                ->where(["public"=>0]);
258
                    }
259
                )
260
                ->orderBy('contest.begin_time', 'desc')
261
                ->paginate(10);
262
            } else {
263
                $paginator=DB::table('group_member')
264
                ->groupBy('contest.cid')
265
                ->select('contest.*')
266
                ->join('contest', 'group_member.gid', '=', 'contest.gid')
267
                ->leftJoin('contest_participant', 'contest.cid', '=', 'contest_participant.cid')
268
                ->where(
269
                    function($query) use ($filter) {
270
                        if ($filter['rule']) {
271
                            $query=$query->where(["rule"=>$filter['rule']]);
272
                        }
273
                        if ($filter['verified']) {
274
                            $query=$query->where(["verified"=>$filter['verified']]);
275
                        }
276
                        if ($filter['rated']) {
277
                            $query=$query->where(["rated"=>$filter['rated']]);
278
                        }
279
                        if ($filter['anticheated']) {
280
                            $query=$query->where(["anticheated"=>$filter['anticheated']]);
281
                        }
282
                        if ($filter['practice']) {
283
                            $query=$query->where(["practice"=>$filter['practice']]);
284
                        }
285
                        $query->where([
286
                            'public'=>1,
287
                            'audit_status'=>1
288
                        ]);
289
                    }
290
                )
291
                ->orWhere(
292
                    function($query) use ($filter, $uid) {
293
                        if ($filter['rule']) {
294
                            $query=$query->where(["rule"=>$filter['rule']]);
295
                        }
296
                        if ($filter['public']) {
297
                            $query=$query->where(["public"=>$filter['public']]);
298
                        }
299
                        if ($filter['verified']) {
300
                            $query=$query->where(["verified"=>$filter['verified']]);
301
                        }
302
                        if ($filter['rated']) {
303
                            $query=$query->where(["rated"=>$filter['rated']]);
304
                        }
305
                        if ($filter['anticheated']) {
306
                            $query=$query->where(["anticheated"=>$filter['anticheated']]);
307
                        }
308
                        if ($filter['practice']) {
309
                            $query=$query->where(["practice"=>$filter['practice']]);
310
                        }
311
                        $query->where('group_member.uid', $uid)
312
                                ->where('group_member.role', '>', 0);
313
                    }
314
                )
315
                ->orderBy('contest.begin_time', 'desc')
316
                ->paginate(10);
317
            }
318
        } else {
319
            $paginator=DB::table($this->tableName)->where([
320
                "public"=>1,
321
                "audit_status"=>1
322
            ])->orderBy('begin_time', 'desc');
323
            if ($filter['rule']) {
324
                $paginator=$paginator->where(["rule"=>$filter['rule']]);
325
            }
326
            if ($filter['verified']) {
327
                $paginator=$paginator->where(["verified"=>$filter['verified']]);
328
            }
329
            if ($filter['rated']) {
330
                $paginator=$paginator->where(["rated"=>$filter['rated']]);
331
            }
332
            if ($filter['anticheated']) {
333
                $paginator=$paginator->where(["anticheated"=>$filter['anticheated']]);
334
            }
335
            if ($filter['practice']) {
336
                $paginator=$paginator->where(["practice"=>$filter['practice']]);
337
            }
338
            $paginator=$paginator ->paginate(10);
339
        }
340
        $contest_list=$paginator->all();
341
        foreach ($contest_list as &$c) {
342
            $c["rule_parsed"]=$this->rule[$c["rule"]];
343
            $c["date_parsed"]=[
344
                "date"=>date_format(date_create($c["begin_time"]), 'j'),
345
                "month_year"=>date_format(date_create($c["begin_time"]), 'M, Y'),
346
            ];
347
            $c["length"]=$this->calcLength($c["begin_time"], $c["end_time"]);
348
        }
349
        return [
350
            'contents' => $contest_list,
351
            'paginator' => $paginator
352
        ];
353
    }
354
355
    public function featured()
356
    {
357
        $featured=DB::table($this->tableName)->where([
358
            "public"=>1,
359
            "audit_status"=>1,
360
            "featured"=>1
361
        ])->orderBy('begin_time', 'desc')->first();
362
363
        if (!empty($featured)) {
364
            $featured["rule_parsed"]=$this->rule[$featured["rule"]];
365
            $featured["date_parsed"]=[
366
                "date"=>date_format(date_create($featured["begin_time"]), 'j'),
367
                "month_year"=>date_format(date_create($featured["begin_time"]), 'M, Y'),
368
            ];
369
            $featured["length"]=$this->calcLength($featured["begin_time"], $featured["end_time"]);
370
            return $featured;
371
        } else {
372
            return null;
373
        }
374
    }
375
376
    public function registContest($cid, $uid)
377
    {
378
        $registered=DB::table("contest_participant")->where([
379
            "cid"=>$cid,
380
            "uid"=>$uid
381
        ])->first();
382
383
        if (empty($registered)) {
384
            DB::table("contest_participant")->insert([
385
                "cid"=>$cid,
386
                "uid"=>$uid,
387
                "audit"=>1
388
            ]);
389
            $name=User::find($uid)->name;
390
            $contest=$this->basic($cid);
391
            $url=route('contest.detail', ['cid' => $cid]);
392
            sendMessage([
393
                'receiver' => $uid,
394
                'sender' => config('app.official_sender'),
395
                'level' => 5,
396
                'title' => "You have successfully registered {$contest['name']}",
397
                'content' => "Hi, Dear **$name**,\n\n  You have successfully registered [**{$contest['name']}**]($url), don't forget to participate!\n\n  **Contest:** {$contest['name']}\n\n  **Begin Time:** {$contest['begin_time']}\n\nSincerely, NOJ"
398
            ]);
399
            return true;
400
        }
401
        return false;
402
    }
403
404
    public function remainingTime($cid)
405
    {
406
        $end_time=DB::table($this->tableName)->where([
407
            "cid"=>$cid
408
        ])->select("end_time")->first()["end_time"];
409
        $end_time=strtotime($end_time);
410
        $cur_time=time();
411
        return $end_time-$cur_time;
412
    }
413
414
    public function intToChr($index, $start=65)
415
    {
416
        $str='';
417
        if (floor($index / 26)>0) {
418
            $str.=$this->intToChr(floor($index / 26)-1);
419
        }
420
        return $str.chr($index % 26+$start);
421
    }
422
423
    public function problems($cid)
424
    {
425
        return DB::table('contest_problem')
426
            ->join('problem', 'contest_problem.pid', '=', 'problem.pid')
427
            ->where('cid', $cid)
428
            ->select('problem.pid as pid', 'pcode', 'number', 'title')
429
            ->orderBy('number')
430
            ->get()->all();
431
    }
432
433
    public function contestProblems($cid, $uid)
434
    {
435
        $submissionModel=new SubmissionModel();
436
437
        $contest_rule=$this->contestRule($cid);
438
439
        $problemSet=DB::table("contest_problem")
440
        ->join("problem", "contest_problem.pid", "=", "problem.pid")
441
        ->join("contest", "contest_problem.cid", "=", "contest.cid")
442
        ->where([
443
            "contest_problem.cid"=>$cid
444
        ])->orderBy('number', 'asc')->select("ncode", "alias", "contest_problem.pid as pid", "title", "contest.gid as gid", "contest.practice as practice")->get()->all();
445
446
        $frozen_time=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
447
        $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...
448
449
        foreach ($problemSet as &$p) {
450
            if ($p['practice']) {
451
                $tags=DB::table("group_problem_tag")
452
                ->where('gid', $p['gid'])
453
                ->where('pid', $p['pid'])
454
                ->get()->all();
455
                $tags_arr=[];
456
                if (!empty($tags)) {
457
                    foreach ($tags as $value) {
458
                        array_push($tags_arr, $value['tag']);
459
                    }
460
                }
461
                $p['tags']=$tags_arr;
462
            }
463
            if ($contest_rule==1) {
464
                $prob_stat=DB::table("submission")->select(
465
                    DB::raw("count(sid) as submission_count"),
466
                    DB::raw("sum(verdict='accepted') as passed_count"),
467
                    DB::raw("sum(verdict='accepted')/count(sid)*100 as ac_rate")
468
                )->where([
469
                    "pid"=>$p["pid"],
470
                    "cid"=>$cid
471
                ])->where("submission_date", "<", $frozen_time)->first();
472
473
                if ($prob_stat["submission_count"]==0) {
474
                    $p["submission_count"]=0;
475
                    $p["passed_count"]=0;
476
                    $p["ac_rate"]=0;
477
                } else {
478
                    $p["submission_count"]=$prob_stat["submission_count"];
479
                    $p["passed_count"]=$prob_stat["passed_count"];
480
                    $p["ac_rate"]=round($prob_stat["ac_rate"], 2);
481
                }
482
            } else {
483
                $prob_stat=$this->contestProblemInfoIOI($cid, $p["pid"], $uid);
484
                $p["points"]=$prob_stat["points"];
485
                $p["score"]=empty($prob_stat["score_parsed"]) ? 0 : $prob_stat["score_parsed"];
486
            }
487
            $prob_status=$submissionModel->getProblemStatus($p["pid"], $uid, $cid);
488
            if (empty($prob_status)) {
489
                $p["prob_status"]=[
490
                    "icon"=>"checkbox-blank-circle-outline",
491
                    "color"=>"wemd-grey-text"
492
                ];
493
            } else {
494
                $p["prob_status"]=[
495
                    "icon"=>$prob_status["verdict"]=="Accepted" ? "checkbox-blank-circle" : "cisco-webex",
496
                    "color"=>$prob_status["color"]
497
                ];
498
            }
499
500
501
        }
502
503
        return $problemSet;
504
    }
505
506
    public function getPid($cid, $ncode)
507
    {
508
        return DB::table("contest_problem")->where([
509
            "cid"=>$cid,
510
            "ncode"=>$ncode
511
        ])->select("contest_problem.pid")->first()["pid"];
512
    }
513
514
    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

514
    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...
515
    {
516
        return DB::table("problem")->where([
517
            "cid"=>$cid
518
        ])->select("contest_problem.pid")->first()["pcode"];
519
    }
520
521
    public function getCustomInfo($cid)
522
    {
523
        $basic_info=DB::table($this->tableName)->where([
524
            "cid"=>$cid
525
        ])->select("verified", "custom_icon", "custom_title")->first();
526
        return $basic_info["verified"] ? ((is_null($basic_info["custom_icon"]) && is_null($basic_info["custom_title"])) ?null:$basic_info) : null;
527
    }
528
529
530
    public function formatTime($seconds)
531
    {
532
        if ($seconds>3600) {
533
            $hours=intval($seconds / 3600);
534
            $minutes=$seconds % 3600;
535
            $time=$hours.":".gmstrftime('%M:%S', $minutes);
536
        } else {
537
            $time=gmstrftime('%H:%M:%S', $seconds);
538
        }
539
        return $time;
540
    }
541
542
    public function contestProblemInfoIOI($cid, $pid, $uid)
543
    {
544
        $ret=[
545
            "color"=>"",
546
            "score"=>null,
547
            "score_parsed"=>"",
548
            "solved"=>0,
549
            "points"=>DB::table("contest_problem")->where([
550
                "pid"=>$pid,
551
                "cid"=>$cid
552
            ])->first()["points"]
553
        ];
554
555
        $frozen_time=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
556
        $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...
557
558
        $highest_record=DB::table("submission")->where([
559
            "cid"=>$cid,
560
            "pid"=>$pid,
561
            "uid"=>$uid
562
        ])->where("submission_date", "<", $frozen_time)->orderBy('score', 'desc')->first();
563
564
        if (!empty($highest_record)) {
565
            $ret["score"]=$highest_record["score"];
566
567
            $tot_score=DB::table("problem")->where([
568
                "pid"=>$pid
569
            ])->first()["tot_score"];
570
571
            $ret["color"]=($ret["score"]==$tot_score) ? "wemd-teal-text" : "wemd-green-text";
572
            $ret["solved"]=($ret["score"]==$tot_score) ? 1 : 0;
573
            $ret["score_parsed"]=$ret["score"] / max($tot_score, 1) * ($ret["points"]);
574
        }
575
        return $ret;
576
    }
577
578
    public function isFrozen($cid)
579
    {
580
        $frozen=DB::table("contest")->where(["cid"=>$cid])->select("froze_length", DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first();
581
        if (empty($frozen["froze_length"])) {
582
            return false;
583
        } else {
584
            return time()>$frozen["frozen_time"];
585
        }
586
    }
587
588
    public function contestProblemInfoACM($cid, $pid, $uid)
589
    {
590
        $ret=[
591
            "color"=>"",
592
            "solved"=>0,
593
            "solved_time"=>"",
594
            "solved_time_parsed"=>"",
595
            "wrong_doings"=>0,
596
            "color"=>"",
597
        ];
598
599
        $frozen_time=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
600
        $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...
601
602
        $ac_record=DB::table("submission")->where([
603
            "cid"=>$cid,
604
            "pid"=>$pid,
605
            "uid"=>$uid,
606
            "verdict"=>"Accepted"
607
        ])->where("submission_date", "<", $frozen_time)->orderBy('submission_date', 'asc')->first();
608
609
        if (!empty($ac_record)) {
610
            $ret["solved"]=1;
611
612
            $ret["solved_time"]=$ac_record["submission_date"]-strtotime(DB::table($this->tableName)->where([
613
                "cid"=>$cid
614
            ])->first()["begin_time"]);
615
616
            $ret["solved_time_parsed"]=$this->formatTime($ret["solved_time"]);
617
618
            $ret["wrong_doings"]=DB::table("submission")->where([
619
                "cid"=>$cid,
620
                "pid"=>$pid,
621
                "uid"=>$uid
622
            ])->whereIn('verdict', [
623
                'Runtime Error',
624
                'Wrong Answer',
625
                'Time Limit Exceed',
626
                'Real Time Limit Exceed',
627
                'Memory Limit Exceed',
628
                'Presentation Error',
629
                'Output Limit Exceeded'
630
            ])->where("submission_date", "<", $ac_record["submission_date"])->count();
631
632
            $others_first=DB::table("submission")->where([
633
                "cid"=>$cid,
634
                "pid"=>$pid,
635
                "verdict"=>"Accepted"
636
            ])->where("submission_date", "<", $ac_record["submission_date"])->count();
637
638
            $ret["color"]=$others_first ? "wemd-green-text" : "wemd-teal-text";
639
        } else {
640
            $ret["wrong_doings"]=DB::table("submission")->where([
641
                "cid"=>$cid,
642
                "pid"=>$pid,
643
                "uid"=>$uid
644
            ])->whereIn('verdict', [
645
                'Runtime Error',
646
                'Wrong Answer',
647
                'Time Limit Exceed',
648
                'Real Time Limit Exceed',
649
                'Memory Limit Exceed',
650
                'Presentation Error',
651
                'Output Limit Exceeded'
652
            ])->where("submission_date", "<", $frozen_time)->count();
653
        }
654
655
        return $ret;
656
    }
657
658
    public function contestRankCache($cid)
659
    {
660
        // if(Cache::tags(['contest','rank'])->get($cid)!=null) return Cache::tags(['contest','rank'])->get($cid);
661
        $ret=[];
662
663
        $contest_info=DB::table("contest")->where("cid", $cid)->first();
664
        $frozen_time=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
665
        $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...
666
667
        if ($contest_info["registration"]) {
668
            $submissionUsers=DB::table("contest_participant")->where([
669
                "cid"=>$cid,
670
                "audit"=>1
671
            ])->select('uid')->get()->all();
672
        } else {
673
            // Those who submitted are participants
674
            $submissionUsers=DB::table("submission")->where([
675
                "cid"=>$cid
676
            ])->where(
677
                "submission_date",
678
                "<",
679
                $frozen_time
680
            )->select('uid')->groupBy('uid')->get()->all();
681
        }
682
683
        $problemSet=DB::table("contest_problem")->join("problem", "contest_problem.pid", "=", "problem.pid")->where([
684
            "cid"=>$cid
685
        ])->orderBy('number', 'asc')->select("ncode", "alias", "contest_problem.pid as pid", "title")->get()->all();
686
687
        if ($contest_info["rule"]==1) {
688
            // ACM/ICPC Mode
689
            foreach ($submissionUsers as $s) {
690
                $prob_detail=[];
691
                $totPen=0;
692
                $totScore=0;
693
                foreach ($problemSet as $p) {
694
                    $prob_stat=$this->contestProblemInfoACM($cid, $p["pid"], $s["uid"]);
695
                    $prob_detail[]=[
696
                        "ncode"=>$p["ncode"],
697
                        "pid"=>$p["pid"],
698
                        "color"=>$prob_stat["color"],
699
                        "wrong_doings"=>$prob_stat["wrong_doings"],
700
                        "solved_time_parsed"=>$prob_stat["solved_time_parsed"]
701
                    ];
702
                    if ($prob_stat["solved"]) {
703
                        $totPen+=$prob_stat["wrong_doings"] * 20;
704
                        $totPen+=$prob_stat["solved_time"] / 60;
705
                        $totScore+=$prob_stat["solved"];
706
                    }
707
                }
708
709
                $nickName=DB::table("group_member")->where([
710
                    "uid" => $s["uid"],
711
                    "gid" => $contest_info["gid"]
712
                ])->where("role", ">", 0)->first();
713
714
                $nickName=is_null($nickName) ?null:$nickName["nick_name"];
715
                $ret[]=[
716
                    "uid" => $s["uid"],
717
                    "name" => DB::table("users")->where([
718
                        "id"=>$s["uid"]
719
                    ])->first()["name"],
720
                    "nick_name" => $nickName,
721
                    "score" => $totScore,
722
                    "penalty" => $totPen,
723
                    "problem_detail" => $prob_detail
724
                ];
725
            }
726
            usort($ret, function($a, $b) {
727
                if ($a["score"]==$b["score"]) {
728
                    if ($a["penalty"]==$b["penalty"]) {
729
                        return 0;
730
                    } elseif (($a["penalty"]>$b["penalty"])) {
731
                        return 1;
732
                    } else {
733
                        return -1;
734
                    }
735
                } elseif ($a["score"]>$b["score"]) {
736
                    return -1;
737
                } else {
738
                    return 1;
739
                }
740
            });
741
        } elseif ($contest_info["rule"]==2) {
742
            // IOI Mode
743
            foreach ($submissionUsers as $s) {
744
                $prob_detail=[];
745
                $totScore=0;
746
                $totSolved=0;
747
                foreach ($problemSet as $p) {
748
                    $prob_stat=$this->contestProblemInfoIOI($cid, $p["pid"], $s["uid"]);
749
                    $prob_detail[]=[
750
                        "ncode"=>$p["ncode"],
751
                        "pid"=>$p["pid"],
752
                        "color"=>$prob_stat["color"],
753
                        "score"=>$prob_stat["score"],
754
                        "score_parsed"=>$prob_stat["score_parsed"]
755
                    ];
756
                    $totSolved+=$prob_stat["solved"];
757
                    $totScore+=intval($prob_stat["score_parsed"]);
758
                }
759
760
                $nickName=DB::table("group_member")->where([
761
                    "uid" => $s["uid"],
762
                    "gid" => $contest_info["gid"]
763
                ])->where("role", ">", 0)->first();
764
765
                $nickName=is_null($nickName) ?null:$nickName["nick_name"];
766
                $ret[]=[
767
                    "uid" => $s["uid"],
768
                    "name" => DB::table("users")->where([
769
                        "id"=>$s["uid"]
770
                    ])->first()["name"],
771
                    "nick_name" => $nickName,
772
                    "score" => $totScore,
773
                    "solved" => $totSolved,
774
                    "problem_detail" => $prob_detail
775
                ];
776
            }
777
            usort($ret, function($a, $b) {
778
                if ($a["score"]==$b["score"]) {
779
                    if ($a["solved"]==$b["solved"]) {
780
                        return 0;
781
                    } elseif (($a["solved"]<$b["solved"])) {
782
                        return 1;
783
                    } else {
784
                        return -1;
785
                    }
786
                } elseif ($a["score"]>$b["score"]) {
787
                    return -1;
788
                } else {
789
                    return 1;
790
                }
791
            });
792
        }
793
794
        Cache::tags(['contest', 'rank'])->put($cid, $ret, 60);
795
796
        return $ret;
797
    }
798
799
    public function contestRank($cid, $uid=0)
800
    {
801
        // [ToDo] If the current user's in the organizer group show nick name
802
        // [ToDo] The participants determination
803
        // [ToDo] Frozen Time
804
        // [ToDo] Performance Opt
805
        // [Todo] Ajaxization - Should have done in controller
806
        // [Todo] Authorization ( Public / Private ) - Should have done in controller
807
        $ret=[];
0 ignored issues
show
Unused Code introduced by
The assignment to $ret is dead and can be removed.
Loading history...
808
809
        $contest_info=DB::table("contest")->where("cid", $cid)->first();
810
811
        $user_in_group=!empty(DB::table("group_member")->where([
812
            "uid" => $uid,
813
            "gid" => $contest_info["gid"]
814
        ])->where("role", ">", 0)->first());
815
816
        $clearance=$this -> judgeClearance($cid, $uid);
817
818
        /** New Version With MySQL */
819
        $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
820
        $contest_eloquent=Contest::find($cid);
821
822
        if (time()<$end_time) {
823
            if ($clearance==3) {
824
                $contestRankRaw=Cache::tags(['contest', 'rank'])->get("contestAdmin$cid");
825
            } else {
826
                $contestRankRaw=Cache::tags(['contest', 'rank'])->get($cid);
827
            }
828
            if (!isset($contestRankRaw)) {
829
                $contestRankRaw=$contest_eloquent->rankRefresh();
830
            }
831
        } else {
832
            if ($clearance==3) {
833
                $contestRankRaw=Cache::tags(['contest', 'rank'])->get("contestAdmin$cid");
834
                if (!isset($contestRankRaw)) {
835
                    $contestRankRaw=$this->getContestRankFromMySQL($cid);
836
                    if (!isset($contestRankRaw)) {
837
                        $contestRankRaw=$contest_eloquent->rankRefresh();
838
                        $this->storeContestRankInMySQL($cid, $contestRankRaw);
839
                    }
840
                }
841
            } else {
842
                $contestRankRaw=$this->getContestRankFromMySQL($cid);
843
                if (!isset($contestRankRaw)) {
844
                    $contestRankRaw=Cache::tags(['contest', 'rank'])->get($cid);
845
                    if (!isset($contestRankRaw)) {
846
                        $contestRankRaw=$contest_eloquent->rankRefresh();
847
                    }
848
                    $this->storeContestRankInMySQL($cid, $contestRankRaw);
849
                }
850
            }
851
        }
852
853
        /** Old version */
854
        // if ($contestRankRaw==null) {
855
        //     $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
856
        //     if(time() > $end_time && !Cache::has($cid)){
857
        //         $contestRankRaw=$this->contestRankCache($cid);
858
        //         // Cache::forever($cid, $contestRankRaw);
859
        //     }else{
860
        //         $contestRankRaw=$this->contestRankCache($cid);
861
        //     }
862
        // }
863
        if ($contest_info["rule"]==1) {
864
            foreach ($contestRankRaw as &$cr) {
865
                $solved=0;
866
                foreach ($cr['problem_detail'] as $pd) {
867
                    if (!empty($pd['solved_time_parsed'])) {
868
                        $solved++;
869
                    }
870
                }
871
                $cr['solved']=$solved;
872
            }
873
        }
874
875
        $ret=$contestRankRaw;
876
877
        foreach ($ret as $r) {
878
            if (!$user_in_group) {
879
                $r["nick_name"]='';
880
            }
881
        }
882
883
        return $ret;
884
    }
885
886
    public function getRejudgeQueue($cid, $filter)
887
    {
888
        $problemModel=new ProblemModel();
889
        $submissionModel=new SubmissionModel();
0 ignored issues
show
Unused Code introduced by
The assignment to $submissionModel is dead and can be removed.
Loading history...
890
        $compilerModel=new CompilerModel();
891
892
        $tempQueue=DB::table("submission")->where([
893
            "cid"=>$cid
894
        ])->whereIn('verdict', $filter)->get()->all();
895
896
        foreach ($tempQueue as &$t) {
897
            $lang=$compilerModel->detail($t["coid"]);
898
            $probBasic=$problemModel->basic($t["pid"]);
899
            $t["oj"]=$problemModel->ocode($t["pid"]);
900
            $t["lang"]=$lang['lcode'];
901
            $t["cid"]=$probBasic["contest_id"];
902
            $t["iid"]=$probBasic["index_id"];
903
            $t["pcode"]=$probBasic["pcode"];
904
            $t["contest"]=$cid;
905
        }
906
907
        return $tempQueue;
908
    }
909
910
    public function getClarificationList($cid)
911
    {
912
        $uid=Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
913
        $clearance=$this -> judgeClearance($cid, $uid);
914
        if ($clearance==3) {
915
            return DB::table("contest_clarification")->where([
916
                "cid"=>$cid
917
            ])->orderBy('created_at', 'desc')->get()->all();
918
        } else {
919
            return DB::table("contest_clarification")->where([
920
                "cid"=>$cid
921
            ])->where(function($query) {
922
                $query->where([
923
                    "public"=>1
924
                ])->orWhere([
925
                    "uid" => Auth::user()->id
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
926
                ]);
927
            })->orderBy('created_at', 'desc')->get()->all();
928
        }
929
    }
930
931
    public function fetchClarification($cid)
932
    {
933
        return DB::table("contest_clarification")->where([
934
            "cid"=>$cid,
935
            "type"=>0,
936
            "public"=>1
937
        ])->whereBetween(
938
            'created_at',
939
            [
940
                date("Y-m-d H:i:s", time()-59),
941
                date("Y-m-d H:i:s")
942
            ]
943
        )->first();
944
    }
945
946
    public function getlatestClarification($cid)
947
    {
948
        return DB::table("contest_clarification")->where([
949
            "cid"=>$cid,
950
            "type"=>0,
951
            "public"=>1
952
        ])->orderBy('created_at', 'desc')->first();
953
    }
954
955
    public function getClarificationDetail($ccid)
956
    {
957
        return DB::table("contest_clarification")->where([
958
            "ccid"=>$ccid,
959
            "public"=>1
960
        ])->first();
961
    }
962
963
    public function requestClarification($cid, $title, $content, $uid)
964
    {
965
        return DB::table("contest_clarification")->insertGetId([
966
            "cid"=>$cid,
967
            "type"=>1,
968
            "title"=>$title,
969
            "content"=>$content,
970
            "public"=>"0",
971
            "uid"=>$uid,
972
            "created_at"=>date("Y-m-d H:i:s")
973
        ]);
974
    }
975
976
    public function issueAnnouncement($cid, $title, $content, $uid, $remote_code=null)
977
    {
978
        return DB::table("contest_clarification")->insertGetId([
979
            "cid"=>$cid,
980
            "type"=>0,
981
            "title"=>$title,
982
            "content"=>$content,
983
            "public"=>"1",
984
            "uid"=>$uid,
985
            "created_at"=>date("Y-m-d H:i:s"),
986
            "remote_code"=>$remote_code
987
        ]);
988
    }
989
990
    public function remoteAnnouncement($remote_code) {
991
        return DB::table("contest_clarification")->where("remote_code", $remote_code)->get()->first();
992
    }
993
994
    public function isContestEnded($cid)
995
    {
996
        return DB::table("contest")->where("cid", $cid)->where("end_time", "<", date("Y-m-d H:i:s"))->count();
997
    }
998
999
    public function isContestRunning($cid)
1000
    {
1001
        return DB::table("contest")->where("cid", $cid)->where("begin_time", "<", date("Y-m-d H:i:s"))->where("end_time", ">", date("Y-m-d H:i:s"))->count();
1002
    }
1003
1004
    public function formatAbsTime($sec)
1005
    {
1006
        $periods=["second", "minute", "hour", "day", "week", "month", "year", "decade"];
1007
        $lengths=["60", "60", "24", "7", "4.35", "12", "10"];
1008
1009
1010
        $difference=$sec;
1011
1012
        for ($j=0; $difference>=$lengths[$j] && $j<count($lengths)-1; $j++) {
1013
            $difference/=$lengths[$j];
1014
        }
1015
1016
        $difference=round($difference);
1017
1018
        if ($difference!=1) {
1019
            $periods[$j].="s";
1020
        }
1021
1022
        return "$difference $periods[$j]";
1023
    }
1024
1025
    public function frozenTime($cid)
1026
    {
1027
        $basicInfo=$this->basic($cid);
1028
        return $this->formatAbsTime($basicInfo["froze_length"]);
1029
    }
1030
1031
    public function getContestRecord($filter, $cid)
1032
    {
1033
        $basicInfo=$this->basic($cid);
1034
        $userInfo=DB::table('group_member')->where('gid', $basicInfo["gid"])->where('uid', Auth::user()->id)->get()->first();
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
1035
        $problemSet_temp=DB::table("contest_problem")->join("problem", "contest_problem.pid", "=", "problem.pid")->where([
1036
            "cid"=>$cid
1037
        ])->orderBy('number', 'asc')->select("ncode", "alias", "contest_problem.pid as pid", "title", "points", "tot_score")->get()->all();
1038
        $problemSet=[];
1039
        foreach ($problemSet_temp as $p) {
1040
            $problemSet[(string) $p["pid"]]=["ncode"=>$p["ncode"], "points"=>$p["points"], "tot_score"=>$p["tot_score"]];
1041
        }
1042
1043
        $frozen_time=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
1044
        $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
1045
        $contestEnd=time()>$end_time;
1046
1047
        $filter['pid']=array_search($filter['ncode'], array_column($problemSet_temp, 'ncode'));
1048
        if ($filter['pid']===false) {
1049
            $filter['pid']=is_null($filter['ncode']) ?null:-1;
1050
        } else {
1051
            $filter['pid']=$problemSet_temp[$filter['pid']]['pid'];
1052
        }
1053
1054
        if ($userInfo==null || $userInfo["role"]!=3) {
1055
            if ($basicInfo["status_visibility"]==2) {
1056
                // View all
1057
                $paginator=DB::table("submission")->where([
1058
                    'cid'=>$cid
1059
                ])->where(
1060
                    "submission_date",
1061
                    "<",
1062
                    $end_time
1063
                )->join(
1064
                    "users",
1065
                    "users.id",
1066
                    "=",
1067
                    "submission.uid"
1068
                )->where(function($query) use ($frozen_time) {
1069
                    $query->where(
1070
                        "submission_date",
1071
                        "<",
1072
                        $frozen_time
1073
                    )->orWhere(
1074
                        'uid',
1075
                        Auth::user()->id
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
1076
                    );
1077
                })->select(
1078
                    "sid",
1079
                    "uid",
1080
                    "pid",
1081
                    "name",
1082
                    "color",
1083
                    "verdict",
1084
                    "time",
1085
                    "memory",
1086
                    "language",
1087
                    "score",
1088
                    "submission_date",
1089
                    "share"
1090
                )->orderBy(
1091
                    'submission_date',
1092
                    'desc'
1093
                );
1094
1095
                if ($filter["pid"]) {
1096
                    $paginator=$paginator->where(["pid"=>$filter["pid"]]);
1097
                }
1098
1099
                if ($filter["result"]) {
1100
                    $paginator=$paginator->where(["verdict"=>$filter["result"]]);
1101
                }
1102
1103
                if ($filter["account"]) {
1104
                    $paginator=$paginator->where(["name"=>$filter["account"]]);
1105
                }
1106
1107
                $paginator=$paginator->paginate(50);
1108
            } elseif ($basicInfo["status_visibility"]==1) {
1109
                $paginator=DB::table("submission")->where([
1110
                    'cid'=>$cid,
1111
                    'uid'=>Auth::user()->id
1112
                ])->where(
1113
                    "submission_date",
1114
                    "<",
1115
                    $end_time
1116
                )->join(
1117
                    "users",
1118
                    "users.id",
1119
                    "=",
1120
                    "submission.uid"
1121
                )->select(
1122
                    "sid",
1123
                    "uid",
1124
                    "pid",
1125
                    "name",
1126
                    "color",
1127
                    "verdict",
1128
                    "time",
1129
                    "memory",
1130
                    "language",
1131
                    "score",
1132
                    "submission_date",
1133
                    "share"
1134
                )->orderBy(
1135
                    'submission_date',
1136
                    'desc'
1137
                );
1138
1139
                if ($filter["pid"]) {
1140
                    $paginator=$paginator->where(["pid"=>$filter["pid"]]);
1141
                }
1142
1143
                if ($filter["result"]) {
1144
                    $paginator=$paginator->where(["verdict"=>$filter["result"]]);
1145
                }
1146
1147
                if ($filter["account"]) {
1148
                    $paginator=$paginator->where(["name"=>$filter["account"]]);
1149
                }
1150
1151
                $paginator=$paginator->paginate(50);
1152
            } else {
1153
                return [
1154
                    "paginator"=>null,
1155
                    "records"=>[]
1156
                ];
1157
            }
1158
        } else {
1159
            if ($basicInfo["status_visibility"]==2) {
1160
                // View all
1161
                $paginator=DB::table("submission")->where([
1162
                    'cid'=>$cid
1163
                ])->where(
1164
                    "submission_date",
1165
                    "<",
1166
                    $end_time
1167
                )->join(
1168
                    "users",
1169
                    "users.id",
1170
                    "=",
1171
                    "submission.uid"
1172
                )->select(
1173
                    "sid",
1174
                    "uid",
1175
                    "pid",
1176
                    "name",
1177
                    "color",
1178
                    "verdict",
1179
                    "time",
1180
                    "memory",
1181
                    "language",
1182
                    "score",
1183
                    "submission_date",
1184
                    "share"
1185
                )->orderBy(
1186
                    'submission_date',
1187
                    'desc'
1188
                );
1189
1190
                if ($filter["pid"]) {
1191
                    $paginator=$paginator->where(["pid"=>$filter["pid"]]);
1192
                }
1193
1194
                if ($filter["result"]) {
1195
                    $paginator=$paginator->where(["verdict"=>$filter["result"]]);
1196
                }
1197
1198
                if ($filter["account"]) {
1199
                    $paginator=$paginator->where(["name"=>$filter["account"]]);
1200
                }
1201
1202
                $paginator=$paginator->paginate(50);
1203
            } elseif ($basicInfo["status_visibility"]==1) {
1204
                $paginator=DB::table("submission")->where([
1205
                    'cid'=>$cid,
1206
                    'uid'=>Auth::user()->id
1207
                ])->where(
1208
                    "submission_date",
1209
                    "<",
1210
                    $end_time
1211
                )->join(
1212
                    "users",
1213
                    "users.id",
1214
                    "=",
1215
                    "submission.uid"
1216
                )->select(
1217
                    "sid",
1218
                    "uid",
1219
                    "pid",
1220
                    "name",
1221
                    "color",
1222
                    "verdict",
1223
                    "time",
1224
                    "memory",
1225
                    "language",
1226
                    "score",
1227
                    "submission_date",
1228
                    "share"
1229
                )->orderBy(
1230
                    'submission_date',
1231
                    'desc'
1232
                );
1233
1234
                if ($filter["pid"]) {
1235
                    $paginator=$paginator->where(["pid"=>$filter["pid"]]);
1236
                }
1237
1238
                if ($filter["result"]) {
1239
                    $paginator=$paginator->where(["verdict"=>$filter["result"]]);
1240
                }
1241
1242
                if ($filter["account"]) {
1243
                    $paginator=$paginator->where(["name"=>$filter["account"]]);
1244
                }
1245
1246
                $paginator=$paginator->paginate(50);
1247
            } else {
1248
                return [
1249
                    "paginator"=>null,
1250
                    "records"=>[]
1251
                ];
1252
            }
1253
        }
1254
1255
        $records=$paginator->all();
1256
        foreach ($records as &$r) {
1257
            $r["submission_date_parsed"]=formatHumanReadableTime(date('Y-m-d H:i:s', $r["submission_date"]));
1258
            $r["submission_date"]=date('Y-m-d H:i:s', $r["submission_date"]);
1259
            $r["nick_name"]="";
1260
            $r["ncode"]=$problemSet[(string) $r["pid"]]["ncode"];
1261
            if ($r["verdict"]=="Partially Accepted") {
1262
                $score_parsed=round($r["score"] / $problemSet[(string) $r["pid"]]["tot_score"] * $problemSet[(string) $r["pid"]]["points"], 1);
1263
                $r["verdict"].=" ($score_parsed)";
1264
            }
1265
            if (!$contestEnd) {
1266
                $r["share"]=0;
1267
            }
1268
        }
1269
        return [
1270
            "paginator"=>$paginator,
1271
            "records"=>$records
1272
        ];
1273
    }
1274
1275
    public function registration($cid, $uid=0)
1276
    {
1277
        if ($uid==0) {
1278
            return [];
1279
        }
1280
1281
1282
        return DB::table("contest_participant")->where([
1283
            "cid" => $cid,
1284
            "uid" => $uid,
1285
            "audit" => 1
1286
        ])->first();
1287
    }
1288
1289
    public function judgeClearance($cid, $uid=0)
1290
    {
1291
        /***************************
1292
         * 2 stands for participant*
1293
         * 3 stands for admin      *
1294
         ***************************/
1295
        if ($uid==0 || filter_var($cid, FILTER_VALIDATE_INT)===false) {
1296
            return 0;
1297
        }
1298
        $groupModel=new GroupModel();
1299
        $contest_info=DB::table("contest")->where("cid", $cid)->first();
1300
        $userInfo=DB::table('group_member')->where('gid', $contest_info["gid"])->where('uid', $uid)->get()->first();
1301
1302
        if (empty($contest_info)) {
1303
            // contest not exist
1304
            return 0;
1305
        }
1306
1307
        if ($uid==$contest_info['assign_uid'] || $groupModel->judgeClearance($contest_info['gid'], $uid)==3) {
1308
            return 3;
1309
        }
1310
1311
        $contest_started=strtotime($contest_info['begin_time'])<time();
1312
        $contest_ended=strtotime($contest_info['end_time'])<time();
1313
        if (!$contest_started) {
1314
            // not started or do not exist
1315
            return 0;
1316
        }
1317
1318
        if (!is_null($userInfo) && $userInfo["role"]==3) {
1319
            return 3;
1320
        }
1321
1322
        if ($contest_info["public"]) {
1323
            //public
1324
            if ($contest_ended) {
1325
                return 1;
1326
            } else {
1327
                if ($contest_info["registration"]) {
1328
                    // check if uid in registration, temp return 3
1329
                    $isParticipant=DB::table("contest_participant")->where([
1330
                        "cid" => $cid,
1331
                        "uid" => $uid,
1332
                        "audit" => 1
1333
                    ])->count();
1334
                    if ($isParticipant) {
1335
                        return 2;
1336
                    } else {
1337
                        return 0;
1338
                    }
1339
                } else {
1340
                    return 2;
1341
                }
1342
            }
1343
        } else {
1344
            //private
1345
            $isMember=DB::table("group_member")->where([
1346
                "gid"=> $contest_info["gid"],
1347
                "uid"=> $uid
1348
            ])->where("role", ">", 0)->count();
1349
            if (!$isMember) {
1350
                return 0;
1351
            } else {
1352
                if ($contest_info["registration"]) {
1353
                    // check if uid in registration, temp return 3
1354
                    $isParticipant=DB::table("contest_participant")->where([
1355
                        "cid" => $cid,
1356
                        "uid" => $uid,
1357
                        "audit" => 1
1358
                    ])->count();
1359
                    if ($isParticipant) {
1360
                        return 2;
1361
                    } else {
1362
                        return 0;
1363
                    }
1364
                } else {
1365
                    return 2;
1366
                }
1367
            }
1368
        }
1369
    }
1370
1371
    public function judgeOutsideClearance($cid, $uid=0)
1372
    {
1373
        if (filter_var($cid, FILTER_VALIDATE_INT)===false) {
1374
            return 0;
1375
        }
1376
        $contest_info=DB::table("contest")->where("cid", $cid)->first();
1377
        if (empty($contest_info)) {
1378
            return 0;
1379
        }
1380
        if ($contest_info["public"]) {
1381
            return 1;
1382
        } else {
1383
            if ($uid==0) {
1384
                return 0;
1385
            }
1386
            return DB::table("group_member")->where([
1387
                "gid"=> $contest_info["gid"],
1388
                "uid"=> $uid
1389
            ])->where("role", ">", 0)->count() ? 1 : 0;
1390
        }
1391
    }
1392
1393
    public function contestName($cid)
1394
    {
1395
        return DB::table("contest")->where("cid", $cid)->select("name")->first()["name"];
1396
    }
1397
1398
    public function contestRule($cid)
1399
    {
1400
        return DB::table("contest")->where("cid", $cid)->select("rule")->first()["rule"];
1401
    }
1402
1403
    public function updateProfessionalRate($cid)
1404
    {
1405
        $basic=$this->basic($cid);
1406
        if ($basic["rated"] && !$basic["is_rated"]) {
1407
            $ratingCalculator=new RatingCalculator($cid);
1408
            if ($ratingCalculator->calculate()) {
1409
                $ratingCalculator->storage();
1410
                return true;
1411
            } else {
1412
                return false;
1413
            }
1414
        } else {
1415
            return false;
1416
        }
1417
    }
1418
1419
    public function contestUpdate($cid, $data, $problems)
1420
    {
1421
        if ($problems!==false) {
1422
            $old_problmes=array_column(
1423
                DB::table('contest_problem')
1424
                ->where('cid', $cid)
1425
                ->get()->all(),
1426
                'pid'
1427
            );
1428
            DB::transaction(function() use ($cid, $data, $problems, $old_problmes) {
1429
                DB::table($this->tableName)
1430
                    ->where('cid', $cid)
1431
                    ->update($data);
1432
                DB::table('contest_problem')
1433
                    ->where('cid', $cid)
1434
                    ->delete();
1435
                $new_problems=[];
1436
                foreach ($problems as $p) {
1437
                    $pid=DB::table("problem")->where(["pcode"=>$p["pcode"]])->select("pid")->first()["pid"];
1438
                    array_push($new_problems, $pid);
1439
                    DB::table("contest_problem")->insert([
1440
                        "cid"=>$cid,
1441
                        "number"=>$p["number"],
1442
                        "ncode"=>$this->intToChr($p["number"]-1),
1443
                        "pid"=>$pid,
1444
                        "alias"=>"",
1445
                        "points"=>$p["points"]
1446
                    ]);
1447
                }
1448
                foreach ($old_problmes as $op) {
1449
                    if (!in_array($op, $new_problems)) {
1450
                        DB::table('submission')
1451
                            ->where('cid', $cid)
1452
                            ->where('pid', $op)
1453
                            ->delete();
1454
                    }
1455
                }
1456
            }, 5);
1457
            $contestRankRaw=$this->contestRankCache($cid);
1458
            Cache::tags(['contest', 'rank'])->put($cid, $contestRankRaw);
1459
            Cache::tags(['contest', 'rank'])->put("contestAdmin$cid", $contestRankRaw);
1460
        } else {
1461
            DB::table($this->tableName)
1462
                ->where('cid', $cid)
1463
                ->update($data);
1464
        }
1465
    }
1466
1467
    public function contestUpdateProblem($cid, $problems)
1468
    {
1469
        DB::table('contest_problem')
1470
                ->where('cid', $cid)
1471
                ->delete();
1472
        foreach ($problems as $p) {
1473
            DB::table("contest_problem")->insertGetId([
1474
                "cid"=>$cid,
1475
                "number"=>$p["number"],
1476
                "ncode"=>$this->intToChr($p["number"]-1),
1477
                "pid"=>$p['pid'],
1478
                "alias"=>"",
1479
                "points"=>$p["points"]
1480
            ]);
1481
        }
1482
    }
1483
1484
    public function arrangeContest($gid, $config, $problems)
1485
    {
1486
        $cid=-1;
1487
        DB::transaction(function() use ($gid, $config, $problems, &$cid) {
1488
            $cid=DB::table($this->tableName)->insertGetId([
1489
                "gid"=>$gid,
1490
                "name"=>$config["name"],
1491
                "assign_uid"=>$config["assign_uid"],
1492
                "verified"=>0, //todo
1493
                "rated"=>0,
1494
                "anticheated"=>0,
1495
                "practice"=>$config["practice"],
1496
                "featured"=>0,
1497
                "description"=>$config["description"],
1498
                "rule"=>1, //todo
1499
                "begin_time"=>$config["begin_time"],
1500
                "end_time"=>$config["end_time"],
1501
                "vcid"=>isset($config["vcid"]) ? $config["vcid"] : null,
1502
                "public"=>$config["public"],
1503
                "registration"=>0, //todo
1504
                "registration_due"=>null, //todo
1505
                "registant_type"=>0, //todo
1506
                "froze_length"=>0, //todo
1507
                "status_visibility"=>$config["status_visibility"],
1508
                "created_at"=>date("Y-m-d H:i:s"),
1509
                "crawled" => isset($config['vcid']) ? $config['crawled'] : null,
1510
                "audit_status"=>$config["public"] ? 0 : 1
1511
            ]);
1512
1513
            foreach ($problems as $p) {
1514
                $pid=DB::table("problem")->where(["pcode"=>$p["pcode"]])->select("pid")->first()["pid"];
1515
                DB::table("contest_problem")->insert([
1516
                    "cid"=>$cid,
1517
                    "number"=>$p["number"],
1518
                    "ncode"=>$this->intToChr($p["number"]-1),
1519
                    "pid"=>$pid,
1520
                    "alias"=>"",
1521
                    "points"=>$p["points"]
1522
                ]);
1523
            }
1524
        }, 5);
1525
        return $cid;
1526
    }
1527
1528
    public function updateContestRankTable($cid, $sub)
1529
    {
1530
        $lock=Cache::lock("contestrank$cid", 10);
1531
        try {
1532
            if ($lock->get()) {
1533
                if (Cache::tags(['contest', 'rank'])->get($cid)!=null) {
1534
                    $ret=Cache::tags(['contest', 'rank'])->get($cid);
1535
                    $chache=[];
1536
                    $chache['contest_info']=DB::table("contest")->where("cid", $cid)->first();
1537
                    $chache['problemSet']=DB::table("contest_problem")->join("problem", "contest_problem.pid", "=", "problem.pid")->where([
1538
                        "cid"=>$cid
1539
                    ])->orderBy('number', 'asc')->select("ncode", "alias", "contest_problem.pid as pid", "title")->get()->all();
1540
                    $chache['frozen_time']=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
1541
                    $chache['end_time']=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
1542
1543
                    $id=0;
1544
1545
                    foreach ($chache['problemSet'] as $key => $p) {
1546
                        if ($p['pid']==$sub['pid']) {
1547
                            $chache['problemSet'][$key]['cpid']=$key;
1548
                            $id=$key;
1549
                        }
1550
                    }
1551
1552
                    $ret=$this->updateContestRankDetail($chache['contest_info'], $chache['problemSet'][$id], $cid, $sub['uid'], $ret);
1553
                    $ret=$this->sortContestRankTable($chache['contest_info'], $cid, $ret);
1554
1555
                    if (time()<$chache['frozen_time']) {
1556
                        Cache::tags(['contest', 'rank'])->put($cid, $ret);
1557
                    }
1558
                    Cache::tags(['contest', 'rank'])->put("contestAdmin$cid", $ret);
1559
                    if (time()>$chache['end_time']) {
1560
                        $this->storeContestRankInMySQL($cid, $ret);
1561
                    }
1562
                } else {
1563
                    $ret=[];
1564
                    $chache=[];
1565
                    $chache['contest_info']=DB::table("contest")->where("cid", $cid)->first();
1566
                    $chache['problemSet']=DB::table("contest_problem")->join("problem", "contest_problem.pid", "=", "problem.pid")->where([
1567
                        "cid"=>$cid
1568
                    ])->orderBy('number', 'asc')->select("ncode", "alias", "contest_problem.pid as pid", "title")->get()->all();
1569
                    $chache['frozen_time']=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"];
1570
                    $chache['end_time']=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
1571
1572
                    if ($chache['contest_info']["registration"]) {
1573
                        $submissionUsers=DB::table("contest_participant")->where([
1574
                            "cid"=>$cid,
1575
                            "audit"=>1
1576
                        ])->select('uid')->get()->all();
1577
                    } else {
1578
                        $submissionUsers=DB::table("submission")->where([
1579
                            "cid"=>$cid
1580
                        ])->where(
1581
                            "submission_date",
1582
                            "<",
1583
                            $chache['frozen_time']
1584
                        )->select('uid')->groupBy('uid')->get()->all();
1585
                        $submissionUsersAdmin=DB::table("submission")->where([
1586
                            "cid"=>$cid
1587
                        ])->select('uid')->groupBy('uid')->get()->all();
1588
                    }
1589
1590
                    $chacheAdmin=$chache;
1591
1592
                    foreach ($submissionUsers as $s) {
1593
                        foreach ($chache['problemSet'] as $key => $p) {
1594
                            $p['cpid']=$key;
1595
                            $ret=$this->updateContestRankDetail($chache['contest_info'], $p, $cid, $s['uid'], $ret);
1596
                        }
1597
                    }
1598
                    $ret=$this->sortContestRankTable($chache['contest_info'], $cid, $ret);
1599
                    Cache::tags(['contest', 'rank'])->put($cid, $ret);
1600
1601
                    $retAdmin=[];
1602
                    foreach ($submissionUsersAdmin as $s) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $submissionUsersAdmin does not seem to be defined for all execution paths leading up to this point.
Loading history...
1603
                        foreach ($chacheAdmin['problemSet'] as $key => $p) {
1604
                            $p['cpid']=$key;
1605
                            $retAdmin=$this->updateContestRankDetail($chacheAdmin['contest_info'], $p, $cid, $s['uid'], $retAdmin);
1606
                        }
1607
                    }
1608
                    $retAdmin=$this->sortContestRankTable($chacheAdmin['contest_info'], $cid, $retAdmin);
1609
                    Cache::tags(['contest', 'rank'])->put("contestAdmin$cid", $retAdmin);
1610
                }
1611
            }
1612
        } catch (LockTimeoutException $e) {
1613
            Log::warning("Contest Rank Lock Timed Out");
1614
        } finally {
1615
            optional($lock)->release();
1616
        }
1617
    }
1618
1619
    public function sortContestRankTable($contest_info, $cid, $ret)
0 ignored issues
show
Unused Code introduced by
The parameter $cid 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

1619
    public function sortContestRankTable($contest_info, /** @scrutinizer ignore-unused */ $cid, $ret)

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...
1620
    {
1621
        if ($contest_info["rule"]==1) {
1622
            usort($ret, function($a, $b) {
1623
                if ($a["score"]==$b["score"]) {
1624
                    if ($a["penalty"]==$b["penalty"]) {
1625
                        return 0;
1626
                    } elseif (($a["penalty"]>$b["penalty"])) {
1627
                        return 1;
1628
                    } else {
1629
                        return -1;
1630
                    }
1631
                } elseif ($a["score"]>$b["score"]) {
1632
                    return -1;
1633
                } else {
1634
                    return 1;
1635
                }
1636
            });
1637
        } else if ($contest_info["rule"]==2) {
1638
            usort($ret, function($a, $b) {
1639
                if ($a["score"]==$b["score"]) {
1640
                    if ($a["solved"]==$b["solved"]) {
1641
                        return 0;
1642
                    } elseif (($a["solved"]<$b["solved"])) {
1643
                        return 1;
1644
                    } else {
1645
                        return -1;
1646
                    }
1647
                } elseif ($a["score"]>$b["score"]) {
1648
                    return -1;
1649
                } else {
1650
                    return 1;
1651
                }
1652
            });
1653
        }
1654
        return $ret;
1655
    }
1656
1657
    public function updateContestRankDetail($contest_info, $problem, $cid, $uid, $ret)
1658
    {
1659
        $id=count($ret);
1660
        foreach ($ret as $key => $r) {
1661
            if ($r['uid']==$uid) {
1662
                            $id=$key;
1663
            }
1664
        }
1665
        if ($contest_info["rule"]==1) {
1666
            // ACM/ICPC Mode
1667
            if ($id==count($ret)) {
1668
                $prob_detail=[];
1669
                $totPen=0;
1670
                $totScore=0;
1671
            } else {
1672
                $prob_detail=$ret[$id]['problem_detail'];
1673
                $totPen=$ret[$id]['penalty'];
1674
                $totScore=$ret[$id]['score'];
1675
            };
1676
1677
            $ac_times=DB::table("submission")->where([
1678
                "cid"=>$cid,
1679
                "pid"=>$problem['pid'],
1680
                "uid"=>$uid,
1681
                "verdict"=>"Accepted"
1682
            ])->count();
1683
1684
            $last_record=DB::table("submission")->where([
1685
                "cid"=>$cid,
1686
                "pid"=>$problem['pid'],
1687
                "uid"=>$uid,
1688
            ])->orderBy('submission_date', 'desc')->first();
1689
1690
            if ($ac_times<=1 && isset($last_record) && $last_record['verdict']!="Waiting" && $last_record['verdict']!="Submission Error" && $last_record['verdict']!="System Error") {
1691
                $prob_stat=$this->contestProblemInfoACM($cid, $problem["pid"], $uid);
1692
1693
                $prob_detail[$problem['cpid']]=[
1694
                    "ncode"=>$problem["ncode"],
1695
                    "pid"=>$problem["pid"],
1696
                    "color"=>$prob_stat["color"],
1697
                    "wrong_doings"=>$prob_stat["wrong_doings"],
1698
                    "solved_time_parsed"=>$prob_stat["solved_time_parsed"]
1699
                ];
1700
                if ($prob_stat["solved"]) {
1701
                    $totPen+=$prob_stat["wrong_doings"] * 20;
1702
                    $totPen+=$prob_stat["solved_time"] / 60;
1703
                    $totScore+=$prob_stat["solved"];
1704
                }
1705
1706
                $nickName=DB::table("group_member")->where([
1707
                    "uid" => $uid,
1708
                    "gid" => $contest_info["gid"]
1709
                ])->where("role", ">", 0)->first();
1710
                $nickName=is_null($nickName) ?null:$nickName["nick_name"];
1711
1712
                $ret[$id]=[
1713
                    "uid" => $uid,
1714
                    "name" => DB::table("users")->where([
1715
                        "id"=>$uid
1716
                    ])->first()["name"],
1717
                    "nick_name" => $nickName,
1718
                    "score" => $totScore,
1719
                    "penalty" => $totPen,
1720
                    "problem_detail" => $prob_detail
1721
                ];
1722
            }
1723
        } elseif ($contest_info["rule"]==2) {
1724
            // IOI Mode
1725
            if ($id==count($ret)) {
1726
                $prob_detail=[];
1727
                $totSolved=0;
1728
                $totScore=0;
1729
            } else {
1730
                $prob_detail=$ret[$id]['problem_detail'];
1731
                $totSolved=$ret[$id]['solved'];
1732
                $totScore=$ret[$id]['score'];
1733
            };
1734
1735
            $prob_stat=$this->contestProblemInfoIOI($cid, $problem["pid"], $uid);
1736
            $prob_detail[$problem['cpid']]=[
1737
                "ncode"=>$problem["ncode"],
1738
                "pid"=>$problem["pid"],
1739
                "color"=>$prob_stat["color"],
1740
                "score"=>$prob_stat["score"],
1741
                "score_parsed"=>$prob_stat["score_parsed"]
1742
            ];
1743
            $totSolved+=$prob_stat["solved"];
1744
            $totScore+=intval($prob_stat["score_parsed"]);
1745
1746
            $nickName=DB::table("group_member")->where([
1747
                "uid" => $uid,
1748
                "gid" => $contest_info["gid"]
1749
            ])->where("role", ">", 0)->first();
1750
            $nickName=is_null($nickName) ?null:$nickName["nick_name"];
1751
1752
            $ret[$id]=[
1753
                "uid" => $uid,
1754
                "name" => DB::table("users")->where([
1755
                    "id"=> $uid
1756
                ])->first()["name"],
1757
                "nick_name" => $nickName,
1758
                "score" => $totScore,
1759
                "solved" => $totSolved,
1760
                "problem_detail" => $prob_detail
1761
            ];
1762
        }
1763
        return $ret;
1764
    }
1765
1766
    public function assignMember($cid, $uid) {
1767
        return DB::table("contest")->where(["cid"=>$cid])->update([
1768
            "assign_uid"=>$uid
1769
        ]);
1770
    }
1771
1772
    public function canUpdateContestTime($cid, $time=[])
1773
    {
1774
        $begin_time_new=$time['begin'] ?? null;
1775
        $end_time_new=$time['end'] ?? null;
1776
1777
        $hold_time=DB::table('contest')
1778
            ->where('cid', $cid)
1779
            ->select('begin_time', 'end_time')
1780
            ->first();
1781
        $begin_stamps=strtotime($hold_time['begin_time']);
1782
        $end_stamps=strtotime($hold_time['end_time']);
1783
        /*
1784
        -1 : have not begun
1785
         0 : ing
1786
         1 : end
1787
        */
1788
        $status=time()>=$end_stamps ? 1
1789
                : (time()<=$begin_stamps ? -1 : 0);
1790
        if ($status===-1) {
1791
            if (time()>$begin_time_new) {
1792
                return false;
1793
            }
1794
            return true;
1795
        } else if ($status===0) {
1796
            if ($begin_time_new!==null) {
1797
                return false;
1798
            }
1799
            if ($end_time_new!==null) {
1800
                if (strtotime($end_time_new)<=time()) {
1801
                    return false;
1802
                } else {
1803
                    return true;
1804
                }
1805
            }
1806
        } else {
1807
            return false;
1808
        }
1809
1810
        return true;
1811
    }
1812
1813
    public function replyClarification($ccid, $content)
1814
    {
1815
        return DB::table("contest_clarification")->where('ccid', '=', $ccid)->update([
1816
            "reply"=>$content
1817
        ]);
1818
    }
1819
1820
    public function setClarificationPublic($ccid, $public)
1821
    {
1822
        if ($public)
1823
        {
1824
            return DB::table("contest_clarification")->where('ccid', '=', $ccid)->update([
1825
                "public"=>1
1826
            ]);
1827
        } else
1828
        {
1829
            return DB::table("contest_clarification")->where('ccid', '=', $ccid)->update([
1830
                "public"=>0
1831
            ]);
1832
        }
1833
    }
1834
1835
    public function getContestAccount($cid)
1836
    {
1837
        return Cache::tags(['contest', 'account'])->get($cid);
1838
    }
1839
1840
    public function praticeAnalysis($cid)
1841
    {
1842
        $gid=DB::table('contest')
1843
            ->where('cid', $cid)
1844
            ->first()['gid'];
1845
        $contestRank=$this->contestRank($cid, Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
1846
        if (!empty($contestRank)) {
1847
            $all_problems=DB::table('problem')
1848
            ->whereIn('pid', array_column($contestRank[0]['problem_detail'], 'pid'))
1849
            ->select('pid', 'title')
1850
            ->get()->all();
1851
        } else {
1852
            $all_problems=[];
1853
        }
1854
        $tags=DB::table('group_problem_tag')
1855
            ->where('gid', $gid)
1856
            ->whereIn('pid', array_column($all_problems, 'pid'))
1857
            ->get()->all();
1858
        $all_tags=array_unique(array_column($tags, 'tag'));
1859
        $memberData=[];
1860
        foreach ($contestRank as $member) {
1861
            $m=[
1862
                'uid' => $member['uid'],
1863
                'name' => $member['name'],
1864
                'nick_name' => $member['nick_name'],
1865
            ];
1866
            $completion=[];
1867
            foreach ($all_tags as $tag) {
1868
                $completion[$tag]=[];
1869
                foreach ($tags as $t) {
1870
                    if ($t['tag']==$tag) {
1871
                        foreach ($member['problem_detail'] as $pd) {
1872
                            if ($pd['pid']==$t['pid']) {
1873
                                $completion[$tag][$t['pid']]=$pd['solved_time_parsed']=="" ? 0 : 1;
1874
                            }
1875
                        }
1876
                    }
1877
                }
1878
            }
1879
            $m['completion']=$completion;
1880
            $memberData[]=$m;
1881
        }
1882
        return $memberData;
1883
    }
1884
1885
    public function storeContestRankInMySQL($cid, $data)
1886
    {
1887
        $contestRankJson=json_encode($data);
1888
        return DB::table('contest')->where('cid', '=', $cid)->update([
1889
            'rank' => $contestRankJson
1890
        ]);
1891
    }
1892
1893
    public function getContestRankFromMySQL($cid)
1894
    {
1895
        $contestRankJson=DB::table('contest')->where('cid', '=', $cid)->pluck('rank')->first();
1896
        $data=json_decode($contestRankJson, true);
1897
        return $data;
1898
    }
1899
1900
    public function isVerified($cid)
1901
    {
1902
        return DB::table('contest')->where('cid', '=', $cid)->pluck('verified')->first();
1903
    }
1904
1905
    public function getScrollBoardData($cid)
1906
    {
1907
        $members=DB::table("contest_participant")->where([
1908
            "cid"=>$cid,
1909
            "audit"=>1
1910
        ])->leftjoin('users', 'users.id', '=', 'contest_participant.uid')->select('users.id as uid', 'users.name as name', DB::raw('NULL AS nick_name'))->get()->all();
1911
        $submissions=DB::table("submission")
1912
            ->where('cid', $cid)
1913
            ->select('sid', 'verdict', 'submission_date', 'pid', 'uid')
1914
            ->orderBy('submission_date')
1915
            ->get()->all();
1916
        $problems=DB::table('contest_problem')
1917
            ->where('cid', $cid)
1918
            ->select('ncode', 'pid')
1919
            ->orderBy('ncode')
1920
            ->get()->all();
1921
        $contest=DB::table('contest')
1922
            ->where('cid', $cid)
1923
            ->select('begin_time', 'end_time', 'froze_length')
1924
            ->first();
1925
        return [
1926
            'members' => $members,
1927
            'submissions' => $submissions,
1928
            'problems' => $problems,
1929
            'contest' => $contest,
1930
        ];
1931
    }
1932
1933
    public function storageCode($path, $cid)
1934
    {
1935
1936
        Storage::disk("private")->makeDirectory($path);
1937
1938
        //example:A-The 3n + 1 problem-UVa100
1939
1940
        $contest_problems=DB::table("contest_problem")->where([
1941
            "cid"=>$cid
1942
        ])->get();
1943
        $problem_info=array();
1944
        foreach ($contest_problems as $contest_problem) {
1945
            $problem_info[$contest_problem["pid"]]=DB::table("problem")->where([
1946
                "pid"=>$contest_problem["pid"]
1947
            ])->first();
1948
            $problem_info[$contest_problem["pid"]]["ncode"]=$contest_problem["ncode"];
1949
            $problem_info[$contest_problem["pid"]]["path"]=$problem_info[$contest_problem["pid"]]["ncode"]."-".$problem_info[$contest_problem["pid"]]["pcode"]."-".$problem_info[$contest_problem["pid"]]["title"];
1950
            Storage::disk("private")->makeDirectory($path."/".urlencode($problem_info[$contest_problem["pid"]]["path"])."/");
1951
        }
1952
1953
        $compilers=DB::table("compiler")->get();
1954
        $language=array();
1955
        foreach ($compilers as $compiler) {
1956
            $language[$compiler["coid"]]=$compiler["lang"];
1957
        }
1958
1959
        //example:12345-admin-A-Accepted.cpp
1960
1961
        $submissions=DB::table("submission")->where([
1962
            "cid"=>$cid,
1963
        ])->get();
1964
        foreach ($submissions as $submission) {
1965
            $user_name=DB::table("users")->where([
1966
                "id"=>$submission["uid"]
1967
            ])->first();
1968
            $SubmissionModel=new SubmissionModel();
1969
            $suffix_name=isset($SubmissionModel->langConfig[$language[$submission["coid"]]]) ? $SubmissionModel->langConfig[$language[$submission["coid"]]]["extensions"][0] : $SubmissionModel->langConfig["plaintext"]["extensions"][0];
1970
            //die($submission["sid"]);
1971
            $file_name=(string) ($submission["sid"])."-".$user_name["name"]."-".$problem_info[$submission["pid"]]["ncode"]."-".$submission["verdict"].$suffix_name;
1972
            Storage::disk("private")->put($path."/".urlencode($problem_info[$submission["pid"]]["path"])."/".$file_name, $submission["solution"]);
1973
        }
1974
    }
1975
1976
    public function deleteZip($path)
1977
    {
1978
        Storage::disk("private")->deleteDirectory($path);
1979
    }
1980
1981
    public function GenerateZip($path, $cid, $code_path, $outputFilename)
0 ignored issues
show
Unused Code introduced by
The parameter $outputFilename 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

1981
    public function GenerateZip($path, $cid, $code_path, /** @scrutinizer ignore-unused */ $outputFilename)

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...
1982
    {
1983
        Storage::disk("private")->deleteDirectory($code_path);
1984
1985
        $this->storageCode($code_path, $cid);
1986
1987
        Storage::disk("private")->makeDirectory($path);
1988
1989
        // create new archive
1990
        $zipFile=new \PhpZip\ZipFile();
1991
        $directories=Storage::disk("private")->allDirectories($code_path);
1992
        try {
1993
            foreach ($directories as $directorie)
1994
            {
1995
1996
                preg_match("/contestCode\/\d+(.*)/", $directorie, $problem_name);
1997
                $zipFile->addDir(base_path('storage/app/private/'.$directorie), urldecode($problem_name[1])); // add files from the directory
1998
            }
1999
            $zipFile
2000
                ->saveAsFile(base_path('storage/app/private/'.$path.$cid.".zip")); // save the archive to a file
2001
                //->extractTo(base_path('storage/app/private/'.$path)); // extract files to the specified directory
2002
        } catch (\PhpZip\Exception\ZipException $e) {
2003
            // handle exception
2004
            Log::debug($e);
2005
        } finally {
2006
            $zipFile->close();
2007
        }
2008
    }
2009
2010
    public function zipName($cid)
2011
    {
2012
        //example:12345-name-2019-08-15 20:41:00.zip
2013
2014
        $contest=DB::table("contest")->where([
2015
            "cid"=>$cid
2016
        ])->first();
2017
        return $outputFilename=(string) ($contest["cid"])."-".$contest["name"].".zip";
0 ignored issues
show
Unused Code introduced by
The assignment to $outputFilename is dead and can be removed.
Loading history...
2018
    }
2019
2020
    public function judgeOver($cid)
2021
    {
2022
        $submissions=DB::table('submission')
2023
            ->where(['cid' => $cid])
2024
            ->whereIn('verdict', ['Waiting', 'Pending'])
2025
            ->select('sid')
2026
            ->get()->all();
2027
        if (empty($submissions)) {
2028
            return [
2029
                'result' => true
2030
            ];
2031
        } else {
2032
            return [
2033
                'result' => false,
2034
                'sid' => $submissions
2035
            ];
2036
        }
2037
    }
2038
}
2039