Passed
Push — master ( 49f1ef...725c5d )
by John
04:04
created

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