Issues (563)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

app/Models/ContestModel.php (18 issues)

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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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