Completed
Push — master ( 3d3760...b0d42a )
by John
30s queued 13s
created

Problem::getProblemStatusFromDB()   C

Complexity

Conditions 11
Paths 169

Size

Total Lines 53
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 36
nc 169
nop 3
dl 0
loc 53
rs 6.7416
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Models\Eloquent;
4
5
use Illuminate\Database\Eloquent\Model;
6
use App\Models\Eloquent\Contest;
7
use Auth;
8
use Carbon;
9
use DB;
10
use Exception;
11
12
class Problem extends Model
13
{
14
    protected $table = 'problem';
15
    protected $primaryKey = 'pid';
16
    const UPDATED_AT = "update_date";
17
18
    public function getReadableNameAttribute()
19
    {
20
        return $this->pcode . '. ' . $this->title;
21
    }
22
23
    public function submissions()
24
    {
25
        return $this->hasMany('App\Models\Eloquent\Submission', 'pid', 'pid');
26
    }
27
28
    public function problemSamples()
29
    {
30
        return $this->hasMany('App\Models\Eloquent\ProblemSample', 'pid', 'pid');
31
    }
32
33
    public function homework_problems()
34
    {
35
        return $this->hasMany('App\Models\Eloquent\GroupHomeworkProblem', 'problem_id', 'pid');
36
    }
37
38
    public function onlinejudge()
39
    {
40
        return $this->belongsTo('App\Models\Eloquent\OJ', 'OJ', 'oid');
41
    }
42
43
    public function getProblemStatusAttribute()
44
    {
45
        return $this->getProblemStatus();
46
    }
47
48
    public function getProblemStatus($userID = null, $contestID = null, Carbon $till = null)
49
    {
50
        if (blank($userID)) {
51
            if (Auth::guard('web')->check()) {
52
                $userID = Auth::guard('web')->user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
53
            }
54
        }
55
56
        if (filled($userID)) {
57
            $probStatus = $this->getProblemStatusFromDB($userID, $contestID, $till);
58
            if (blank($probStatus)) {
59
                return [
60
                    "icon" => "checkbox-blank-circle-outline",
61
                    "color" => "wemd-grey-text"
62
                ];
63
            } else {
64
                return [
65
                    "icon" => $probStatus->verdict == "Accepted" ? "checkbox-blank-circle" : "cisco-webex",
66
                    "color" => $probStatus->color
67
                ];
68
            }
69
        } else {
70
            return [
71
                "icon" => "checkbox-blank-circle-outline",
72
                "color" => "wemd-grey-text"
73
            ];
74
        }
75
    }
76
77
    private function getProblemStatusFromDB($userID, $contestID = null, Carbon $till = null)
78
    {
79
        if (filled($contestID)) {
80
            try {
81
                $endedAt = Carbon::parse(Contest::findOrFail($contestID)->endedAt);
82
            } catch (Exception $e) {
83
                return null;
84
            }
85
        }
86
87
        // Get the very first AC record
88
89
        $acRecords = $this->submissions()->where([
90
            'uid' => $userID,
91
            'cid' => $contestID,
92
            'verdict' => 'Accepted'
93
        ]);
94
        if (filled($contestID)) {
95
            $acRecords = $acRecords->where("submission_date", "<", $endedAt->timestamp);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $endedAt does not seem to be defined for all execution paths leading up to this point.
Loading history...
96
        }
97
        if (filled($till)) {
98
            $acRecords = $acRecords->where("submission_date", "<", $till->timestamp);
99
        }
100
        $acRecords = $acRecords->orderBy('submission_date', 'desc')->first();
101
        if (blank($acRecords)) {
102
            $pacRecords = $this->submissions()->where([
103
                'uid' => $userID,
104
                'cid' => $contestID,
105
                'verdict' => 'Partially Accepted'
106
            ]);
107
            if (filled($contestID)) {
108
                $pacRecords = $pacRecords->where("submission_date", "<", $endedAt->timestamp);
109
            }
110
            if (filled($till)) {
111
                $pacRecords = $pacRecords->where("submission_date", "<", $till->timestamp);
112
            }
113
            $pacRecords = $pacRecords->orderBy('submission_date', 'desc')->first();
114
            if (blank($pacRecords)) {
115
                $otherRecords = $this->submissions()->where([
116
                    'uid' => $userID,
117
                    'cid' => $contestID
118
                ]);
119
                if (filled($contestID)) {
120
                    $otherRecords = $otherRecords->where("submission_date", "<", $endedAt->timestamp);
121
                }
122
                if (filled($till)) {
123
                    $otherRecords = $otherRecords->where("submission_date", "<", $till->timestamp);
124
                }
125
                return $otherRecords->orderBy('submission_date', 'desc')->first();
126
            }
127
            return $pacRecords;
128
        } else {
129
            return $acRecords;
130
        }
131
    }
132
133
    public function users_latest_submission($users, $contestID = null, Carbon $till = null, $verdictFilter = [])
134
    {
135
        if (filled($contestID)) {
136
            $endedAt = Carbon::parse(Contest::findOrFail($contestID)->endedAt);
137
        }
138
139
        $lastRecordSubQuery = $this->submissions()->select('uid', DB::raw('MAX(submission_date) as submission_date'))->whereIntegerInRaw('uid', $users)->where('cid', $contestID)->groupBy('uid');
140
141
        if (filled($contestID)) {
142
            $lastRecordSubQuery = $lastRecordSubQuery->where("submission_date", "<", $endedAt->timestamp);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $endedAt does not seem to be defined for all execution paths leading up to this point.
Loading history...
143
        }
144
145
        if (filled($till)) {
146
            $lastRecordSubQuery = $lastRecordSubQuery->where("submission_date", "<", $till->timestamp);
147
        }
148
149
        if(filled($verdictFilter)) {
150
            $lastRecordSubQuery = $lastRecordSubQuery->whereIn('verdict', $verdictFilter);
151
        }
152
153
        $query = DB::table(DB::raw("({$lastRecordSubQuery->toSql()}) last_sub"))->leftJoinSub(Submission::toBase(), 'submissions', function ($join) {
154
            $join->on('last_sub.submission_date', '=', 'submissions.submission_date')->on('last_sub.uid', '=', 'submissions.uid');
155
        })->select('sid', 'last_sub.submission_date as submission_date', 'last_sub.uid as uid', 'verdict', 'color')->orderBy('uid', 'ASC');
156
157
        return $query->mergeBindings($lastRecordSubQuery->toBase());
158
    }
159
160
    /*     public function getSamplesAttribute()
161
    {
162
        return array_map(function($sample) {
163
            return [
164
                'sample_input' => $sample->sample_input,
165
                'sample_output' => $sample->sample_output,
166
                'sample_note' => $sample->sample_note,
167
            ];
168
        }, $this->problemSamples()->select('sample_input', 'sample_output', 'sample_note')->get()->all());
169
    }
170
171
    public function setSamplesAttribute($value)
172
    {
173
        return;
174
    } */
175
}
176