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

Client::getAttachments()   A

Complexity

Conditions 3
Paths 6

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 10
c 0
b 0
f 0
nc 6
nop 3
dl 0
loc 16
ccs 0
cts 10
cp 0
crap 12
rs 9.9332
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