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

Client::getTicket()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
c 0
b 0
f 0
nc 5
nop 1
dl 0
loc 17
rs 9.9
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