Passed
Branch master (3ca537)
by Daniel
02:55
created

Client::getEvents()   C

Complexity

Conditions 12
Paths 56

Size

Total Lines 75
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 30
c 1
b 0
f 0
nc 56
nop 13
dl 0
loc 75
ccs 0
cts 27
cp 0
crap 156
rs 6.9666

How to fix   Long Method    Complexity    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace InShore\Bookwhen;
6
7
use GuzzleHttp;
8
use GuzzleHttp\Client as GuzzleClient;
9
use GuzzleHttp\Psr7\Request;
10
use InShore\Bookwhen\Exceptions\ConfigurationException;
11
use InShore\Bookwhen\Exceptions\RestException;
12
use InShore\Bookwhen\Exceptions\ValidationException;
13
use InShore\Bookwhen\Interfaces\ClientInterface;
14
use InShore\Bookwhen\Validator;
15
use InShore\Bookwhen\Exceptions\InshoreBookwhenException;
16
use Monolog\Logger;
17
use Monolog\Handler\StreamHandler;
18
use Psr\Http\Message\ResponseInterface;
19
20
21
/**
22
 * Class Client
23
 *
24
 * The main class for API consumption
25
 *
26
 * @package inshore\bookwhen
27
 * @todo comments
28
 * @todo externalise config
29
 * @todo fix token
30
 */
31
class Client implements ClientInterface
32
{
33
    
34
    /** @var string The API access token */
35
    private static $token = null;
36
    
37
    /** @var string The instance token, settable once per new instance */
38
    private $instanceToken;
39
    
40
    private $apiBaseUri;
41
    
42
    private $apiQuery;
43
   
44
    private $apiResource;
45
    
46
    private $apiVersion;
47
    
48
    private $validator;
49
    
50
    private $guzzleClient;
51
    
52
    /**
53
     * @param string|null $token The API access token, as obtained on diffbot.com/dev
54
     * @throws DiffbotException When no token is provided
55
     */
56
    public function __construct($token = null)
57
    {
58
        
59
        $this->apiBaseUri = 'https://api.bookwhen.com/';
60
            
61
        $this->apiQuery = [];
62
        
63
        $this->apiVersion = 'v2';
64
        
65
        $this->validator = new Validator();
66
        
67
        $this->guzzleClient = new GuzzleClient([
68
            'base_uri' => $this->apiBaseUri
69
        ]);
70
        
71
        if ($token === null) {
72
            if (self::$token === null) {
0 ignored issues
show
introduced by
The condition self::token === null is always false.
Loading history...
73
                $msg = 'No token provided, and none is globally set. ';
74
                $msg .= 'Use Diffbot::setToken, or instantiate the Diffbot class with a $token parameter.';
75
                throw new ConfigurationException($msg);
76
            }
77
        } else {
78
            if ($this->validator->validToken($token)) {
79
                self::$token = $token;
80
                $this->instanceToken = self::$token;
81
            }
82
        }
83
        
84
        if (empty($this->logging)) {
85
            $this->logging = 'debug';
0 ignored issues
show
Bug Best Practice introduced by
The property logging does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
86
            $this->log = 'inShoreBookwhen.log';
0 ignored issues
show
Bug Best Practice introduced by
The property log does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
87
        }
88
        
89
        $this->logger = new Logger('inShore Bookwhen API');
0 ignored issues
show
Bug Best Practice introduced by
The property logger does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
90
        $this->logger->pushHandler(new StreamHandler($this->log, Logger::DEBUG ));
91
        $this->logger->info('Client class successfully instantiated');
92
        $this->logger->debug(var_export($this, true));
93
    }
94
    
95
    /**
96
     * @todo debug flag
97
     */
98
    protected function request(): ResponseInterface
99
    {
100
        try {
101
            // Authorization.
102
            $requestOptions = [
103
                'headers' => [
104
                    'Authorization' => 'Basic ' . base64_encode($this->instanceToken . ':')
105
                ]
106
            ];
107
            
108
            // Query.
109
            if (!empty($this->apiQuery) && is_array($this->apiQuery)) {
110
                $requestOptions['query'] = $this->apiQuery;
111
            }
112
   
113
            $this->logger->debug('request(GET, ' . $this->apiResource . ', ' . var_export($requestOptions, true) . ')');
114
            //$requestOptions['debug'] = true;
115
            
116
            return $this->guzzleClient->request('GET', $this->apiResource, $requestOptions);
117
           
118
        } catch (Exception $e) {
119
            throw new RestException($e, $this->logger);
120
        }
121
    }
122
    
123
    /**
124
     * @todo
125
     */
126
    public function getAttachment($attachmentId)
127
    {
128
        if (!$this->validator->validId($attachmentId, 'attachment')) {
129
            throw new ValidationException('attachmentId', $attachmentId);
0 ignored issues
show
Bug introduced by
'attachmentId' of type string is incompatible with the type InShore\Bookwhen\Exceptions\unknown expected by parameter $key of InShore\Bookwhen\Excepti...xception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

129
            throw new ValidationException(/** @scrutinizer ignore-type */ 'attachmentId', $attachmentId);
Loading history...
130
        }
131
        $this->apiResource = $this->apiVersion . '/attachments' . '/' . $attachmentId;
132
     
133
        try {
134
            $Response = $this->request();
135
            $body = json_decode($Response->getBody()->getContents());
136
            $attachment = $body->data[0];
137
            $return = $attachment;
138
            return $return;
139
        } catch (Exception $e) {
140
            throw new RestException($e, $this->logger);
141
        }
142
    }
143
    
144
    /**
145
     *
146
     * {@inheritDoc}
147
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getAttachments()
148
     * @todo is ! empty then tests each optional param and write validator method.
149
     */
150
    public function getAttachments($title = null, $fileName = null, $fileType = null): array
151
    {    
152
        $this->apiResource = $this->apiVersion . '/attachments';
153
        
154
        try {
155
            $return = [];
156
            $Response = $this->request();
157
            $body = json_decode($Response->getBody()->getContents());
158
            
159
            foreach ($body->data as $attachment) {
160
                array_push($return, $attachment);
161
            }
162
            
163
            return $return;
164
        } catch (Exception $e) {
165
            throw new RestException($e, $this->logger);
166
        }
167
    }
168
    
169
    /**
170
     *
171
     * {@inheritDoc}
172
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getClassPass()
173
     */
174
    public function getClassPass($classPassId)
175
    {
176
        $this->apiResource = $this->apiVersion . '/class_passes';
177
       
178
        if (!$this->validator->validId($classPassId, 'classPass')) {
179
            throw new ValidationException('classPassId', $classPassId);
0 ignored issues
show
Bug introduced by
'classPassId' of type string is incompatible with the type InShore\Bookwhen\Exceptions\unknown expected by parameter $key of InShore\Bookwhen\Excepti...xception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

179
            throw new ValidationException(/** @scrutinizer ignore-type */ 'classPassId', $classPassId);
Loading history...
180
        }
181
     
182
        try {
183
            $Response = $this->request();
184
            $body = json_decode($Response->getBody()->getContents());
185
            $classPass = $body->data[0];
186
            $return = $classPass;
187
            return $return;
188
        } catch (Exception $e) {
189
            throw new RestException($e->getMessage());
0 ignored issues
show
Bug introduced by
The call to InShore\Bookwhen\Excepti...xception::__construct() has too few arguments starting with logger. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

189
            throw /** @scrutinizer ignore-call */ new RestException($e->getMessage());

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
190
        }
191
    }
192
    
193
    /**
194
     *
195
     * {@inheritDoc}
196
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getClassPasses()
197
     * @todo break params on to multiplper lines..
198
     */
199
    public function getClassPasses($title = null, $detail = null, $usageType, $cost = null, $usageAllowance = null, $useRestrictedForDays = null): array
200
    {   
201
        $this->apiResource = $this->apiVersion . '/???';
202
        
203
        // @todo prepocess response onto nice model objects.
204
        $Response = $this->request();
205
        return json_decode($Response->getBody()->getContents());
206
    }
207
    
208
    /**
209
     *
210
     * {@inheritDoc}
211
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getEvent()
212
     */
213
    public function getEvent($eventId)
214
    {
215
        if (!$this->validator->validId($eventId, 'event')) {
216
            throw new ValidationException('eventId', $eventId);
0 ignored issues
show
Bug introduced by
'eventId' of type string is incompatible with the type InShore\Bookwhen\Exceptions\unknown expected by parameter $key of InShore\Bookwhen\Excepti...xception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

216
            throw new ValidationException(/** @scrutinizer ignore-type */ 'eventId', $eventId);
Loading history...
217
        }
218
        $this->apiResource = $this->apiVersion . '/events' . '/' . $eventId;
219
     
220
        try {
221
            $Response = $this->request();
222
            $body = json_decode($Response->getBody()->getContents());
223
            $event = $body->data;
224
            $event->soldOut = (bool) ($event->attributes->attendee_count >= $event->attributes->attendee_limit);
225
            $return = $event;
226
            return $return;
227
        } catch (Exception $e) {
228
            throw new RestException($e, $this->logger);
229
        }
230
    }
231
    
232
    /**
233
     *
234
     * {@inheritDoc}
235
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getEvents()
236
     */
237
    public function getEvents(
238
        $calendar = false,
239
        $entry = false,
240
        $location = [],
241
        $tags = [],
242
        $title = [],
243
        $detail = [],
244
        $from = null,
245
        $to = null,
246
        $includeLocation = false,
247
        $includeAttachments = false,
248
        $includeTickets = false,
249
        $includeTicketsEvents = false,
250
        $includeTicketsClassPasses = false): array
251
    {    
252
        // Validate $tags.
253
        if (!empty($tags)) {
254
            if (!is_array($tags)) {
255
                throw new ValidationException();
0 ignored issues
show
Bug introduced by
The call to InShore\Bookwhen\Excepti...xception::__construct() has too few arguments starting with key. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

255
                throw /** @scrutinizer ignore-call */ new ValidationException();

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
256
            } else {
257
                $tags = array_unique($tags);
258
                foreach ($tags as $tag) {
259
                    if (!empty($tag) && !$this->validator->validTag($tag)) {
260
                        throw new ValidationException();
261
                    }
262
                }
263
            }
264
            $this->apiQuery['filter[tag]'] = implode(',', $tags);
265
        }
266
        
267
        // Validate $from;
268
        if (!empty($from)) {
269
            if (!$this->validator->validFrom($from, $to)) {
270
                throw new ValidationException('from', $from . '-' . $to);
0 ignored issues
show
Bug introduced by
'from' of type string is incompatible with the type InShore\Bookwhen\Exceptions\unknown expected by parameter $key of InShore\Bookwhen\Excepti...xception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

270
                throw new ValidationException(/** @scrutinizer ignore-type */ 'from', $from . '-' . $to);
Loading history...
Bug introduced by
$from . '-' . $to of type string is incompatible with the type InShore\Bookwhen\Exceptions\unknown expected by parameter $value of InShore\Bookwhen\Excepti...xception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

270
                throw new ValidationException('from', /** @scrutinizer ignore-type */ $from . '-' . $to);
Loading history...
271
            } else {
272
                $this->apiQuery['filter[from]'] = $from;
273
            }
274
        }
275
        
276
        // Validate $to;
277
        if (!empty($to)) {
278
            if (!$this->validator->validTo($to, $from)) {
279
                throw new ValidationException('to', $to . '-' . $from);
280
            } else {
281
                $this->apiQuery['filter[to]'] = $to;
282
            }
283
        }
284
        
285
        // API resource.
286
        $this->apiResource = $this->apiVersion . '/events';
287
        
288
        
289
        
290
        // Validate $includeLocation;
291
        
292
        // Validate $includeTickets;
293
  
294
        try {
295
            $Response = $this->request();
296
            
297
            $body = json_decode($Response->getBody()->getContents());
298
            
299
            // Prepocess response onto nice model objects.
300
            // @todo abstract.
301
            $return = [];
302
            
303
            foreach ($body->data as $event) {
304
                // Add additional properties here.
305
                $event->soldOut = (bool) ($event->attributes->attendee_count >= $event->attributes->attendee_limit);
306
                array_push($return, $event);
307
            }
308
            
309
            return $return;
310
        } catch (Exception $e) {
311
            throw new RestException($e, $this->logger);
312
        }
313
    }
314
    
315
    /**
316
     *
317
     * {@inheritDoc}
318
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getLocation()
319
     */
320
    public function getLocation($locationId)
321
    {
322
        $this->apiResource = $this->apiVersion . '/locations';
323
        if (!$this->Valdator->validId($locationId, 'location')) {
0 ignored issues
show
Bug Best Practice introduced by
The property Valdator does not exist on InShore\Bookwhen\Client. Did you maybe forget to declare it?
Loading history...
324
            throw new ValidationException('locationId', $locationId);
0 ignored issues
show
Bug introduced by
'locationId' of type string is incompatible with the type InShore\Bookwhen\Exceptions\unknown expected by parameter $key of InShore\Bookwhen\Excepti...xception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

324
            throw new ValidationException(/** @scrutinizer ignore-type */ 'locationId', $locationId);
Loading history...
325
        }
326
        
327
        try {
328
            $Response = $this->request();
329
            $body = json_decode($Response->getBody()->getContents());
330
            $location = $body->data[0];
331
            $return = $location;
332
            return $return;
333
        } catch (Exception $e) {
334
            throw new RestException($e->getMessage());
0 ignored issues
show
Bug introduced by
The call to InShore\Bookwhen\Excepti...xception::__construct() has too few arguments starting with logger. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

334
            throw /** @scrutinizer ignore-call */ new RestException($e->getMessage());

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
335
        }
336
337
    }
338
    
339
    /**
340
     *
341
     * {@inheritDoc}
342
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getLocations()
343
     * @todo validate params.
344
     */
345
    public function getLocations($addressText = null, $additionalInfo = null): array
346
    {
347
        $this->apiResource = $this->apiVersion . '/locations';
348
349
        $return = [];
350
        
351
        try {
352
            $Response = $this->request();
353
            $body = json_decode($Response->getBody()->getContents());
354
            
355
            foreach ($body->data as $location) {
356
                array_push($return, $location);
357
            }
358
            
359
            return $return;
360
        } catch (Exception $e) {
361
            throw new RestException($e, $this->logger);
362
        }
363
    } 
364
    
365
    /**
366
     *
367
     * {@inheritDoc}
368
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getTicket()
369
     */
370
    public function getTicket($ticketId)
371
    {        
372
        if (!$this->validator->validId($ticketId, 'ticket')) {
373
            throw new ValidationException('ticketId', $ticketId);
0 ignored issues
show
Bug introduced by
'ticketId' of type string is incompatible with the type InShore\Bookwhen\Exceptions\unknown expected by parameter $key of InShore\Bookwhen\Excepti...xception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

373
            throw new ValidationException(/** @scrutinizer ignore-type */ 'ticketId', $ticketId);
Loading history...
374
        }
375
376
        $this->apiResource = $this->apiVersion . '/tickets';
377
378
        
379
        try {
380
            $Response = $this->request();
381
            $body = json_decode($Response->getBody()->getContents());
382
            $ticket = $body->data[0];
383
            $return = $ticket;
384
            return $return;
385
        } catch (Exception $e) {
386
            throw new RestException($e, $this->logger);
387
        }
388
    }
389
    
390
    /**
391
     * 
392
     * {@inheritDoc}
393
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getTickets()
394
     */
395
    public function getTickets($eventId): array
396
    {
397
        if (!$this->validator->validId($eventId, 'event')) {
398
            throw new ValidationException('eventId', $eventId);
0 ignored issues
show
Bug introduced by
'eventId' of type string is incompatible with the type InShore\Bookwhen\Exceptions\unknown expected by parameter $key of InShore\Bookwhen\Excepti...xception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

398
            throw new ValidationException(/** @scrutinizer ignore-type */ 'eventId', $eventId);
Loading history...
399
        }
400
401
        $this->apiQuery = ['event' => $eventId];
402
        
403
        $this->apiResource = $this->apiVersion . '/tickets';
404
                
405
        try {
406
            $return = [];
407
            
408
            $Response = $this->request();
409
            $body = json_decode($Response->getBody()->getContents());
410
            
411
            foreach ($body->data as $ticket) {
412
                array_push($return, $ticket);
413
            }
414
            $this->logger->debug(var_export($return, true));
415
            return $return;
416
        } catch (GuzzleHttp\Exception\ClientException $e) {
417
            throw new RestException($e, $this->logger);
418
        }
419
    }
420
    
421
    /**
422
     * Set Debug.
423
     */
424
    public function setLogging($level)
425
    {
426
        $this->logging = $level;
0 ignored issues
show
Bug Best Practice introduced by
The property logging does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
427
    } 
428
    
429
    /**
430
     * Set Guzzle Client
431
     */
432
    public function setGuzzleClient($guzzleClient)
433
    {
434
        $this->guzzleClient = $guzzleClient;
435
    } 
436
    
437
    /**
438
     * Sets the token for all future new instances
439
     * @param $token string The API access token, as obtained on diffbot.com/dev.
440
     */
441
    public static function setToken($token)
442
    {
443
        $validator = new Validator();
444
        if (!$validator->validToken($token)) {
445
            throw new \InvalidArgumentException('Invalid Token.');
446
        }
447
        self::$token = $token;
448
    } 
449
}
450
451
// EOF!
452