Completed
Push — develop ( b1e0d8...d70504 )
by Daniel
14s queued 10s
created

Client::getEvent()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 16
rs 9.8666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace InShore\Bookwhen;
6
7
use GuzzleHttp\Client as GuzzleClient;
8
use GuzzleHttp\Psr7\Request;
9
use InShore\Bookwhen\Exceptions\ConfigurationException;
10
use InShore\Bookwhen\Exceptions\RestException;
11
use InShore\Bookwhen\Exceptions\ValidationException;
12
use InShore\Bookwhen\Interfaces\ClientInterface;
13
use InShore\Bookwhen\Validator;
14
use Psr\Http\Message\ResponseInterface;
15
use InShore\Bookwhen\Exceptions\InshoreBookwhenException;
16
17
/**
18
 * Class Client
19
 *
20
 * The main class for API consumption
21
 *
22
 * @package inshore\bookwhen
23
 * @todo comments
24
 * @todo externalise config
25
 * @todo fix token
26
 */
27
class Client implements ClientInterface
28
{
29
    
30
    /** @var string The API access token */
31
    private static $token = null;
32
    
33
    /** @var string The instance token, settable once per new instance */
34
    private $instanceToken;
35
    
36
    private $apiBaseUri;
37
    
38
    private $apiQuery;
39
   
40
    private $apiResource;
41
    
42
    private $apiVersion;
43
    
44
    private $validator;
45
    
46
    private $guzzleClient;
47
    
48
    /**
49
     * @param string|null $token The API access token, as obtained on diffbot.com/dev
50
     * @throws DiffbotException When no token is provided
51
     */
52
    public function __construct($token = null)
53
    {
54
        
55
        $this->apiBaseUri = 'https://api.bookwhen.com/';
56
            
57
        $this->apiQuery = [];
58
        
59
        $this->apiVersion = 'v2';
60
        
61
        $this->validator = new Validator();
62
        
63
        $this->guzzleClient = new GuzzleClient([
64
            'base_uri' => $this->apiBaseUri
65
        ]);
66
        
67
        if ($token === null) {
68
            if (self::$token === null) {
0 ignored issues
show
introduced by
The condition self::token === null is always false.
Loading history...
69
                $msg = 'No token provided, and none is globally set. ';
70
                $msg .= 'Use Diffbot::setToken, or instantiate the Diffbot class with a $token parameter.';
71
                throw new ConfigurationException($msg);
72
            }
73
        } else {
74
            if ($this->validator->validToken($token)) {
75
                self::$token = $token;
76
                $this->instanceToken = self::$token;
77
            }
78
        }
79
    }
80
    
81
    /**
82
     * @todo debug flag
83
     */
84
    protected function request(): ResponseInterface
85
    {
86
        try {
87
            // Authorization.
88
            $requestOptions = [
89
                'headers' => [
90
                    'Authorization' => 'Basic ' . base64_encode($this->instanceToken . ':')
91
                ]
92
            ];
93
            
94
            // Query.
95
            if (!empty($this->apiQuery) && is_array($this->apiQuery)) {
96
                $requestOptions['query'] = $this->apiQuery;
97
            }
98
   
99
            //$requestOptions['debug'] = true;
100
            
101
            return $this->guzzleClient->request('GET', $this->apiResource, $requestOptions);
102
           
103
        } catch (Exception $e) {
104
            throw new RestException($e);
105
        }
106
    }
107
    
108
    /**
109
     * @todo
110
     */
111
    public function getAttachment($attachmentId)
112
    {
113
        if (!$this->validator->validId($attachmentId, 'attachment')) {
114
            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

114
            throw new ValidationException(/** @scrutinizer ignore-type */ 'attachmentId', $attachmentId);
Loading history...
115
        }
116
        $this->apiResource = $this->apiVersion . '/attachments' . '/' . $attachmentId;
117
     
118
        try {
119
            $Response = $this->request();
120
            $body = json_decode($Response->getBody()->getContents());
121
            $attachment = $body->data[0];
122
            $return = $attachment;
123
            return $return;
124
        } catch (Exception $e) {
125
            throw new RestException($e->getMessage());
126
        }
127
    }
128
    
129
    /**
130
     *
131
     * {@inheritDoc}
132
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getAttachments()
133
     * @todo validate params.
134
     */
135
    public function getAttachments($title = null, $fileName = null, $fileType = null): array
136
    {    
137
        
138
        $this->apiResource = $this->apiVersion . '/attachments';
139
        
140
        try {
141
            $return = [];
142
            $Response = $this->request();
143
            $body = json_decode($Response->getBody()->getContents());
144
            
145
            foreach ($body->data as $attachment) {
146
                array_push($return, $attachment);
147
            }
148
            
149
            return $return;
150
        } catch (Exception $e) {
151
            throw new RestException($e->getMessage());
152
        }
153
    }
154
    
155
    /**
156
     *
157
     * {@inheritDoc}
158
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getClassPass()
159
     */
160
    public function getClassPass($classPassId)
161
    {
162
        $this->apiResource = $this->apiVersion . '/class_passes';
163
       
164
        if (!$this->validator->validId($classPassId, 'classPass')) {
165
            throw ValidationException::class;
166
        }
167
     
168
        try {
169
            $Response = $this->request();
170
            $body = json_decode($Response->getBody()->getContents());
171
            $classPass = $body->data[0];
172
            $return = $classPass;
173
            return $return;
174
        } catch (Exception $e) {
175
            throw new RestException($e->getMessage());;
176
        }
177
    }
178
    
179
    /**
180
     *
181
     * {@inheritDoc}
182
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getClassPasses()
183
     */
184
    public function getClassPasses($title = null, $detail = null, $usageType, $cost = null, $usageAllowance = null, $useRestrictedForDays = null): array
185
    {   
186
        $this->apiResource = $this->apiVersion . '/???';
187
        
188
        // @todo prepocess response onto nice model objects.
189
        $Response = $this->request();
190
        return json_decode($Response->getBody()->getContents());
191
    }
192
    
193
    /**
194
     *
195
     * {@inheritDoc}
196
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getEvent()
197
     */
198
    public function getEvent($eventId)
199
    {
200
        if (!$this->validator->validId($eventId, 'event')) {
201
            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

201
            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...
202
        }
203
        $this->apiResource = $this->apiVersion . '/events' . '/' . $eventId;
204
     
205
        try {
206
            $Response = $this->request();
207
            $body = json_decode($Response->getBody()->getContents());
208
            $event = $body->data;
209
            $event->soldOut = (bool) ($event->attributes->attendee_count >= $event->attributes->attendee_limit);
210
            $return = $event;
211
            return $return;
212
        } catch (Exception $e) {
213
            throw new RestException($e->getMessage());
214
        }
215
    }
216
    
217
    /**
218
     *
219
     * {@inheritDoc}
220
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getEvents()
221
     */
222
    public function getEvents(
223
        $calendar = false,
224
        $entry = false,
225
        $location = [],
226
        $tags = [],
227
        $title = [],
228
        $detail = [],
229
        $from = null,
230
        $to = null,
231
        $includeLocation = false,
232
        $includeAttachments = false,
233
        $includeTickets = false,
234
        $includeTicketsEvents = false,
235
        $includeTicketsClassPasses = false): array
236
    {    
237
        // Validate $tags.
238
        if (!empty($tags)) {
239
            if (!is_array($tags)) {
240
                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

240
                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...
241
            } else {
242
                $tags = array_unique($tags);
243
                foreach ($tags as $tag) {
244
                    if (!empty($tag) && !$this->validator->validTag($tag)) {
245
                        throw new ValidationException();
246
                    }
247
                }
248
            }
249
            $this->apiQuery['filter[tag]'] = implode(',', $tags);
250
        }
251
        
252
        // Validate $from;
253
        if (!empty($from)) {
254
            if (!$this->validator->validFrom($from, $to)) {
255
                throw new ValidationException();
256
            } else {
257
                $this->apiQuery['filter[from]'] = $from;
258
            }
259
        }
260
        
261
        // Validate $to;
262
        if (!empty($to)) {
263
            if (!$this->validator->validTo($to, $from)) {
264
                throw ValidationException::class;
265
            } else {
266
                $this->apiQuery['filter[to]'] = $to;
267
            }
268
        }
269
        
270
        // API resource.
271
        $this->apiResource = $this->apiVersion . '/events';
272
        
273
        
274
        
275
        // Validate $includeLocation;
276
        
277
        // Validate $includeTickets;
278
  
279
        try {
280
            $Response = $this->request();
281
            
282
            $body = json_decode($Response->getBody()->getContents());
283
            
284
            // Prepocess response onto nice model objects.
285
            // @todo abstract.
286
            $return = [];
287
            
288
            foreach ($body->data as $event) {
289
                // Add additional properties here.
290
                $event->soldOut = (bool) ($event->attributes->attendee_count >= $event->attributes->attendee_limit);
291
                array_push($return, $event);
292
            }
293
            
294
            return $return;
295
        } catch (Exception $e) {
296
            throw new RestException($e->getMessage());
297
        }
298
    }
299
    
300
    /**
301
     *
302
     * {@inheritDoc}
303
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getLocation()
304
     */
305
    public function getLocation($locationId)
306
    {
307
        $this->apiResource = $this->apiVersion . '/locations';
308
        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...
309
            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

309
            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...
310
        }
311
        
312
        try {
313
            $Response = $this->request();
314
            $body = json_decode($Response->getBody()->getContents());
315
            $location = $body->data[0];
316
            $return = $location;
317
            return $return;
318
        } catch (Exception $e) {
319
            throw new RestException($e->getMessage());
320
        }
321
322
    }
323
    
324
    /**
325
     *
326
     * {@inheritDoc}
327
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getLocations()
328
     * @todo validate params.
329
     */
330
    public function getLocations($addressText = null, $additionalInfo = null): array
331
    {
332
        $this->apiResource = $this->apiVersion . '/locations';
333
334
        $return = [];
335
        
336
        try {
337
            $Response = $this->request();
338
            $body = json_decode($Response->getBody()->getContents());
339
            
340
            foreach ($body->data as $location) {
341
                array_push($return, $location);
342
            }
343
            
344
            return $return;
345
        } catch (Exception $e) {
346
            throw new RestException($e->getMessage());
347
        }
348
    } 
349
    
350
    /**
351
     *
352
     * {@inheritDoc}
353
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getTicket()
354
     */
355
    public function getTicket($ticketId)
356
    {        
357
        if (!$this->validator->validId($ticketId, 'ticket')) {
358
            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

358
            throw new ValidationException(/** @scrutinizer ignore-type */ 'ticketId', $ticketId);
Loading history...
359
        }
360
361
        $this->apiResource = $this->apiVersion . '/tickets';
362
363
        
364
        try {
365
            $Response = $this->request();
366
            $body = json_decode($Response->getBody()->getContents());
367
            $ticket = $body->data[0];
368
            $return = $ticket;
369
            return $return;
370
        } catch (Exception $e) {
371
            throw new RestException($e->getMessage());
372
        }
373
    }
374
    
375
    /**
376
     * 
377
     * {@inheritDoc}
378
     * @see \InShore\Bookwhen\Interfaces\ClientInterface::getTickets()
379
     */
380
    public function getTickets($eventId): array
381
    {
382
        if (!$this->validator->validId($eventId, 'event')) {
383
            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

383
            throw new ValidationException(/** @scrutinizer ignore-type */ 'eventId', $eventId);
Loading history...
384
        }
385
386
        $this->apiQuery = ['event' => $eventId];
387
        
388
        $this->apiResource = $this->apiVersion . '/tickets';
389
                
390
        try {
391
            $return = [];
392
            
393
            $Response = $this->request();
394
            $body = json_decode($Response->getBody()->getContents());
395
            
396
            foreach ($body->data as $ticket) {
397
                array_push($return, $ticket);
398
            }
399
            
400
            return $return;
401
        } catch (Exception $e) {
402
            throw new RestException($e->getMessage());
403
        }
404
    }
405
    
406
    /**
407
     * Set Guzzle Client
408
     */
409
    public function setGuzzleClient($guzzleClient)
410
    {
411
        $this->guzzleClient = $guzzleClient;
412
    } 
413
    
414
    /**
415
     * Sets the token for all future new instances
416
     * @param $token string The API access token, as obtained on diffbot.com/dev.
417
     */
418
    public static function setToken($token)
419
    {
420
        $validator = new Validator();
421
        if (!$validator->validToken($token)) {
422
            throw new \InvalidArgumentException('Invalid Token.');
423
        }
424
        self::$token = $token;
425
    } 
426
}
427
428
// EOF!
429