Passed
Push — master ( f7976d...1a53ec )
by John
04:45 queued 11s
created

ProblemModel::isHidden()   A

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 GrahamCampbell\Markdown\Facades\Markdown;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Support\Facades\DB;
8
use App\Models\Submission\SubmissionModel;
9
use Cache;
10
11
class ProblemModel extends Model
12
{
13
    protected $table='problem';
14
    protected $primaryKey='pid';
15
    const UPDATED_AT="update_date";
16
17
    public function detail($pcode, $cid=null)
18
    {
19
        $prob_detail=DB::table($this->table)->where("pcode", $pcode)->first();
20
        // [Depreciated] Joint Query was depreciated here for code maintenance reasons
21
        if (!is_null($prob_detail)) {
22
            if ($prob_detail["force_raw"]) {
23
                $prob_detail["parsed"]=[
24
                    "description"=>$prob_detail["description"],
25
                    "input"=>$prob_detail["input"],
26
                    "output"=>$prob_detail["output"],
27
                    "note"=>$prob_detail["note"]
28
                ];
29
            } elseif ($prob_detail["markdown"]) {
30
                $prob_detail["parsed"]=[
31
                    "description"=>clean(convertMarkdownToHtml($prob_detail["description"])),
32
                    "input"=>clean(convertMarkdownToHtml($prob_detail["input"])),
33
                    "output"=>clean(convertMarkdownToHtml($prob_detail["output"])),
34
                    "note"=>clean(convertMarkdownToHtml($prob_detail["note"]))
35
                ];
36
            } else {
37
                $prob_detail["parsed"]=[
38
                    "description"=>$prob_detail["description"],
39
                    "input"=>$prob_detail["input"],
40
                    "output"=>$prob_detail["output"],
41
                    "note"=>$prob_detail["note"]
42
                ];
43
            }
44
            $prob_detail["update_date"]=date_format(date_create($prob_detail["update_date"]), 'm/d/Y H:i:s');
45
            $prob_detail["oj_detail"]=DB::table("oj")->where("oid", $prob_detail["OJ"])->first();
46
            $prob_detail["samples"]=DB::table("problem_sample")->where("pid", $prob_detail["pid"])->get()->all();
47
            $prob_detail["tags"]=DB::table("problem_tag")->where("pid", $prob_detail["pid"])->get()->all();
48
            if ($cid) {
49
                $frozen_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
50
                $prob_stat=DB::table("submission")->select(
51
                    DB::raw("count(sid) as submission_count"),
52
                    DB::raw("sum(verdict='accepted') as passed_count"),
53
                    DB::raw("sum(verdict='accepted')/count(sid)*100 as ac_rate")
54
                )->where([
55
                    "pid"=>$prob_detail["pid"],
56
                    "cid"=>$cid,
57
                ])->where("submission_date", "<", $frozen_time)->first();
58
                $prob_detail['vcid']=DB::table("contest")->where(["cid"=>$cid])->select("vcid")->first()['vcid'];
59
                $prob_detail["points"]=DB::table("contest_problem")->where(["cid"=>$cid, "pid"=>$prob_detail["pid"]])->select("points")->first()["points"];
60
            } else {
61
                $prob_stat=DB::table("submission")->select(
62
                    DB::raw("count(sid) as submission_count"),
63
                    DB::raw("sum(verdict='accepted') as passed_count"),
64
                    DB::raw("sum(verdict='accepted')/count(sid)*100 as ac_rate")
65
                )->where(["pid"=>$prob_detail["pid"]])->first();
66
                $prob_detail['vcid']=null;
67
                $prob_detail["points"]=0;
68
            }
69
            if ($prob_stat["submission_count"]==0) {
70
                $prob_detail["submission_count"]=0;
71
                $prob_detail["passed_count"]=0;
72
                $prob_detail["ac_rate"]=0;
73
            } else {
74
                $prob_detail["submission_count"]=$prob_stat["submission_count"];
75
                $prob_detail["passed_count"]=$prob_stat["passed_count"];
76
                $prob_detail["ac_rate"]=round($prob_stat["ac_rate"], 2);
77
            }
78
        }
79
        return $prob_detail;
80
    }
81
82
    public function basic($pid)
83
    {
84
        return DB::table($this->table)->where("pid", $pid)->first();
85
    }
86
87
    public function tags()
88
    {
89
        return DB::table("problem_tag")->groupBy('tag')->select("tag", DB::raw('count(*) as tag_count'))->orderBy('tag_count', 'desc')->limit(12)->get()->all();
90
    }
91
92
    public function ojs()
93
    {
94
        return DB::table("oj")->orderBy('oid', 'asc')->limit(12)->get()->all();
95
    }
96
97
    public function ojdetail($oid)
98
    {
99
        return DB::table("oj")->where('oid', $oid)->first();
100
    }
101
102
    public function solutionList($pid, $uid=null)
103
    {
104
        if (is_null($uid)) {
105
            $details=DB::table("problem_solution")->join(
106
                "users",
107
                "id",
108
                "=",
109
                "problem_solution.uid"
110
            )->where([
111
                'problem_solution.pid'=>$pid,
112
                'problem_solution.audit'=>1
113
            ])->orderBy(
114
                "problem_solution.votes",
115
                "desc"
116
            )->get()->all();
117
        } else {
118
            $votes=DB::table("problem_solution_vote")->where([
119
                "uid"=>$uid
120
            ])->get()->all();
121
            foreach ($votes as $v) {
122
                $userVotes[$v["psoid"]]=$v["type"];
123
            }
124
            $details=DB::table("problem_solution")->join(
125
                "users",
126
                "id",
127
                "=",
128
                "problem_solution.uid"
129
            )->where([
130
                'problem_solution.pid'=>$pid,
131
                'problem_solution.audit'=>1
132
            ])->select([
133
                "problem_solution.psoid as psoid",
134
                "problem_solution.uid as uid",
135
                "problem_solution.pid as pid",
136
                "problem_solution.content as content",
137
                "problem_solution.audit as audit",
138
                "problem_solution.votes as votes",
139
                "problem_solution.created_at as created_at",
140
                "problem_solution.updated_at as updated_at",
141
                "avatar",
142
                "name"
143
            ])->orderBy("problem_solution.votes", "desc")->get()->all();
144
            foreach ($details as &$d) {
145
                $d["type"]=isset($userVotes[$d["psoid"]]) ? $userVotes[$d["psoid"]] : null;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $userVotes seems to be defined by a foreach iteration on line 121. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
146
            }
147
            unset($d);
148
        }
149
        foreach ($details as &$d) {
150
            $d["content_parsed"]=clean(convertMarkdownToHtml($d["content"]));
151
        }
152
        return $details;
153
    }
154
155
    public function solution($pid, $uid)
156
    {
157
        $details=DB::table("problem_solution")->join("users", "id", "=", "uid")->where(['pid'=>$pid, 'uid'=>$uid])->first();
158
        return $details;
159
    }
160
161
    public function addSolution($pid, $uid, $content)
162
    {
163
        $details=DB::table("problem_solution")->where(['pid'=>$pid, 'uid'=>$uid])->first();
164
        if (empty($details)) {
165
            DB::table("problem_solution")->insert([
166
                "uid"=>$uid,
167
                "pid"=>$pid,
168
                "content"=>$content,
169
                "votes"=>0,
170
                "audit"=>$this->inteliAudit($uid, $content),
171
                "created_at"=>date("Y-m-d H:i:s"),
172
                "updated_at"=>date("Y-m-d H:i:s"),
173
            ]);
174
            return true;
175
        }
176
        return false;
177
    }
178
179
    private function inteliAudit($uid, $content)
180
    {
181
        if (strpos($content, '```')!==false){
182
            $userSolutionHistory=DB::table("problem_solution")->where(['uid'=>$uid])->orderByDesc('updated_at')->first();
183
            if (!empty($userSolutionHistory) && $userSolutionHistory["audit"]==1){
184
                return 1;
185
            }
186
        }
187
        return 0;
188
    }
189
190
    public function voteSolution($psoid, $uid, $type)
191
    {
192
        $val=$type ? 1 : -1;
193
        $details=DB::table("problem_solution")->where(['psoid'=>$psoid])->first();
194
        if (empty($details)) {
195
            return ["ret"=>false];
196
        }
197
198
        $userVote=DB::table("problem_solution_vote")->where(['uid'=>$uid, "psoid"=>$psoid])->first();
199
200
        if (!empty($userVote)) {
201
            DB::table("problem_solution_vote")->where(['uid'=>$uid, "psoid"=>$psoid])->delete();
202
            if ($userVote["type"]==$type) {
203
                DB::table("problem_solution")->where([
204
                    'psoid'=>$psoid
205
                ])->update([
206
                    "votes"=>$details["votes"]+($userVote["type"]==1 ?-1 : 1),
207
                ]);
208
                return ["ret"=>true, "votes"=>$details["votes"]+($userVote["type"]==1 ?-1 : 1), "select"=>-1]; //disvote
209
            } elseif ($userVote["type"]==1) {
210
                $val--;
211
            } else {
212
                $val++;
213
            }
214
        }
215
216
        DB::table("problem_solution")->where([
217
            'psoid'=>$psoid
218
        ])->update([
219
            "votes"=>$details["votes"]+$val,
220
        ]);
221
222
        DB::table("problem_solution_vote")->insert([
223
            "uid"=>$uid,
224
            "psoid"=>$psoid,
225
            "type"=>$type,
226
        ]);
227
228
        return ["ret"=>true, "votes"=>$details["votes"]+$val, "select"=>$type];
229
    }
230
231
    public function removeSolution($psoid, $uid)
232
    {
233
        if (empty(DB::table("problem_solution")->where(['psoid'=>$psoid, 'uid'=>$uid])->first())) {
234
            return false;
235
        }
236
        DB::table("problem_solution")->where(['psoid'=>$psoid, 'uid'=>$uid])->delete();
237
        return true;
238
    }
239
240
    public function updateSolution($psoid, $uid, $content)
241
    {
242
        if (empty(DB::table("problem_solution")->where(['psoid'=>$psoid, 'uid'=>$uid])->first())) {
243
            return false;
244
        }
245
        DB::table("problem_solution")->where(['psoid'=>$psoid, 'uid'=>$uid])->update([
246
            "content"=>$content,
247
            "audit"=>$this->inteliAudit($uid, $content),
248
            "updated_at"=>date("Y-m-d H:i:s"),
249
        ]);
250
        return true;
251
    }
252
253
    public function isBlocked($pid, $cid=null)
254
    {
255
        $conflictContests=DB::table("contest")
256
                            ->join("contest_problem", "contest.cid", "=", "contest_problem.cid")
257
                            ->where("end_time", ">", date("Y-m-d H:i:s"))
258
                            ->where(["verified"=>1, "pid"=>$pid])
259
                            ->select(["contest_problem.cid as cid"])
260
                            ->get()
261
                            ->all();
262
        if (empty($conflictContests)) {
263
            return false;
264
        }
265
        foreach ($conflictContests as $c) {
266
            if ($cid==$c["cid"]) {
267
                return false;
268
            }
269
        }
270
        // header("HTTP/1.1 403 Forbidden");
271
        // exit();
272
        return true;
273
    }
274
275
    public function list($filter, $uid=null)
276
    {
277
        // $prob_list = DB::table($this->table)->select("pid","pcode","title")->get()->all(); // return a array
278
        $submissionModel=new SubmissionModel();
279
        $preQuery=DB::table($this->table)->where('hide','=',0);
280
        if ($filter['oj']) {
281
            $preQuery=$preQuery->where(["OJ"=>$filter['oj']]);
282
        }
283
        if ($filter['tag']) {
284
            $preQuery=$preQuery->join("problem_tag", "problem.pid", "=", "problem_tag.pid")->where(["tag"=>$filter['tag']]);
285
        }
286
        $paginator=$preQuery->select("problem.pid as pid", "pcode", "title")->orderBy(
287
            "OJ",
288
            "ASC"
289
        )->orderBy(
290
            DB::raw("length(contest_id)"),
291
            "ASC"
292
        )->orderBy(
293
            "contest_id",
294
            "ASC"
295
        )->orderBy(
296
            DB::raw("length(index_id)"),
297
            "ASC"
298
        )->orderBy(
299
            "index_id",
300
            "ASC"
301
        )->orderBy(
302
            "pcode",
303
            "ASC"
304
        )->paginate(20);
305
        $prob_list=$paginator->all();
306
307
        if (empty($prob_list)) {
308
            return null;
309
        }
310
        foreach ($prob_list as &$p) {
311
            $prob_stat=DB::table("submission")->select(
312
                DB::raw("count(sid) as submission_count"),
313
                DB::raw("sum(verdict='accepted') as passed_count"),
314
                DB::raw("sum(verdict='accepted')/count(sid)*100 as ac_rate")
315
            )->where(["pid"=>$p["pid"]])->first();
316
            if ($prob_stat["submission_count"]==0) {
317
                $p["submission_count"]=0;
318
                $p["passed_count"]=0;
319
                $p["ac_rate"]=0;
320
            } else {
321
                $p["submission_count"]=$prob_stat["submission_count"];
322
                $p["passed_count"]=$prob_stat["passed_count"];
323
                $p["ac_rate"]=round($prob_stat["ac_rate"], 2);
324
            }
325
            if (!is_null($uid)) {
326
                $prob_status=$submissionModel->getProblemStatus($p["pid"], $uid);
327
                if (empty($prob_status)) {
328
                    $p["prob_status"]=[
329
                        "icon"=>"checkbox-blank-circle-outline",
330
                        "color"=>"wemd-grey-text"
331
                    ];
332
                } else {
333
                    $p["prob_status"]=[
334
                        "icon"=>$prob_status["verdict"]=="Accepted" ? "checkbox-blank-circle" : "cisco-webex",
335
                        "color"=>$prob_status["color"]
336
                    ];
337
                }
338
            } else {
339
                $p["prob_status"]=[
340
                    "icon"=>"checkbox-blank-circle-outline",
341
                    "color"=>"wemd-grey-text"
342
                ];
343
            }
344
        }
345
        return [
346
            'paginator' => $paginator,
347
            'problems' => $prob_list,
348
        ];
349
    }
350
351
    public function existPCode($pcode)
352
    {
353
        $temp=DB::table($this->table)->where(["pcode"=>$pcode])->select("pcode")->first();
354
        return empty($temp) ? null : $temp["pcode"];
355
    }
356
357
    public function pid($pcode)
358
    {
359
        $temp=DB::table($this->table)->where(["pcode"=>$pcode])->select("pid")->first();
360
        return empty($temp) ? 0 : $temp["pid"];
361
    }
362
363
    public function pcode($pid)
364
    {
365
        $temp=DB::table($this->table)->where(["pid"=>$pid])->select("pcode")->first();
366
        return empty($temp) ? 0 : $temp["pcode"];
367
    }
368
369
    public function ocode($pid)
370
    {
371
        $temp=DB::table($this->table)->where(["pid"=>$pid])->select("OJ as oid")->first();
372
        return empty($temp) ? null : DB::table("oj")->where(["oid"=>$temp["oid"]])->select("ocode")->first()["ocode"];
373
    }
374
375
    public function oid($pid)
376
    {
377
        return DB::table($this->table)->where(["pid"=>$pid])->select("OJ as oid")->first()["oid"];
378
    }
379
380
    public function clearTags($pid)
381
    {
382
        DB::table("problem_tag")->where(["pid"=>$pid])->delete();
383
        return true;
384
    }
385
386
    public function addTags($pid, $tag)
387
    {
388
        DB::table("problem_tag")->insert(["pid"=>$pid, "tag"=>$tag]);
389
        return true;
390
    }
391
392
    public function getSolvedCount($oid)
393
    {
394
        return DB::table($this->table)->select("pid", "solved_count")->where(["OJ"=>$oid])->get()->all();
395
    }
396
397
    public function updateDifficulty($pid, $diff_level)
398
    {
399
        DB::table("problem_tag")->where(["pid"=>$pid])->update(["difficulty"=>$diff_level]);
400
        return true;
401
    }
402
403
    public function insertProblem($data)
404
    {
405
        $pid=DB::table($this->table)->insertGetId([
406
            'difficulty'=>-1,
407
            'file'=>$data['file'],
408
            'title'=>$data['title'],
409
            'time_limit'=>$data['time_limit'],
410
            'memory_limit'=>$data['memory_limit'],
411
            'OJ'=>$data['OJ'],
412
            'description'=>$data['description'],
413
            'input'=>$data['input'],
414
            'output'=>$data['output'],
415
            'note'=>$data['note'],
416
            'input_type'=>$data['input_type'],
417
            'output_type'=>$data['output_type'],
418
            'pcode'=>$data['pcode'],
419
            'contest_id'=>$data['contest_id'],
420
            'index_id'=>$data['index_id'],
421
            'origin'=>$data['origin'],
422
            'source'=>$data['source'],
423
            'solved_count'=>$data['solved_count'],
424
            'update_date'=>date("Y-m-d H:i:s"),
425
            'tot_score'=>$data['tot_score'],
426
            'partial'=>$data['partial'],
427
            'markdown'=>$data['markdown'],
428
            'special_compiler'=>$data['special_compiler'],
429
        ]);
430
431
        if (!empty($data["sample"])) {
432
            foreach ($data["sample"] as $d) {
433
                if(!isset($d['sample_note'])) $d['sample_note']=null;
434
                DB::table("problem_sample")->insert([
435
                    'pid'=>$pid,
436
                    'sample_input'=>$d['sample_input'],
437
                    'sample_output'=>$d['sample_output'],
438
                    'sample_note'=>$d['sample_note'],
439
                ]);
440
            }
441
        }
442
443
        return $pid;
444
    }
445
446
    public function updateProblem($data)
447
    {
448
        DB::table($this->table)->where(["pcode"=>$data['pcode']])->update([
449
            'difficulty'=>-1,
450
            'file'=>$data['file'],
451
            'title'=>$data['title'],
452
            'time_limit'=>$data['time_limit'],
453
            'memory_limit'=>$data['memory_limit'],
454
            'OJ'=>$data['OJ'],
455
            'description'=>$data['description'],
456
            'input'=>$data['input'],
457
            'output'=>$data['output'],
458
            'note'=>$data['note'],
459
            'input_type'=>$data['input_type'],
460
            'output_type'=>$data['output_type'],
461
            'contest_id'=>$data['contest_id'],
462
            'index_id'=>$data['index_id'],
463
            'origin'=>$data['origin'],
464
            'source'=>$data['source'],
465
            'solved_count'=>$data['solved_count'],
466
            'update_date'=>date("Y-m-d H:i:s"),
467
            'tot_score'=>$data['tot_score'],
468
            'partial'=>$data['partial'],
469
            'markdown'=>$data['markdown'],
470
            'special_compiler'=>$data['special_compiler'],
471
        ]);
472
473
        $pid=$this->pid($data['pcode']);
474
475
        DB::table("problem_sample")->where(["pid"=>$pid])->delete();
476
477
        if (!empty($data["sample"])) {
478
            foreach ($data["sample"] as $d) {
479
                if(!isset($d['sample_note'])) $d['sample_note']=null;
480
                DB::table("problem_sample")->insert([
481
                    'pid'=>$pid,
482
                    'sample_input'=>$d['sample_input'],
483
                    'sample_output'=>$d['sample_output'],
484
                    'sample_note'=>$d['sample_note'],
485
                ]);
486
            }
487
        }
488
489
        return $pid;
490
    }
491
492
    public function isHidden($pid)
493
    {
494
        return DB::table('problem')->where('pid','=',$pid)->get()->first()['hide'];
495
    }
496
}
497