Passed
Push — master ( 9ec2ee...019716 )
by Patrick
08:18
created

ParticipantAPI   F

Complexity

Total Complexity 64

Size/Duplication

Total Lines 349
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 1
Metric Value
eloc 206
c 5
b 0
f 1
dl 0
loc 349
rs 3.28
wmc 64

15 Methods

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

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 getMyShifts($request, $response, $args)
107
    {
108
        $this->validateLoggedIn($request);
109
        $uid = $this->user->uid;
110
        $dataTable = DataSetFactory::getDataTableByNames('fvs', 'shifts');
111
        $filter = new \Data\Filter("participant eq '$uid'");
112
        $shifts = $dataTable->read($filter);
113
        $format = $request->getAttribute('format', false);
114
        if($format === false || $format === 'text/calendar')
115
        {
116
            $text = "BEGIN:VCALENDAR\r\n";
117
            $text .= "VERSION:2.0\r\n";
118
            $text .= "PRODID:-//hacksw/handcal//NONSGML v1.0//EN\r\n";
119
            $count = count($shifts);
120
            for($i = 0; $i < $count; $i++)
121
            {
122
                $text .= "BEGIN:VEVENT\r\n";
123
                $text .= "UID:".$this->user->mail."\r\n";
124
                $d = new DateTime($shifts[$i]['startTime']);
125
                $d->setTimezone(new \DateTimeZone('UTC'));
126
                $text .= "DTSTAMP:".$d->format('Ymd\THis\Z')."\r\n";
127
                $text .= "DTSTART:".$d->format('Ymd\THis\Z')."\r\n";
128
                $d = new DateTime($shifts[$i]['endTime']);
129
                $d->setTimezone(new \DateTimeZone('UTC'));
130
                $text .= "DTEND:".$d->format('Ymd\THis\Z')."\r\n";
131
                $text .= "SUMMARY:".$shifts[$i]['roleID'].' '.$shifts[$i]['name']."\r\n";
132
                $text .= "END:VEVENT\r\n";
133
            }
134
            $text .= "END:VCALENDAR\r\n";
135
            $response = $response->withHeader('Content-type', 'text/calendar');
136
            $response = $response->withHeader('Content-Disposition', 'attachment; filename="MyShifts.ics"');
137
            $body = $response->getBody();
138
            $body->write($text);
139
        }
140
        else if($format === 'application/pdf')
141
        {
142
            $pdf = new \Schedules\SimplePDF('My', $shifts);
143
            $response = $response->withHeader('Content-Type', 'application/pdf');
144
            $response->getBody()->write($pdf->toPDFBuffer());
145
        }
146
        else
147
        {
148
            throw new \Exception('Unknown format '.$format);
149
        }
150
        return $response;
151
    }
152
153
    public function getCerts($request, $response, $args)
154
    {
155
        $this->validateLoggedIn($request);
156
        $uid = $args['uid'];
157
        if($uid === 'me')
158
        {
159
            $uid = $this->user->uid;
160
        }
161
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
162
        {
163
            return $response->withStatus(401);
164
        }
165
        $dataTable = $this->getDataTable();
166
        $odata = $request->getAttribute('odata', new \ODataParams(array()));
167
        $filter = $this->getFilterForPrimaryKey($uid);
168
        $areas = $dataTable->read($filter, array('certs'), $odata->top,
169
                                    $odata->skip, $odata->orderby);
170
        if(empty($areas))
171
        {
172
            return $response->withStatus(404);
173
        }
174
        if(!isset($areas[0]['certs']))
175
        {
176
            return $response->withJson(array());
177
        }
178
        return $response->withJson($areas[0]['certs']);
179
    }
180
181
    public function uploadCert($request, $response, $args)
182
    {
183
        $this->validateLoggedIn($request);
184
        $uid = $args['uid'];
185
        if($uid === 'me')
186
        {
187
            $uid = $this->user->uid;
188
        }
189
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
190
        {
191
            return $response->withStatus(401);
192
        }
193
        $dataTable = $this->getDataTable();
194
        $filter = $this->getFilterForPrimaryKey($uid);
195
        $users = $dataTable->read($filter);
196
        if(empty($users))
197
        {
198
            return $response->withStatus(404);
199
        }
200
        $user = $users[0];
201
        if(!isset($user['certs']))
202
        {
203
            $user['certs'] = array();
204
        }
205
        $files = $request->getUploadedFiles();
206
        $file = $files['file'];
207
        $stream = $file->getStream();
208
        $cert = array('status'=>'pending', 'image'=>base64_encode($stream->getContents()), 'imageType'=>$file->getClientMediaType());
209
        $user['certs'][$args['certId']] = $cert;
210
        $ret = $dataTable->update($filter, $user);
211
        if($ret)
212
        {
213
            return $response->withStatus(200);
214
        }
215
        return $response->withStatus(500);
216
    }
217
218
    public function rejectCert($request, $response, $args)
219
    {
220
        $this->validateLoggedIn($request);
221
        $uid = $args['uid'];
222
        if($uid === 'me')
223
        {
224
            $uid = $this->user->uid;
225
        }
226
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
227
        {
228
            return $response->withStatus(401);
229
        }
230
        $dataTable = $this->getDataTable();
231
        $filter = $this->getFilterForPrimaryKey($uid);
232
        $users = $dataTable->read($filter);
233
        if(empty($users))
234
        {
235
            return $response->withStatus(404);
236
        }
237
        $user = $users[0];
238
        $certType = $args['certId'];
239
        if(!isset($user['certs']) || !isset($user['certs'][$certType]))
240
        {
241
            return $response->withStatus(404);
242
        }
243
        $obj = $this->getParsedBody($request);
244
        $reason = 'Unknown';
245
        switch($obj['reason'])
246
        {
247
            case 'invalid':
248
                $reason = 'the image provided did not seem to show a valid certication of the type selected';
249
                break;
250
            case 'expired':
251
                $reason = 'the image provided was for a certification that had already expired';
252
                break;
253
        }
254
        unset($user['certs'][$certType]);
255
        $ret = $dataTable->update($filter, $user);
256
        if($ret)
257
        {
258
            $profile = new \VolunteerProfile(false, $user);
259
            $email = new \Emails\CertificationEmail($profile, 'certifcationRejected', $certType, array('reason'=>$reason));
260
            $emailProvider = \EmailProvider::getInstance();
261
            if($emailProvider->sendEmail($email) === false)
262
            {
263
                throw new \Exception('Unable to send email!');
264
            }
265
            return $response->withStatus(200);
266
        }
267
        return $response->withStatus(500);
268
    }
269
270
    public function acceptCert($request, $response, $args)
271
    {
272
        $this->validateLoggedIn($request);
273
        $uid = $args['uid'];
274
        if($uid === 'me')
275
        {
276
            $uid = $this->user->uid;
277
        }
278
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
279
        {
280
            return $response->withStatus(401);
281
        }
282
        $dataTable = $this->getDataTable();
283
        $filter = $this->getFilterForPrimaryKey($uid);
284
        $users = $dataTable->read($filter);
285
        if(empty($users))
286
        {
287
            return $response->withStatus(404);
288
        }
289
        $user = $users[0];
290
        $certType = $args['certId'];
291
        $certType = $args['certId'];
292
        if(!isset($user['certs']) || !isset($user['certs'][$certType]))
293
        {
294
            return $response->withStatus(404);
295
        }
296
        $user['certs'][$certType]['status'] = 'current';
297
        $ret = $dataTable->update($filter, $user);
298
        if($ret)
299
        {
300
            $profile = new \VolunteerProfile(false, $user);
301
            $email = new \Emails\CertificationEmail($profile, 'certifcationAccepted', $certType);
302
            $emailProvider = \EmailProvider::getInstance();
303
            if($emailProvider->sendEmail($email) === false)
304
            {
305
                throw new \Exception('Unable to send email!');
306
            }
307
            return $response->withStatus(200);
308
        }
309
        return $response->withStatus(500);
310
    }
311
312
    public function getTicketStatus($request, $response, $args)
313
    {
314
        $this->validateLoggedIn($request);
315
        $uid = $args['uid'];
316
        if($uid === 'me')
317
        {
318
            $uid = $this->user->uid;
319
        }
320
        else if($uid !== $this->user->uid && $this->canRead($request) === false)
321
        {
322
            return $response->withStatus(401);
323
        }
324
        $dataTable = $this->getDataTable();
325
        $filter = $this->getFilterForPrimaryKey($uid);
326
        $users = $dataTable->read($filter);
327
        if(empty($users))
328
        {
329
            return $response->withStatus(404);
330
        }
331
        $user = $users[0];
332
        //TODO Ticket IDs for people who don't have tickets associated to their email
333
        //Get the ticket year
334
        $settingsTable = DataSetFactory::getDataTableByNames('tickets', 'Variables');
335
        $settings = $settingsTable->read(new \Data\Filter('name eq \'year\''));
336
        $year = $settings[0]['value']; 
337
        $email = $user['email'];
338
        $ticketTable = DataSetFactory::getDataTableByNames('tickets', 'Tickets');
339
        $tickets = $ticketTable->read(new \Data\Filter("email eq '$email' and year eq $year"));
340
        if(empty($tickets))
341
        {
342
            $requestTable = DataSetFactory::getDataTableByNames('tickets', 'TicketRequest');
343
            $requests = $requestTable->read(new \Data\Filter("mail eq '$email' and year eq $year"));
344
            if(empty($requests))
345
            {
346
                return $response->withJson(array('ticket' => false, 'request' => false));
347
            }
348
            return $response->withJson(array('ticket' => false, 'request' => true));
349
        }
350
        return $response->withJson(array('ticket' => true));
351
    }
352
}
353
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
354