Completed
Push — master ( 718c54...9a8ca3 )
by Marin
02:12
created

Client::get()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 2
1
<?php
2
3
namespace OnFleet;
4
5
use GuzzleHttp\Client as Guzzle;
6
use GuzzleHttp\Exception\ClientException;
7
8
/**
9
 * Class Client
10
 * @package OnFleet
11
 */
12
class Client extends Guzzle
13
{
14
    const BASE_URL = 'https://onfleet.com/api/{version}/';
15
    const VERSION  = 'v2';
16
17
    /**
18
     * Client constructor.
19
     * @param string $username
20
     * @param array $config
21
     */
22
    public function __construct($username, array $config = [])
23
    {
24
        $version = isset($config['version']) ? $config['version'] : static::VERSION;
25
26
        if (!isset($config['base_url'])) {
27
            $config['base_url'] = [
28
                static::BASE_URL,
29
                ['version' => $version]
30
            ];
31
        }
32
        $config['defaults']['auth'] = [$username, null];
33
34
        parent::__construct($config);
35
    }
36
37
    /**
38
     * @param null $url
39
     * @param array $options
40
     * @throws \Exception
41
     * @return \GuzzleHttp\Message\FutureResponse|\GuzzleHttp\Message\ResponseInterface|\GuzzleHttp\Ring\Future\FutureInterface|null
42
     */
43
    public function post($url = null, array $options = [])
44
    {
45
        try {
46
            return parent::post($url, $options);
47
        } catch (ClientException $e) {
48
            $error   = $e->getResponse()->json();
49
            $message = $error['message']['message'];
50
            if (isset($error['message']['cause'])) {
51
                if (is_array($error['message']['cause'])) {
52
                    $message .= ' '. implode(', ', $error['message']['cause']);
53
                } else {
54
                    $message .= ' '. $error['message']['cause'];
55
                }
56
            }
57
            throw new \Exception('Error while calling post on '. $url .': '. $message);
58
        }
59
    }
60
61
    /**
62
     * @param null $url
63
     * @param array $options
64
     * @return \GuzzleHttp\Message\FutureResponse|\GuzzleHttp\Message\ResponseInterface|\GuzzleHttp\Ring\Future\FutureInterface|null
65
     */
66
    public function get($url = null, $options = [])
67
    {
68
        try {
69
            return parent::get($url, $options);
70
        } catch (ClientException $e) {
71
            if ($e->getCode() == 404) {
72
                return null;
73
            }
74
            throw $e;
75
        }
76
    }
77
78
    /**
79
     * @return Organization
80
     */
81
    public function getMyOrganization(): Organization
82
    {
83
        $response = $this->get('organization');
84
        return Organization::fromJson($response->json(['object' => true]), $this);
85
    }
86
87
    /**
88
     * Get delegatee organization
89
     *
90
     * @return Organization
91
     */
92
    public function getOrganization($id): Organization
93
    {
94
        $response = $this->get('organizations/'. $id);
95
        return Organization::fromJson($response->json(['object' => true]), $this);
96
    }
97
98
    /**
99
     * @param array $data {
100
     *     @var string  $name       The administrator’s complete name.
101
     *     @var string  $email      The administrator’s email address.
102
     *     @var string  $phone      Optional. The administrator’s phone number.
103
     *     @var boolean $isReadOnly Optional. Whether this administrator can perform write operations.
104
     * }
105
     * @return Administrator
106
     */
107
    public function createAdministrator(array $data): Administrator
108
    {
109
        $response = $this->post('admins', ['json' => $data]);
110
        return Administrator::fromJson($response->json(['object' => true]), $this);
0 ignored issues
show
Bug introduced by
The method json does only exist in GuzzleHttp\Message\ResponseInterface, but not in GuzzleHttp\Ring\Future\FutureInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
111
    }
112
113
    /**
114
     * @return Administrator[]
115
     */
116
    public function getAdministrators(): array
117
    {
118
        $response = $this->get('admins');
119
120
        $administrators = [];
121
        foreach ($response->json(['object' => true]) as $administratorData) {
122
            $administrators[] = Administrator::fromJson($administratorData, $this);
123
        }
124
125
        return $administrators;
126
    }
127
128
    /**
129
     * @param array $data {
130
     *     @var string  $name       The worker’s complete name.
131
     *     @var string  $phone      A valid phone number as per the worker’s organization’s country.
132
     *     @var string|array $teams One or more team IDs of which the worker is a member.
133
     *     @var object  $vehicle    Optional. The worker’s vehicle; providing no vehicle details is equivalent to the
134
     *                              worker being on foot.
135
     *       @var string $type          The vehicle’s type, must be one of CAR, MOTORCYCLE, BICYCLE or TRUCK.
136
     *       @var string $description   Optional. The vehicle’s make, model, year, or any other relevant identifying details.
137
     *       @var string $licensePlate  Optional. The vehicle’s license plate number.
138
     *       @var string $color         Optional. The vehicle's color.
139
     *     @var integer $capacity   Optional. The maximum number of units this worker can carry, for route optimization purposes.
140
     * }
141
     * @return Worker
142
     */
143
    public function createWorker(array $data): Worker
144
    {
145
        $response = $this->post('workers', ['json' => $data]);
146
        return Worker::fromJson($response->json(['object' => true]), $this);
0 ignored issues
show
Bug introduced by
The method json does only exist in GuzzleHttp\Message\ResponseInterface, but not in GuzzleHttp\Ring\Future\FutureInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
147
    }
148
149
    /**
150
     * @param string $filter Optional. A comma-separated list of fields to return, if all are not desired. For example, name, location.
151
     * @param string $teams  Optional. A comma-separated list of the team IDs that workers must be part of.
152
     * @param string $states Optional. A comma-separated list of worker states, where
153
     *                       0 is off-duty, 1 is idle (on-duty, no active task) and 2 is active (on-duty, active task).
154
     * @return Worker[]
155
     */
156
    public function getWorkers($filter = null, $teams = null, $states = null): array
157
    {
158
        $response = $this->get('workers', [
159
            'query' => [
160
                'filter' => $filter,
161
                'teams'  => $teams,
162
                'states' => $states,
163
            ],
164
        ]);
165
166
        $workers = [];
167
        foreach ($response->json(['object' => true]) as $workerData) {
168
            $workers[] = Worker::fromJson($workerData, $this);
169
        }
170
171
        return $workers;
172
    }
173
174
    /**
175
     * @param string $id
176
     * @param string $filter  Optional. A comma-separated list of fields to return, if all are not desired.
177
     *                        For example: "name, location".
178
     * @param bool $analytics Basic worker duty event, traveled distance (meters) and time analytics are optionally
179
     *                        available by specifying the query parameter analytics as true.
180
     * @return Worker
181
     *
182
     * @todo: Add "from" and "to" timestamps if analytics is true
183
     */
184
    public function getWorker($id, $filter = null, $analytics = false): Worker
185
    {
186
        $response = $this->get('workers/'. $id, [
187
            'query' => [
188
                'filter'    => $filter,
189
                'analytics' => $analytics ? 'true' : 'false',
190
            ],
191
        ]);
192
193
        return Worker::fromJson($response->json(['object' => true]), $this);
194
    }
195
196
    /**
197
     * @return Hub[]
198
     */
199
    public function getHubs(): array
200
    {
201
        $response = $this->get('hubs');
202
203
        $hubs = [];
204
        foreach ($response->json(['object' => true]) as $hubData) {
205
            $hubs[] = Hub::fromJson($hubData, $this);
206
        }
207
208
        return $hubs;
209
    }
210
211
    /**
212
     * @param array $data {
213
     *     @var string $name     A unique name for the team.
214
     *     @var array  $workers  An array of worker IDs.
215
     *     @var array  $managers An array of managing administrator IDs.
216
     *     @var string $hub      Optional. The ID of the team's hub.
217
     * }
218
     *
219
     * @return Team
220
     */
221
    public function createTeam(array $data): Team
222
    {
223
        $response = $this->post('teams', ['json' => $data]);
224
        return Team::fromJson($response->json(['object' => true]), $this);
0 ignored issues
show
Bug introduced by
The method json does only exist in GuzzleHttp\Message\ResponseInterface, but not in GuzzleHttp\Ring\Future\FutureInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
225
    }
226
227
    /**
228
     * @return Team[]
229
     */
230
    public function getTeams(): array
231
    {
232
        $response = $this->get('teams');
233
234
        $teams = [];
235
        foreach ($response->json(['object' => true]) as $teamData) {
236
            $teams[] = Team::fromJson($teamData, $this);
237
        }
238
239
        return $teams;
240
    }
241
242
    /**
243
     * @param $id
244
     * @return Team
245
     */
246
    public function getTeam($id): Team
247
    {
248
        $response = $this->get('teams/'. $id);
249
        return Team::fromJson($response->json(['object' => true]), $this);
250
    }
251
252
    /**
253
     * @param array $data {
254
     *     @var array $address  The destination’s street address details. {
255
     *         @var string $name       Optional. A name associated with this address, e.g., "Transamerica Pyramid".
256
     *         @var string $number     The number component of this address, it may also contain letters.
257
     *         @var string $street     The name of the street.
258
     *         @var string $apartment  Optional. The suite or apartment number, or any additional relevant information.
259
     *         @var string $city       The name of the municipality.
260
     *         @var string $state      Optional. The name of the state, province or jurisdiction.
261
     *         @var string $postalCode Optional. The postal or zip code.
262
     *         @var string $country    The name of the country.
263
     *         @var string $unparsed   Optional. A complete address specified in a single, unparsed string where the
264
     *                                 various elements are separated by commas. If present, all other address
265
     *                                 properties will be ignored (with the exception of name and apartment).
266
     *                                 In some countries, you may skip most address details (like city or state)
267
     *                                 if you provide a valid postalCode: for example,
268
     *                                 543 Howard St, 94105, USA will be geocoded correctly.
269
     *     }
270
     *     @var string $notes   Optional. Note that goes with this destination, e.g. "Please call before"
271
     *     @var array $location Optional. The [ longitude, latitude ] geographic coordinates. If missing, the API will
272
     *                          geocode based on the address details provided. Note that geocoding may slightly modify
273
     *                          the format of the address properties. address.unparsed cannot be provided if you are
274
     *                          also including a location.
275
     * }
276
     * @return Destination
277
     */
278
    public function createDestination(array $data): Destination
279
    {
280
        $response = $this->post('destinations', ['json' => $data]);
281
        return Destination::fromJson($response->json(['object' => true]), $this);
0 ignored issues
show
Bug introduced by
The method json does only exist in GuzzleHttp\Message\ResponseInterface, but not in GuzzleHttp\Ring\Future\FutureInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
282
    }
283
284
    /**
285
     * @param $id
286
     * @return Destination
287
     */
288
    public function getDestination($id): Destination
289
    {
290
        $response = $this->get('destinations/'. $id);
291
        return Destination::fromJson($response->json(['object' => true]), $this);
292
    }
293
294
    /**
295
     * @param array $data {
296
     *     @var string $name    The recipient’s complete name.
297
     *     @var string $phone   A unique, valid phone number as per the recipient’s organization’s country.
298
     *     @var string $notes   Optional. Notes for this recipient: these are global notes that should not be
299
     *                          task- or destination-specific.
300
     *                          For example, "Customer since June 2012, does not drink non-specialty coffee".
301
     *     @var boolean $skipSMSNotifications Optional. Whether this recipient has requested to not receive SMS
302
     *                          notifications. Defaults to false if not provided.
303
     *     @var boolean $skipPhoneNumberValidation Optional. Whether to skip validation of this recipient's phone
304
     *                          number. An E.164-like number is still required (must start with +), however the API
305
     *                          will not enforce any country-specific validation rules.
306
     * }
307
     * @return Recipient
308
     */
309
    public function createRecipient(array $data): Recipient
310
    {
311
        $response = $this->post('recipients', ['json' => $data]);
312
        return Recipient::fromJson($response->json(['object' => true]), $this);
0 ignored issues
show
Bug introduced by
The method json does only exist in GuzzleHttp\Message\ResponseInterface, but not in GuzzleHttp\Ring\Future\FutureInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
313
    }
314
315
    /**
316
     * @param $id
317
     * @return Recipient
318
     */
319
    public function getRecipient($id): Recipient
320
    {
321
        $response = $this->get('recipients/'. $id);
322
        return Recipient::fromJson($response->json(['object' => true]), $this);
323
    }
324
325
    /**
326
     * @param string $name
327
     * @return Recipient|null
328
     */
329
    public function getRecipientByName($name)
330
    {
331
        $name     = str_replace('+', '%20', urlencode(strtolower($name)));
332
        $response = $this->get('recipients/name/'. $name);
333
334
        if (null === $response) {
335
            return null;
336
        }
337
338
        return Recipient::fromJson($response->json(['object' => true]), $this);
339
    }
340
341
    /**
342
     * @param string $phone
343
     * @return Recipient|null
344
     */
345
    public function getRecipientByPhone($phone)
346
    {
347
        $response = $this->get('recipients/phone/'. $phone);
348
349
        if (null === $response) {
350
            return null;
351
        }
352
353
        return Recipient::fromJson($response->json(['object' => true]), $this);
354
    }
355
356
    /**
357
     * @see Task::createAutoAssignedArray
358
     * @param array $data
359
     * @return Task
360
     */
361
    public function createTask(array $data): Task
362
    {
363
        $response = $this->post('tasks', ['json' => $data]);
364
        return Task::fromJson($response->json(['object' => true]), $this);
0 ignored issues
show
Bug introduced by
The method json does only exist in GuzzleHttp\Message\ResponseInterface, but not in GuzzleHttp\Ring\Future\FutureInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
365
    }
366
367
    /**
368
     * @param int|\DateTime $from      The starting time of the range. Tasks created or completed at or after this time will be included.
369
     *                                 Millisecond precision int or DateTime
370
     * @param int|\DateTime $to        Optional. If missing, defaults to the current time. The ending time of the range.
371
     *                                 Tasks created or completed before this time will be included.
372
     *                                 Millisecond precision int or DateTime
373
     * @param string $lastId Optional. Used to walk the paginated response, if there is one. Tasks created after this ID
374
     *                       will be returned, up to the per-query limit of 64.
375
     * @return Task[]
376
     */
377
    public function getTasks($from, $to = null, &$lastId = null): array
378
    {
379
        if ($from instanceof \DateTime) {
380
            $from = $from->getTimestamp() * 1000;
381
        }
382
        if ($to instanceof \DateTime) {
383
            $to = $to->getTimestamp() * 1000;
384
        }
385
        $query = array_filter([
386
            'from'   => $from,
387
            'to'     => $to,
388
            'lastId' => $lastId,
389
        ]);
390
        $response = $this->get('tasks/all', compact('query'));
391
392
        $tasks  = [];
393
        $json   = $response->json(['object' => true]);
394
        $lastId = isset($json->lastId) ? $json->lastId : false;
395
        foreach ($json->tasks as $taskData) {
396
            $tasks[] = Task::fromJson($taskData, $this);
397
        }
398
399
        return $tasks;
400
    }
401
402
    /**
403
     * @param $id
404
     * @return Task
405
     */
406
    public function getTask($id): Task
407
    {
408
        $response = $this->get('tasks/'. $id);
409
        return Task::fromJson($response->json(['object' => true]), $this);
410
    }
411
412
    /**
413
     * @param $shortId
414
     * @return Task
415
     */
416
    public function getTaskByShortId($shortId): Task
417
    {
418
        $response = $this->get('tasks/shortId/'. $shortId);
419
        return Task::fromJson($response->json(['object' => true]), $this);
420
    }
421
422
    /**
423
     * Replace all organization's tasks.
424
     *
425
     * @param array $taskIds
426
     * @param string $organizationId
427
     */
428
    public function setOrganizationTasks(array $taskIds, $organizationId)
429
    {
430
        $this->setContainerTasks('organizations', $organizationId, $taskIds);
431
    }
432
433
    /**
434
     * @param array $taskIds
435
     * @param string $organizationId
436
     */
437
    public function addTasksToOrganization(array $taskIds, $organizationId)
438
    {
439
        $this->setContainerTasks('organizations', $organizationId, $taskIds, -1);
440
    }
441
442
    /**
443
     * Replace all team's tasks.
444
     *
445
     * @param array $taskIds
446
     * @param string $teamId
447
     */
448
    public function setTeamTasks(array $taskIds, $teamId)
449
    {
450
        $this->setContainerTasks('teams', $teamId, $taskIds);
451
    }
452
453
    /**
454
     * @param array $taskIds
455
     * @param string $teamId
456
     */
457
    public function addTasksToTeam(array $taskIds, $teamId)
458
    {
459
        $this->setContainerTasks('teams', $teamId, $taskIds, -1);
460
    }
461
462
    /**
463
     * Replace all worker's tasks.
464
     *
465
     * @param array $taskIds
466
     * @param string $workerId
467
     */
468
    public function setWorkerTasks(array $taskIds, $workerId)
469
    {
470
        $this->setContainerTasks('workers', $workerId, $taskIds);
471
    }
472
473
    /**
474
     * @param array $taskIds
475
     * @param string $workerId
476
     */
477
    public function addTasksToWorker(array $taskIds, $workerId)
478
    {
479
        $this->setContainerTasks('workers', $workerId, $taskIds, -1);
480
    }
481
482
    /**
483
     * @param $url
484
     * @param $triggerId
485
     * @return Webhook
486
     */
487
    public function createWebhook($url, $triggerId): Webhook
488
    {
489
        $response = $this->post('webhooks', [
490
            'json' => [
491
                'url'     => $url,
492
                'trigger' => $triggerId,
493
            ]
494
        ]);
495
496
        return Webhook::fromJson($response->json(['object' => true]), $this);
0 ignored issues
show
Bug introduced by
The method json does only exist in GuzzleHttp\Message\ResponseInterface, but not in GuzzleHttp\Ring\Future\FutureInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
497
    }
498
499
    /**
500
     * @return Webhook[]
501
     */
502
    public function getWebhooks(): array
503
    {
504
        $response = $this->get('webhooks');
505
506
        $webhooks = [];
507
        foreach ($response->json(['object' => true]) as $webhookData) {
508
            $webhooks[] = Webhook::fromJson($webhookData, $this);
509
        }
510
511
        return $webhooks;
512
    }
513
514
    /**
515
     * @param string $containerEndpoint "organizations", "workers" or "teams"
516
     * @param string $targetId          ID of organization, worker or team.
517
     * @param array $taskIds            Array of task IDs.
518
     * @param int $position             Insert tasks at a given index. To append to the end, use -1, to prepend, use 0.
519
     */
520
    private function setContainerTasks($containerEndpoint, $targetId, array $taskIds, $position = null)
521
    {
522
        if (null !== $position) {
523
            if (!is_numeric($position)) {
524
                throw new \InvalidArgumentException('Position argument should be numeric, -1 for appending, 0 to prepend');
525
            }
526
527
            array_unshift($taskIds, $position);
528
        }
529
530
        $this->put('containers/'. $containerEndpoint .'/'. $targetId, [
531
            'json' => [
532
                'tasks' => $taskIds
533
            ]
534
        ]);
535
    }
536
}
537