ParticipantAPI   F
last analyzed

Complexity

Total Complexity 78

Size/Duplication

Total Lines 405
Duplicated Lines 0 %

Importance

Changes 7
Bugs 0 Features 1
Metric Value
eloc 238
dl 0
loc 405
rs 2.16
c 7
b 0
f 1
wmc 78

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A canDelete() 0 3 1
A canUpdate() 0 8 2
A readEntry() 0 22 5
A canCreate() 0 4 1
A canRead() 0 11 3
A validateCreate() 0 17 3
A getFilterForPrimaryKey() 0 7 2
A setup() 0 9 1
A getCerts() 0 26 6
B rejectCert() 0 50 11
C updateEntry() 0 44 12
B acceptCert() 0 40 9
A getMyShifts() 0 45 5
B uploadCert() 0 35 7
B getTicketStatus() 0 49 9

How to fix   Complexity   

Complex Class

Complex classes like ParticipantAPI often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ParticipantAPI, and based on these observations, apply Extract Interface, too.

1
<?php
2
class ParticipantAPI extends VolunteerAPI
3
{
4
    public function __construct()
5
    {
6
        parent::__construct('participants', 'uid');
7
    }
8
9
    public function setup($app)
10
    {
11
        parent::setup($app);
12
        $app->get('/me/shifts[/]', array($this, 'getMyShifts'));
13
        $app->get('/{uid}/certs[/]', array($this, 'getCerts'));
14
        $app->post('/{uid}/certs/{certId}[/]', array($this, 'uploadCert'));
15
        $app->post('/{uid}/certs/{certId}/Actions/RejectCert', array($this, 'rejectCert'));
16
        $app->post('/{uid}/certs/{certId}/Actions/AcceptCert', array($this, 'acceptCert'));
17
        $app->get('/{uid}/ticketStatus', array($this, 'getTicketStatus'));
18
    }
19
20
    protected function canCreate($request)
21
    {
22
        $this->validateLoggedIn($request);
23
        return true;
24
    }
25
26
    protected function canRead($request)
27
    {
28
        if($this->isVolunteerAdmin($request))
29
        {
30
            return true;
31
        }
32
        if($this->user->isInGroupNamed('Leads'))
33
        {
34
            return true;
35
        }
36
        return false;
37
    }
38
39
    protected function canUpdate($request, $entity)
40
    {
41
        if($this->isVolunteerAdmin($request))
42
        {
43
            return true;
44
        }       
45
        //TODO give access to department lead
46
        return false;
47
    }
48
49
    protected function canDelete($request, $entity)
50
    {
51
        return $this->canUpdate($request, $entity);
52
    }
53
54
    protected function validateCreate(&$obj, $request)
55
    {
56
        if(isset($obj['uid']))
57
        {
58
            return false;
59
        }
60
        $uid = $this->user->uid;
61
        $dataTable = $this->getDataTable();
62
        $filter = $this->getFilterForPrimaryKey($uid);
63
        $users = $dataTable->read($filter);
64
        if(!empty($users))
65
        {
66
            //User is already created...
67
            return false;
68
        }
69
        $obj['uid'] = $uid;
70
        return true;
71
    }
72
73
    protected function getFilterForPrimaryKey($value)
74
    {
75
        if($value === 'me')
76
        {
77
            $value = $this->user->uid;
78
        }
79
        return parent::getFilterForPrimaryKey($value);
80
    }
81
82
    public function readEntry($request, $response, $args)
83
    {
84
        $this->validateLoggedIn($request);
85
        $uid = $args['name'];
86
        if($uid === 'me')
87
        {
88
            $uid = $this->user->uid;
89
        }
90
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
91
        {
92
            return $response->withStatus(401);
93
        }
94
        $dataTable = $this->getDataTable();
95
        $odata = $request->getAttribute('odata', new \ODataParams(array()));
96
        $filter = $this->getFilterForPrimaryKey($uid);
97
        $areas = $dataTable->read($filter, $odata->select, $odata->top,
98
                                    $odata->skip, $odata->orderby);
99
        if(empty($areas))
100
        {
101
            return $response->withStatus(404);
102
        }
103
        return $response->withJson($areas[0]);
104
    }
105
106
    public function updateEntry($request, $response, $args)
107
    {
108
        $this->validateLoggedIn($request);
109
        $uid = $args['name'];
110
        if($uid === 'me')
111
        {
112
            $uid = $this->user->uid;
113
        }
114
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
115
        {
116
            return $response->withStatus(401);
117
        }
118
        $filter = $this->getFilterForPrimaryKey($uid);
119
        $dataTable = $this->getDataTable();
120
        $entry = $dataTable->read($filter);
121
        if(empty($entry))
122
        {
123
            return $response->withStatus(404);
124
        }
125
        if(count($entry) === 1 && isset($entry[0]))
126
        {
127
            $entry = $entry[0];
128
        }
129
        if($uid !== $this->user->uid && $this->canUpdate($request, $entry) === false)
130
        {
131
            return $response->withStatus(401);
132
        }
133
        $obj = $request->getParsedBody();
134
        if($obj === null)
135
        {
136
            $request->getBody()->rewind();
137
            $obj = $request->getBody()->getContents();
138
            $tmp = json_decode($obj, true);
139
            if($tmp !== null)
140
            {
141
                $obj = $tmp;
142
            }
143
        }
144
        if($this->validateUpdate($obj, $request, $entry) === false)
0 ignored issues
show
introduced by
The condition $this->validateUpdate($o...uest, $entry) === false is always false.
Loading history...
145
        {
146
            return $response->withStatus(400);
147
        }
148
        $ret = $dataTable->update($filter, $obj);
149
        return $response->withJson($ret);
150
    }
151
152
    public function getMyShifts($request, $response, $args)
153
    {
154
        $this->validateLoggedIn($request);
155
        $uid = $this->user->uid;
156
        $dataTable = DataSetFactory::getDataTableByNames('fvs', 'shifts');
157
        $filter = new \Data\Filter("participant eq '$uid'");
158
        $shifts = $dataTable->read($filter);
159
        $format = $request->getAttribute('format', false);
160
        if($format === false || $format === 'text/calendar')
161
        {
162
            $text = "BEGIN:VCALENDAR\r\n";
163
            $text .= "VERSION:2.0\r\n";
164
            $text .= "PRODID:-//hacksw/handcal//NONSGML v1.0//EN\r\n";
165
            $count = count($shifts);
166
            for($i = 0; $i < $count; $i++)
167
            {
168
                $text .= "BEGIN:VEVENT\r\n";
169
                $text .= "UID:".$this->user->mail."\r\n";
170
                $d = new DateTime($shifts[$i]['startTime']);
171
                $d->setTimezone(new \DateTimeZone('UTC'));
172
                $text .= "DTSTAMP:".$d->format('Ymd\THis\Z')."\r\n";
173
                $text .= "DTSTART:".$d->format('Ymd\THis\Z')."\r\n";
174
                $d = new DateTime($shifts[$i]['endTime']);
175
                $d->setTimezone(new \DateTimeZone('UTC'));
176
                $text .= "DTEND:".$d->format('Ymd\THis\Z')."\r\n";
177
                $text .= "SUMMARY:".$shifts[$i]['roleID'].' '.$shifts[$i]['name']."\r\n";
178
                $text .= "END:VEVENT\r\n";
179
            }
180
            $text .= "END:VCALENDAR\r\n";
181
            $response = $response->withHeader('Content-type', 'text/calendar');
182
            $response = $response->withHeader('Content-Disposition', 'attachment; filename="MyShifts.ics"');
183
            $body = $response->getBody();
184
            $body->write($text);
185
        }
186
        else if($format === 'application/pdf')
187
        {
188
            $pdf = new \Schedules\SimplePDF('My', $shifts);
189
            $response = $response->withHeader('Content-Type', 'application/pdf');
190
            $response->getBody()->write($pdf->toPDFBuffer());
191
        }
192
        else
193
        {
194
            throw new \Exception('Unknown format '.$format);
195
        }
196
        return $response;
197
    }
198
199
    public function getCerts($request, $response, $args)
200
    {
201
        $this->validateLoggedIn($request);
202
        $uid = $args['uid'];
203
        if($uid === 'me')
204
        {
205
            $uid = $this->user->uid;
206
        }
207
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
208
        {
209
            return $response->withStatus(401);
210
        }
211
        $dataTable = $this->getDataTable();
212
        $odata = $request->getAttribute('odata', new \ODataParams(array()));
213
        $filter = $this->getFilterForPrimaryKey($uid);
214
        $areas = $dataTable->read($filter, array('certs'), $odata->top,
215
                                    $odata->skip, $odata->orderby);
216
        if(empty($areas))
217
        {
218
            return $response->withStatus(404);
219
        }
220
        if(!isset($areas[0]['certs']))
221
        {
222
            return $response->withJson(array());
223
        }
224
        return $response->withJson($areas[0]['certs']);
225
    }
226
227
    public function uploadCert($request, $response, $args)
228
    {
229
        $this->validateLoggedIn($request);
230
        $uid = $args['uid'];
231
        if($uid === 'me')
232
        {
233
            $uid = $this->user->uid;
234
        }
235
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
236
        {
237
            return $response->withStatus(401);
238
        }
239
        $dataTable = $this->getDataTable();
240
        $filter = $this->getFilterForPrimaryKey($uid);
241
        $users = $dataTable->read($filter);
242
        if(empty($users))
243
        {
244
            return $response->withStatus(404);
245
        }
246
        $user = $users[0];
247
        if(!isset($user['certs']))
248
        {
249
            $user['certs'] = array();
250
        }
251
        $files = $request->getUploadedFiles();
252
        $file = $files['file'];
253
        $stream = $file->getStream();
254
        $cert = array('status'=>'pending', 'image'=>base64_encode($stream->getContents()), 'imageType'=>$file->getClientMediaType());
255
        $user['certs'][$args['certId']] = $cert;
256
        $ret = $dataTable->update($filter, $user);
257
        if($ret)
258
        {
259
            return $response->withStatus(200);
260
        }
261
        return $response->withStatus(500);
262
    }
263
264
    public function rejectCert($request, $response, $args)
265
    {
266
        $this->validateLoggedIn($request);
267
        $uid = $args['uid'];
268
        if($uid === 'me')
269
        {
270
            $uid = $this->user->uid;
271
        }
272
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
273
        {
274
            return $response->withStatus(401);
275
        }
276
        $dataTable = $this->getDataTable();
277
        $filter = $this->getFilterForPrimaryKey($uid);
278
        $users = $dataTable->read($filter);
279
        if(empty($users))
280
        {
281
            return $response->withStatus(404);
282
        }
283
        $user = $users[0];
284
        $certType = $args['certId'];
285
        if(!isset($user['certs']) || !isset($user['certs'][$certType]))
286
        {
287
            return $response->withStatus(404);
288
        }
289
        $obj = $this->getParsedBody($request);
290
        $reason = 'Unknown';
291
        switch($obj['reason'])
292
        {
293
            case 'invalid':
294
                $reason = 'the image provided did not seem to show a valid certication of the type selected';
295
                break;
296
            case 'expired':
297
                $reason = 'the image provided was for a certification that had already expired';
298
                break;
299
        }
300
        unset($user['certs'][$certType]);
301
        $ret = $dataTable->update($filter, $user);
302
        if($ret)
303
        {
304
            $profile = new \VolunteerProfile(false, $user);
305
            $email = new \Emails\CertificationEmail($profile, 'certifcationRejected', $certType, array('reason'=>$reason));
306
            $emailProvider = \EmailProvider::getInstance();
307
            if($emailProvider->sendEmail($email) === false)
308
            {
309
                throw new \Exception('Unable to send email!');
310
            }
311
            return $response->withStatus(200);
312
        }
313
        return $response->withStatus(500);
314
    }
315
316
    public function acceptCert($request, $response, $args)
317
    {
318
        $this->validateLoggedIn($request);
319
        $uid = $args['uid'];
320
        if($uid === 'me')
321
        {
322
            $uid = $this->user->uid;
323
        }
324
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
325
        {
326
            return $response->withStatus(401);
327
        }
328
        $dataTable = $this->getDataTable();
329
        $filter = $this->getFilterForPrimaryKey($uid);
330
        $users = $dataTable->read($filter);
331
        if(empty($users))
332
        {
333
            return $response->withStatus(404);
334
        }
335
        $user = $users[0];
336
        $certType = $args['certId'];
337
        $certType = $args['certId'];
338
        if(!isset($user['certs']) || !isset($user['certs'][$certType]))
339
        {
340
            return $response->withStatus(404);
341
        }
342
        $user['certs'][$certType]['status'] = 'current';
343
        $ret = $dataTable->update($filter, $user);
344
        if($ret)
345
        {
346
            $profile = new \VolunteerProfile(false, $user);
347
            $email = new \Emails\CertificationEmail($profile, 'certifcationAccepted', $certType);
348
            $emailProvider = \EmailProvider::getInstance();
349
            if($emailProvider->sendEmail($email) === false)
350
            {
351
                throw new \Exception('Unable to send email!');
352
            }
353
            return $response->withStatus(200);
354
        }
355
        return $response->withStatus(500);
356
    }
357
358
    public function getTicketStatus($request, $response, $args)
359
    {
360
        $this->validateLoggedIn($request);
361
        $uid = $args['uid'];
362
        if($uid === 'me')
363
        {
364
            $uid = $this->user->uid;
365
        }
366
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
367
        {
368
            return $response->withStatus(401);
369
        }
370
        $dataTable = $this->getDataTable();
371
        $filter = $this->getFilterForPrimaryKey($uid);
372
        $users = $dataTable->read($filter);
373
        if(empty($users))
374
        {
375
            return $response->withStatus(404);
376
        }
377
        $user = $users[0];
378
        $settingsTable = DataSetFactory::getDataTableByNames('tickets', 'Variables');
379
        $settings = $settingsTable->read(new \Data\Filter('name eq \'year\''));
380
        $year = $settings[0]['value'];
381
        $ticketTable = DataSetFactory::getDataTableByNames('tickets', 'Tickets');
382
        if(isset($user['ticketCode']))
383
        {
384
            $code = $user['ticketCode'];
385
            $tickets = $ticketTable->read(new \Data\Filter("contains(hash,$code) and year eq $year"));
386
        }
387
        else
388
        {
389
            $email = $user['email'];
390
            $tickets = $ticketTable->read(new \Data\Filter("email eq '$email' and year eq $year"));
391
        }
392
        if(empty($tickets))
393
        {
394
            $requestTable = DataSetFactory::getDataTableByNames('tickets', 'TicketRequest');
395
            $requests = $requestTable->read(new \Data\Filter("mail eq '$email' and year eq $year"));
396
            if(empty($requests))
397
            {
398
                return $response->withJson(array('ticket' => false, 'request' => false));
399
            }
400
            if($requests[0]['status'] === '1')
401
            {
402
                return $response->withJson(array('ticket' => false, 'request' => true, 'requestRecieved' => true));
403
            }
404
            return $response->withJson(array('ticket' => false, 'request' => true));
405
        }
406
        return $response->withJson(array('ticket' => true));
407
    }
408
}
409
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
410