Passed
Pull Request — develop (#58)
by
unknown
08:53
created

Client::getEvents()   C

Complexity

Conditions 12
Paths 56

Size

Total Lines 75
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 30
nc 56
nop 13
dl 0
loc 75
rs 6.9666
c 1
b 0
f 0

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
        if (!is_null($title) && !$this->validator->validTitle($title)) {
153
            throw new ValidationException('title', $title);
0 ignored issues
show
Bug introduced by
'title' 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

153
            throw new ValidationException(/** @scrutinizer ignore-type */ 'title', $title);
Loading history...
154
        }
155
156
        if(!is_null($fileName) && !$this->validator->validFileName($fileName)) {
157
            throw new ValidationException('file name', $fileName);
158
        }
159
160
161
        if(!is_null($fileType) && !$this->validator->validFileType($fileType)) {
162
            throw new ValidationException('file type', $fileType);
163
        }
164
        
165
        $this->apiResource = $this->apiVersion . '/attachments';
166
        
167
        try {
168
            $return = [];
169
            $Response = $this->request();
170
            $body = json_decode($Response->getBody()->getContents());
171
            
172
            foreach ($body->data as $attachment) {
173
                array_push($return, $attachment);
174
            }
175
            
176
            return $return;
177
        } catch (Exception $e) {
178
            throw new RestException($e, $this->logger);
179
        }
180
    }
181
    
182
    /**
183
     *
184
     * {@inheritDoc}
185
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getClassPass()
186
     */
187
    public function getClassPass($classPassId)
188
    {
189
        $this->apiResource = $this->apiVersion . '/class_passes';
190
       
191
        if (!$this->validator->validId($classPassId, 'classPass')) {
192
            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

192
            throw new ValidationException(/** @scrutinizer ignore-type */ 'classPassId', $classPassId);
Loading history...
193
        }
194
     
195
        try {
196
            $Response = $this->request();
197
            $body = json_decode($Response->getBody()->getContents());
198
            $classPass = $body->data[0];
199
            $return = $classPass;
200
            return $return;
201
        } catch (Exception $e) {
202
            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

202
            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...
203
        }
204
    }
205
    
206
    /**
207
     *
208
     * {@inheritDoc}
209
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getClassPasses()
210
     * @todo break params on to multiplper lines..
211
     */
212
    public function getClassPasses(
213
        $title = null, 
214
        $detail = null, 
215
        $usageType, 
216
        $cost = null, 
217
        $usageAllowance = null, 
218
        $useRestrictedForDays = null): array
219
    {   
220
        if (!is_null($title) && !$this->validator->validTitle($title)) {
221
            throw new ValidationException('title', $title);
0 ignored issues
show
Bug introduced by
'title' 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

221
            throw new ValidationException(/** @scrutinizer ignore-type */ 'title', $title);
Loading history...
222
        }
223
       
224
        $this->apiResource = $this->apiVersion . '/???';
225
        
226
        // @todo prepocess response onto nice model objects.
227
        $Response = $this->request();
228
        return json_decode($Response->getBody()->getContents());
229
    }
230
    
231
    /**
232
     *
233
     * {@inheritDoc}
234
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getEvent()
235
     */
236
    public function getEvent($eventId)
237
    {
238
        if (!$this->validator->validId($eventId, 'event')) {
239
            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

239
            throw new ValidationException(/** @scrutinizer ignore-type */ 'eventId', $eventId);
Loading history...
240
        }
241
        $this->apiResource = $this->apiVersion . '/events' . '/' . $eventId;
242
     
243
        try {
244
            $Response = $this->request();
245
            $body = json_decode($Response->getBody()->getContents());
246
            $event = $body->data;
247
            $event->soldOut = (bool) ($event->attributes->attendee_count >= $event->attributes->attendee_limit);
248
            $return = $event;
249
            return $return;
250
        } catch (Exception $e) {
251
            throw new RestException($e, $this->logger);
252
        }
253
    }
254
    
255
    /**
256
     *
257
     * {@inheritDoc}
258
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getEvents()
259
     */
260
    public function getEvents(
261
        $calendar = false,
262
        $entry = false,
263
        $location = [],
264
        $tags = [],
265
        $title = [],
266
        $detail = [],
267
        $from = null,
268
        $to = null,
269
        $includeLocation = false,
270
        $includeAttachments = false,
271
        $includeTickets = false,
272
        $includeTicketsEvents = false,
273
        $includeTicketsClassPasses = false): array
274
    {    
275
        // Validate $tags.
276
        if (!empty($tags)) {
277
            if (!is_array($tags)) {
278
                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

278
                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...
279
            } else {
280
                $tags = array_unique($tags);
281
                foreach ($tags as $tag) {
282
                    if (!empty($tag) && !$this->validator->validTag($tag)) {
283
                        throw new ValidationException();
284
                    }
285
                }
286
            }
287
            $this->apiQuery['filter[tag]'] = implode(',', $tags);
288
        }
289
        
290
        // Validate $from;
291
        if (!empty($from)) {
292
            if (!$this->validator->validFrom($from, $to)) {
293
                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

293
                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

293
                throw new ValidationException('from', /** @scrutinizer ignore-type */ $from . '-' . $to);
Loading history...
294
            } else {
295
                $this->apiQuery['filter[from]'] = $from;
296
            }
297
        }
298
        
299
        // Validate $to;
300
        if (!empty($to)) {
301
            if (!$this->validator->validTo($to, $from)) {
302
                throw new ValidationException('to', $to . '-' . $from);
303
            } else {
304
                $this->apiQuery['filter[to]'] = $to;
305
            }
306
        }
307
        
308
        // API resource.
309
        $this->apiResource = $this->apiVersion . '/events';
310
        
311
        
312
        
313
        // Validate $includeLocation;
314
        
315
        // Validate $includeTickets;
316
  
317
        try {
318
            $Response = $this->request();
319
            
320
            $body = json_decode($Response->getBody()->getContents());
321
            
322
            // Prepocess response onto nice model objects.
323
            // @todo abstract.
324
            $return = [];
325
            
326
            foreach ($body->data as $event) {
327
                // Add additional properties here.
328
                $event->soldOut = (bool) ($event->attributes->attendee_count >= $event->attributes->attendee_limit);
329
                array_push($return, $event);
330
            }
331
            
332
            return $return;
333
        } catch (Exception $e) {
334
            throw new RestException($e, $this->logger);
335
        }
336
    }
337
    
338
    /**
339
     *
340
     * {@inheritDoc}
341
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getLocation()
342
     */
343
    public function getLocation($locationId)
344
    {
345
        $this->apiResource = $this->apiVersion . '/locations';
346
        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...
347
            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

347
            throw new ValidationException(/** @scrutinizer ignore-type */ 'locationId', $locationId);
Loading history...
348
        }
349
        
350
        try {
351
            $Response = $this->request();
352
            $body = json_decode($Response->getBody()->getContents());
353
            $location = $body->data[0];
354
            $return = $location;
355
            return $return;
356
        } catch (Exception $e) {
357
            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

357
            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...
358
        }
359
360
    }
361
    
362
    /**
363
     *
364
     * {@inheritDoc}
365
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getLocations()
366
     * @todo validate params.
367
     */
368
    public function getLocations($addressText = null, $additionalInfo = null): array
369
    {
370
        $this->apiResource = $this->apiVersion . '/locations';
371
372
        $return = [];
373
        
374
        try {
375
            $Response = $this->request();
376
            $body = json_decode($Response->getBody()->getContents());
377
            
378
            foreach ($body->data as $location) {
379
                array_push($return, $location);
380
            }
381
            
382
            return $return;
383
        } catch (Exception $e) {
384
            throw new RestException($e, $this->logger);
385
        }
386
    } 
387
    
388
    /**
389
     *
390
     * {@inheritDoc}
391
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getTicket()
392
     */
393
    public function getTicket($ticketId)
394
    {        
395
        if (!$this->validator->validId($ticketId, 'ticket')) {
396
            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

396
            throw new ValidationException(/** @scrutinizer ignore-type */ 'ticketId', $ticketId);
Loading history...
397
        }
398
399
        $this->apiResource = $this->apiVersion . '/tickets';
400
401
        
402
        try {
403
            $Response = $this->request();
404
            $body = json_decode($Response->getBody()->getContents());
405
            $ticket = $body->data[0];
406
            $return = $ticket;
407
            return $return;
408
        } catch (Exception $e) {
409
            throw new RestException($e, $this->logger);
410
        }
411
    }
412
    
413
    /**
414
     * 
415
     * {@inheritDoc}
416
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getTickets()
417
     */
418
    public function getTickets($eventId): array
419
    {
420
        if (!$this->validator->validId($eventId, 'event')) {
421
            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

421
            throw new ValidationException(/** @scrutinizer ignore-type */ 'eventId', $eventId);
Loading history...
422
        }
423
424
        $this->apiQuery = ['event' => $eventId];
425
        
426
        $this->apiResource = $this->apiVersion . '/tickets';
427
                
428
        try {
429
            $return = [];
430
            
431
            $Response = $this->request();
432
            $body = json_decode($Response->getBody()->getContents());
433
            
434
            foreach ($body->data as $ticket) {
435
                array_push($return, $ticket);
436
            }
437
            $this->logger->debug(var_export($return, true));
438
            return $return;
439
        } catch (GuzzleHttp\Exception\ClientException $e) {
440
            throw new RestException($e, $this->logger);
441
        }
442
    }
443
    
444
    /**
445
     * Set Debug.
446
     */
447
    public function setLogging($level)
448
    {
449
        $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...
450
    } 
451
    
452
    /**
453
     * Set Guzzle Client
454
     */
455
    public function setGuzzleClient($guzzleClient)
456
    {
457
        $this->guzzleClient = $guzzleClient;
458
    } 
459
    
460
    /**
461
     * Sets the token for all future new instances
462
     * @param $token string The API access token, as obtained on diffbot.com/dev.
463
     */
464
    public static function setToken($token)
465
    {
466
        $validator = new Validator();
467
        if (!$validator->validToken($token)) {
468
            throw new \InvalidArgumentException('Invalid Token.');
469
        }
470
        self::$token = $token;
471
    } 
472
}
473
474
// EOF!
475