GroupHomework::cacheStatistics()   F
last analyzed

Complexity

Conditions 10
Paths 933

Size

Total Lines 73
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 1
Metric Value
cc 10
eloc 49
nc 933
nop 0
dl 0
loc 73
rs 3.9871
c 2
b 1
f 1

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\Factories\HasFactory;
6
use Illuminate\Database\Eloquent\Model;
7
use Carbon;
8
use DateTimeInterface;
9
use Exception;
10
use Cache;
11
use Log;
12
use DB;
13
use Throwable;
14
15
class GroupHomework extends Model
16
{
17
    use HasFactory;
18
19
    public function group()
20
    {
21
        return $this->belongsTo('App\Models\Eloquent\Group', 'group_id', 'gid');
22
    }
23
24
    public function problems()
25
    {
26
        return $this->hasMany('App\Models\Eloquent\GroupHomeworkProblem');
27
    }
28
29
    protected function serializeDate(DateTimeInterface $date)
30
    {
31
        return $date->format('Y-m-d H:i:s');
32
    }
33
34
    public function getStatisticsAttribute()
35
    {
36
        $cachedStatistics = Cache::tags(['homework', 'statistics'])->get($this->id);
37
38
        if (blank($cachedStatistics)) {
39
            $cachedStatistics = $this->cacheStatistics();
40
        }
41
42
        if ($cachedStatistics === false) {
43
            return null;
44
        }
45
46
        $cachedStatistics['timestamp'] = Carbon::createFromTimestamp($cachedStatistics['timestamp']);
47
48
        return $cachedStatistics;
49
    }
50
51
    public function cacheStatistics()
52
    {
53
        try {
54
            $statistics = [];
55
            $homeworkProblems = $this->problems->sortBy('order_index');
56
            $users = $this->group->members()->where('role', '>=', 1)->get();
57
            $userIDArr = $users->pluck('uid');
58
            $defaultVerdict = [];
59
60
            foreach ($homeworkProblems as $homeworkProblem) {
61
                $statistics['problems'][] = [
62
                    'pid' => $homeworkProblem->problem_id,
63
                    'readable_name' => $homeworkProblem->problem->readable_name,
64
                ];
65
                $defaultVerdict[$homeworkProblem->problem_id] = [
66
                    "icon" => "checkbox-blank-circle-outline",
67
                    "color" => "wemd-grey-text"
68
                ];
69
            }
70
71
            foreach ($users as $user) {
72
                $statistics['data'][$user->uid] = [
73
                    'name' => $user->user->name,
74
                    'nick_name' => blank($user->nick_name) ? null : $user->nick_name,
75
                    'solved' => 0,
76
                    'attempted' => 0,
77
                    'verdict' => $defaultVerdict
78
                ];
79
            }
80
81
            $endedAt = Carbon::parse($this->ended_at);
82
83
            foreach ($homeworkProblems as $homeworkProblem) {
84
                $userProbIDArr = [];
85
86
                foreach ($homeworkProblem->problem->users_latest_submission($userIDArr->diff($userProbIDArr), null, $endedAt, ['Accepted'])->get() as $acceptedRecord) {
87
                    $statistics['data'][$acceptedRecord['uid']]['verdict'][$homeworkProblem->problem_id] = [
88
                        "icon" => "checkbox-blank-circle",
89
                        "color" => $acceptedRecord['color']
90
                    ];
91
                    $statistics['data'][$acceptedRecord['uid']]['solved']++;
92
                    $userProbIDArr[] = $acceptedRecord['uid'];
93
                }
94
95
                foreach ($homeworkProblem->problem->users_latest_submission($userIDArr->diff($userProbIDArr), null, $endedAt, ['Partially Accepted'])->get() as $acceptedRecord) {
96
                    $statistics['data'][$acceptedRecord['uid']]['verdict'][$homeworkProblem->problem_id] = [
97
                        "icon" => "cisco-webex",
98
                        "color" => $acceptedRecord['color']
99
                    ];
100
                    $statistics['data'][$acceptedRecord['uid']]['attempted']++;
101
                    $userProbIDArr[] = $acceptedRecord['uid'];
102
                }
103
104
                foreach ($homeworkProblem->problem->users_latest_submission($userIDArr->diff($userProbIDArr), null, $endedAt)->get() as $acceptedRecord) {
105
                    $statistics['data'][$acceptedRecord['uid']]['verdict'][$homeworkProblem->problem_id] = [
106
                        "icon" => "cisco-webex",
107
                        "color" => $acceptedRecord['color']
108
                    ];
109
                    $statistics['data'][$acceptedRecord['uid']]['attempted']++;
110
                    $userProbIDArr[] = $acceptedRecord['uid'];
111
                }
112
            }
113
114
            usort($statistics['data'], function ($a, $b) {
115
                return $b["solved"] == $a["solved"] ? $b["attempted"] <=> $a["attempted"] : $b["solved"] <=> $a["solved"];
116
            });
117
118
            $statistics['timestamp'] = time();
119
            Cache::tags(['homework', 'statistics'])->put($this->id, $statistics, 360);
120
            return $statistics;
121
        } catch (Exception $e) {
122
            Log::alert($e);
123
            return false;
124
        }
125
    }
126
127
    public function sendMessage()
128
    {
129
        DB::beginTransaction();
130
        try {
131
            foreach($this->group->members()->where('role', '>', '0')->get() as $member) {
132
                sendMessage([
133
                    'sender'   => config('app.official_sender'),
134
                    'receiver' => $member->uid,
135
                    'title'    => __('message.homework.new.title'),
136
                    'type'     => 5,
137
                    'level'    => 1,
138
                    'data'     => [
139
                        'homework' => [[
140
                            'id' => $this->id,
141
                            'gcode' => $this->group->gcode,
142
                            'title' => $this->title
143
                        ]]
144
                    ]
145
                ]);
146
            }
147
            DB::commit();
148
        } catch (Throwable $e) {
149
            Log::error($e);
150
            DB::rollback();
151
        }
152
    }
153
}
154