Passed
Push — master ( 23e4b6...12f961 )
by Evert
02:59 queued 14s
created

VeloClient::prepareUri()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Earnould\LaravelVeloApi;
4
5
use Closure;
6
use GuzzleHttp\Client;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Facades\Cache;
9
use Earnould\LaravelVeloApi\Exceptions\VeloException;
10
11
class VeloClient
12
{
13
    private $guzzleClient;
14
    private $client_id;
15
    private $client_secret;
16
    private $token_url;
17
    private $api_url;
18
    private $apiResponseFormat;
19
20 13
    public function __construct(Client $client = null)
21
    {
22 13
        $this->guzzleClient = $client ?: new Client();
23 13
        $this->client_id = config('laravel-velo-api.client_id');
24 13
        $this->client_secret = config('laravel-velo-api.client_secret');
25 13
        $this->token_url = 'https://antwerp.pub.api.smartbike.com/oauth/v2/token';
26 13
        $this->api_url = 'https://antwerp.pub.api.smartbike.com/api/en/v3';
27 13
        $this->apiResponseFormat = '.json';
28 13
    }
29
30
    /**
31
     * Request Velo API Access Token response.
32
     *
33
     * @return void
34
     */
35 11
    private function requestAccessToken() : string
36
    {
37 11
        $response = $this->guzzleClient->post($this->token_url, [
38
            'form_params'   =>  [
39 11
                'client_id'     => $this->client_id,
40 11
                'client_secret' => $this->client_secret,
41 11
                'grant_type'    => 'client_credentials',
42
            ],
43
        ]);
44
45 11
        $access_token = json_decode($response->getBody()->getContents())->access_token;
46
47 11
        if (! empty($access_token)) {
48 8
            return $access_token;
49
        }
50
51 3
        throw new VeloException('An access token is required to perform requests tothe Velo API', 403);
52
    }
53
54
    /**
55
     * Get cached token or request a new one.
56
     *
57
     * @return void
58
     */
59 11
    public function getAccessToken() : string
60
    {
61 11
        return Cache::remember('access_token', 55, Closure::fromCallable([$this, 'requestAccessToken']));
62
    }
63
64
    /**
65
     * Prepare the uri for a request.
66
     *
67
     * @param $resource
68
     * @return string
69
     */
70 9
    private function prepareUri($resource) : string
71
    {
72 9
        $uri = $this->api_url.'/'.$resource.$this->apiResponseFormat;
73
74 9
        return $uri;
75
    }
76
77
    /**
78
     * Fetch all Velo stations.
79
     *
80
     * @return Collection
81
     */
82 5
    public function fetchStations() : Collection
83
    {
84 5
        $response = $this->guzzleClient->get($this->prepareUri('stations'), [
85
            'headers' => [
86 5
                'Authorization' => 'Bearer '.$this->getAccessToken(),
87
            ],
88
        ]);
89
90
        try {
91 4
            $stations = json_decode($response->getBody()->getContents())->stations;
92 1
        } catch (\ErrorException $e) {
93 1
            throw new VeloException($e->getMessage(), $e->getCode());
94
        }
95
96 3
        return collect($stations);
97
    }
98
99
    /**
100
     * Fetch all Velo stations statuses.
101
     *
102
     * @return Collection
103
     */
104 5
    public function fetchStationsStatuses() : Collection
105
    {
106 5
        $response = $this->guzzleClient->get($this->prepareUri('stations/status'), [
107
            'headers' => [
108 5
                'Authorization' => 'Bearer '.$this->getAccessToken(),
109
            ],
110
        ]);
111
112
        try {
113 4
            $stationsStatuses = json_decode($response->getBody()->getContents())->stationsStatus;
114 1
        } catch (\ErrorException $e) {
115 1
            throw new VeloException($e->getMessage(), $e->getCode());
116
        }
117
118 3
        return collect($stationsStatuses);
119
    }
120
121 1
    public function fetchStationsWithStatus()
122
    {
123 1
        $stations = $this->fetchStations();
124 1
        $statuses = $this->fetchStationsStatuses();
125
126
        $stationsWithStatus = $stations->map(function ($station) use ($statuses) {
127 1
            return (object) array_merge((array) $station, (array) collect($statuses)->firstWhere('id', $station->id));
128 1
        });
129
130 1
        return $stationsWithStatus;
131
    }
132
}
133