Completed
Push — master ( c9cf5a...44002c )
by Patrick
01:34
created

Processor::cleanupNonDBFields()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 8
nop 1
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
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);
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
                $profile = new \VolunteerProfile($uid);
65
                $uids[$uid] = $profile->getDisplayName();
66
            } catch (Exception $e) {
67
                $uids[$uid] = $uid;
68
            }
69
        }
70
        return $uids[$uid];
71
    }
72
73
    protected function isUserDepartmentLead($departmentID, $user)
74
    {
75
        static $deptCache = array();
76
        if(!isset($deptCache[$departmentID]))
77
        {
78
            $dataTable = DataSetFactory::getDataTableByNames('fvs', 'departments');
79
            $filter = new \Data\Filter('departmentID eq '.$departmentID);
80
            $depts = $dataTable->read($filter);
81
            if(empty($depts))
82
            {
83
                return false;
84
            }
85
            $deptCache[$departmentID] = $depts[0];
86
        }
87
        return $this->isUserDepartmentLead2($deptCache[$departmentID], $user);
88
    }
89
90
    protected function userIsLeadCached($user)
91
    {
92
        static $userIsLead = null;
93
        if($userIsLead === null)
94
        {
95
            $userIsLead = $user->isInGroupNamed('Leads');
96
        }
97
        return $userIsLead;
98
    }
99
100
    protected function isUserDepartmentLead2($dept, $user)
101
    {
102
        static $depts = array();
103
        if(!isset($depts[$dept['departmentID']]))
104
        {
105
            $depts[$dept['departmentID']] = array();
106
        }
107
        $deptCache = $depts[$dept['departmentID']];
108
        $uid = $user->uid;
109
        if(!isset($deptCache[$uid]))
110
        {
111
            if(isset($dept['lead']) && $this->userIsLeadCached($user) && is_array($user->title) && in_array($dept['lead'], $user->title))
112
            {
113
                $deptCache[$uid] = true;
114
            }
115
            else if(!isset($dept['others']))
116
            {
117
                $deptCache[$uid] = false;
118
            }
119
            else
120
            {
121
                $email = $user->mail;
122
                $otherAdmins = explode(',', $dept['others']);
123
                $deptCache[$uid] = in_array($email, $otherAdmins);
124
            }
125
        }
126
        return $deptCache[$uid];
127
    }
128
129
    public function isAdminForShift($shift, $user)
130
    {
131
        if($this->isAdmin)
132
        {
133
            return true;
134
        }
135
        if($this->isUserDepartmentLead($shift['departmentID'], $user))
136
        {
137
            return true;
138
        }
139
        return false;
140
    }
141
142
    public function isAdminForRole($role, $user)
143
    {
144
        //Shift and Role use the same key for department ID...
145
        return $this->isAdminForShift($role, $user);
146
    }
147
148
    protected function shouldShowDepartment($deptId, $isAdmin)
149
    {
150
        static $privateDepts = null;
151
        if($privateDepts === null)
152
        {
153
            $privateDepts = VolunteerDepartment::getPrivateDepartments();
154
        }
155
        if($isAdmin)
156
        {
157
            return true;
158
        }
159
        return !in_array($deptId, $privateDepts);
160
    }
161
162
    protected function doShiftTimeChecks($shift, $entry)
163
    {
164
        $now = new DateTime();
165
        if($shift->startTime < $now)
166
        {
167
            $entry['available'] = false;
168
            $entry['why'] = 'Shift already started';
169
        }
170
        if($shift->endTime < $now)
171
        {
172
            $entry['available'] = false;
173
            $entry['why'] = 'Shift already ended';
174
        }
175
    }
176
177
    protected function cleanupNonDBFields(&$entry)
178
    {
179
        if(isset($entry['volunteer']))
180
        {
181
          unset($entry['volunteer']);
182
        }
183
        if(isset($entry['why']))
184
        {
185
          unset($entry['why']);
186
        }
187
        if(isset($entry['whyClass']))
188
        {
189
          unset($entry['whyClass']);
190
        }
191
    }
192
193
    protected function processShift($entry, $request)
194
    {
195
        static $profile = null;
196
        static $eeAvailable = false;
197
        static $canDoRole = array();
198
        static $roles = array();
199
        if($this->isAdmin === null)
200
        {
201
            $this->isVolunteerAdmin($request);
202
        }
203
        if($profile === null)
204
        {
205
            $profile = new \VolunteerProfile($this->user->uid);
206
            $eeAvailable = $profile->isEEAvailable();
207
            $dataTable = DataSetFactory::getDataTableByNames('fvs', 'roles');
208
            $tmp = $dataTable->read();
209
            foreach($tmp as $role)
0 ignored issues
show
Bug introduced by
The expression $tmp of type boolean|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
210
            {
211
               $roles[$role['short_name']] = $role;
212
            }
213
        }
214
        $this->cleanupNonDBFields($entry);
215
        $shift = new \VolunteerShift(false, $entry);
216
        $entry['isAdmin'] = $this->isAdminForShift($entry, $this->user);
217
        $entry['overlap'] = $shift->findOverlaps($this->user->uid, true);
218
        if(!$this->shouldShowDepartment($entry['departmentID'], $entry['isAdmin']))
219
        {
220
            return null;
221
        }
222
        $entry['available'] = true;
223
        $this->doShiftTimeChecks($shift, $entry);
224
        if($entry['earlyLate'] != -1 && !$eeAvailable)
225
        {
226
            $entry['available'] = false;
227
            $entry['why'] = 'Shift requires early entry or late stay and you have not provided your legal name';
228
        }
229
        if(!isset($canDoRole[$entry['roleID']]))
230
        {
231
            $canDoRole[$entry['roleID']] = $this->canUserDoRole($profile, $roles[$entry['roleID']]);
232
        }
233
        if($canDoRole[$entry['roleID']] !== true)
234
        {
235
            $entry['available'] = false;
236
            $entry['why'] = $canDoRole[$entry['roleID']]['whyMsg'];
237
            $entry['whyClass'] = $canDoRole[$entry['roleID']]['whyClass'];
238
        }
239
        if($shift->isFilled())
240
        {
241
            if(isset($entry['participant']) && ($entry['participant'] !== '/dev/null' || $entry['participant'] !== ''))
242
            {
243
                $entry['volunteer'] = $this->getParticipantDiplayName($entry['participant']);
244
            }
245
            if(isset($entry['participant']) && $entry['participant'] === $profile->uid)
246
            {
247
                $entry['available'] = false;
248
                $entry['why'] = 'Shift is already taken, by you';
249
                $entry['whyClass'] = 'MINE';
250
            }
251
            else
252
            {
253
                $entry['available'] = false;
254
                $entry['why'] = 'Shift is already taken';
255
                $entry['whyClass'] = 'TAKEN';
256
            }
257
            if(!$entry['isAdmin'])
258
            {
259
                unset($entry['participant']);
260
            }
261
        }
262
        return $entry;
263
    }
264
265
    protected function processRole($entry, $request)
266
    {
267
        if($this->isAdmin === null)
268
        {
269
            $this->isVolunteerAdmin($request);
270
        }
271
        $entry['isAdmin'] = $this->isAdminForRole($entry, $this->user);
272
        return $entry;
273
    }
274
}
275
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
276