Passed
Push — master ( d7e703...d0dd1b )
by Patrick
09:55
created

Processor::processShift()   F

Complexity

Conditions 16
Paths 292

Size

Total Lines 70
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 16
eloc 44
c 4
b 0
f 0
nc 292
nop 2
dl 0
loc 70
rs 3.5833

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
trait Processor
3
{
4
    protected function certCheck($requirements, $certs, $certType)
5
    {
6
        if(isset($requirements[$certType]) && $requirements[$certType])
7
        {
8
            return (!isset($certs[$certType]) || !$certs[$certType]);
9
        }
10
        return false;
11
    }
12
13
    protected abstract function isVolunteerAdmin($request);
14
15
    public function canUserDoRole($user, $role)
16
    {
17
        static $certs = null;
18
        static $certCount = 0;
19
        if($certs === null)
20
        {
21
            $dataTable = DataSetFactory::getDataTableByNames('fvs', 'certifications');
22
            $certs = $dataTable->read();
23
            $certCount = count($certs);
0 ignored issues
show
Bug introduced by
It seems like $certs can also be of type boolean; however, parameter $var of count() does only seem to accept Countable|array, 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

23
            $certCount = count(/** @scrutinizer ignore-type */ $certs);
Loading history...
24
        }
25
        if($role['publicly_visible'] === true)
26
        {
27
            return true;
28
        }
29
        $requirements = array();
30
        if(isset($role['requirements']))
31
        {
32
            $requirements = $role['requirements'];
33
        }
34
        $userCerts = $user->certs;
35
        if(count($requirements) === 0)
36
        {
37
            //Bugged role...
38
            return true;
39
        }
40
        if(isset($requirements['email_list']))
41
        {
42
            $emails = explode(',', $requirements['email_list']);
43
            if(!$user->userInEmailList($emails))
44
            {
45
                return array('whyClass' => 'INVITE', 'whyMsg' => 'Shift is invite only.');
46
            }
47
        }
48
        for($i = 0; $i < $certCount; $i++)
49
        {
50
            if($this->certCheck($requirements, $userCerts, $certs[$i]['certID']))
51
            {
52
                return array('whyClass' => 'CERT', 'whyMsg' => 'Shift requires '.$certs[$i]['name'].' and you do not have that certification');
53
            }
54
        }
55
        return true;
56
    }
57
58
    protected function getParticipantDiplayName($uid)
59
    {
60
        static $uids = array();
61
        if(!isset($uids[$uid]))
62
        {
63
            try
64
            {
65
                $profile = new \VolunteerProfile($uid);
66
                $uids[$uid] = $profile->getDisplayName();
67
            }
68
            catch(Exception $e)
69
            {
70
                $uids[$uid] = $uid;
71
            }
72
        }
73
        return $uids[$uid];
74
    }
75
76
    protected function isUserDepartmentLead($departmentID, $user)
77
    {
78
        static $deptCache = array();
79
        if(!isset($deptCache[$departmentID]))
80
        {
81
            $dataTable = DataSetFactory::getDataTableByNames('fvs', 'departments');
82
            $filter = new \Data\Filter('departmentID eq '.$departmentID);
83
            $depts = $dataTable->read($filter);
84
            if(empty($depts))
85
            {
86
                return false;
87
            }
88
            $deptCache[$departmentID] = $depts[0];
89
        }
90
        return $this->isUserDepartmentLead2($deptCache[$departmentID], $user);
91
    }
92
93
    protected function userIsLeadCached($user)
94
    {
95
        static $userIsLead = null;
96
        if($userIsLead === null)
97
        {
98
            $userIsLead = $user->isInGroupNamed('Leads');
99
        }
100
        return $userIsLead;
101
    }
102
103
    protected function isUserDepartmentLead2($dept, $user)
104
    {
105
        static $depts = array();
106
        if(!isset($depts[$dept['departmentID']]))
107
        {
108
            $depts[$dept['departmentID']] = array();
109
        }
110
        $deptCache = $depts[$dept['departmentID']];
111
        $uid = $user->uid;
112
        if(!isset($deptCache[$uid]))
113
        {
114
            if(isset($dept['lead']) && $this->userIsLeadCached($user) && is_array($user->title) && in_array($dept['lead'], $user->title))
115
            {
116
                $deptCache[$uid] = true;
117
            }
118
            else if(!isset($dept['others']))
119
            {
120
                $deptCache[$uid] = false;
121
            }
122
            else
123
            {
124
                $email = $user->mail;
125
                $otherAdmins = explode(',', $dept['others']);
126
                $deptCache[$uid] = in_array($email, $otherAdmins);
127
            }
128
        }
129
        return $deptCache[$uid];
130
    }
131
132
    public function isAdminForShift($shift, $user)
133
    {
134
        if($this->isAdmin)
135
        {
136
            return true;
137
        }
138
        if($this->isUserDepartmentLead($shift['departmentID'], $user))
139
        {
140
            return true;
141
        }
142
        return false;
143
    }
144
145
    public function isAdminForRole($role, $user)
146
    {
147
        //Shift and Role use the same key for department ID...
148
        return $this->isAdminForShift($role, $user);
149
    }
150
151
    protected function shouldShowDepartment($deptId, $isAdmin)
152
    {
153
        static $privateDepts = null;
154
        if($privateDepts === null)
155
        {
156
            $privateDepts = VolunteerDepartment::getPrivateDepartments();
157
        }
158
        if($isAdmin)
159
        {
160
            return true;
161
        }
162
        return !in_array($deptId, $privateDepts);
163
    }
164
165
    protected function doShiftTimeChecks($shift, $entry)
166
    {
167
        $now = new DateTime();
168
        if($shift->startTime < $now)
169
        {
170
            $entry['available'] = false;
171
            $entry['why'] = 'Shift already started';
172
        }
173
        if($shift->endTime < $now)
174
        {
175
            $entry['available'] = false;
176
            $entry['why'] = 'Shift already ended';
177
        }
178
    }
179
180
    protected function cleanupNonDBFields(&$entry)
181
    {
182
        if(isset($entry['volunteer']))
183
        {
184
            unset($entry['volunteer']);
185
        }
186
        if(isset($entry['why']))
187
        {
188
            unset($entry['why']);
189
        }
190
        if(isset($entry['whyClass']))
191
        {
192
            unset($entry['whyClass']);
193
        }
194
    }
195
196
    protected function processShift($entry, $request)
197
    {
198
        static $profile = null;
199
        static $eeAvailable = false;
200
        static $canDoRole = array();
201
        static $roles = array();
202
        if($this->isAdmin === null)
203
        {
204
            $this->isVolunteerAdmin($request);
205
        }
206
        if($profile === null)
207
        {
208
            $profile = new \VolunteerProfile($this->user->uid);
209
            $eeAvailable = $profile->isEEAvailable();
210
            $dataTable = DataSetFactory::getDataTableByNames('fvs', 'roles');
211
            $tmp = $dataTable->read();
212
            foreach($tmp as $role)
213
            {
214
                $roles[$role['short_name']] = $role;
215
            }
216
        }
217
        $this->cleanupNonDBFields($entry);
218
        $shift = new \VolunteerShift(false, $entry);
219
        $entry['isAdmin'] = $this->isAdminForShift($entry, $this->user);
220
        $entry['overlap'] = $shift->findOverlaps($this->user->uid, true);
221
        if(!$this->shouldShowDepartment($entry['departmentID'], $entry['isAdmin']))
222
        {
223
            return null;
224
        }
225
        $entry['available'] = true;
226
        $this->doShiftTimeChecks($shift, $entry);
227
        if($entry['earlyLate'] != -1 && !$eeAvailable)
228
        {
229
            $entry['available'] = false;
230
            $entry['why'] = 'Shift requires early entry or late stay and you have not provided your legal name';
231
        }
232
        if(!isset($canDoRole[$entry['roleID']]))
233
        {
234
            $canDoRole[$entry['roleID']] = $this->canUserDoRole($profile, $roles[$entry['roleID']]);
235
        }
236
        if($canDoRole[$entry['roleID']] !== true)
237
        {
238
            $entry['available'] = false;
239
            $entry['why'] = $canDoRole[$entry['roleID']]['whyMsg'];
240
            $entry['whyClass'] = $canDoRole[$entry['roleID']]['whyClass'];
241
        }
242
        if($shift->isFilled())
243
        {
244
            if(isset($entry['participant']) && ($entry['participant'] !== '/dev/null' || $entry['participant'] !== ''))
245
            {
246
                $entry['volunteer'] = $this->getParticipantDiplayName($entry['participant']);
247
            }
248
            if(isset($entry['participant']) && $entry['participant'] === $profile->uid)
249
            {
250
                $entry['available'] = false;
251
                $entry['why'] = 'Shift is already taken, by you';
252
                $entry['whyClass'] = 'MINE';
253
            }
254
            else
255
            {
256
                $entry['available'] = false;
257
                $entry['why'] = 'Shift is already taken';
258
                $entry['whyClass'] = 'TAKEN';
259
            }
260
            if(!$entry['isAdmin'])
261
            {
262
                unset($entry['participant']);
263
            }
264
        }
265
        return $entry;
266
    }
267
268
    protected function processRole($entry, $request)
269
    {
270
        if($this->isAdmin === null)
271
        {
272
            $this->isVolunteerAdmin($request);
273
        }
274
        $entry['isAdmin'] = $this->isAdminForRole($entry, $this->user);
275
        return $entry;
276
    }
277
}
278
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
279