Test Setup Failed
Pull Request — master (#623)
by Alejandro Carstens
04:04
created

RESTfulService::request()   B

Complexity

Conditions 5
Paths 10

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
cc 5
eloc 13
nc 10
nop 4
1
<?php
2
3
namespace App\Services;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\Exception\ClientException;
7
use InvalidArgumentException;
8
9
/**
10
 * Class RESTfulService.
11
 *
12
 * @method object get($uri)
13
 * @method object post($uri, ...$data)
14
 * @method object put($uri, ...$data)
15
 * @method object patch($uri, ...$data)
16
 * @method object head($uri, ...$data)
17
 * @method object delete($uri)
18
 */
19
class RESTfulService
20
{
21
    protected $responseFormat = 'json';
22
23
    /**
24
     * The API endpoint.
25
     *
26
     * @var string
27
     */
28
    protected $endpoint;
29
30
    /**
31
     * The GuzzleHttp client to talk to the API.
32
     *
33
     * @var Client;
34
     */
35
    protected $client;
36
37
    /**
38
     * The API key.
39
     *
40
     * @var string
41
     */
42
    protected $key;
43
44
    /**
45
     * The query parameter name for the key.
46
     * For example, Last.fm use api_key, like this:
47
     * https://ws.audioscrobbler.com/2.0?method=artist.getInfo&artist=Kamelot&api_key=API_KEY.
48
     *
49
     * @var string
50
     */
51
    protected $keyParam = 'key';
52
53
    /**
54
     * The API secret.
55
     *
56
     * @var string
57
     */
58
    protected $secret;
59
60
    public function __construct($key, $secret, $endpoint, Client $client)
61
    {
62
        $this->setKey($key);
63
        $this->setSecret($secret);
64
        $this->setEndpoint($endpoint);
65
        $this->setClient($client);
66
    }
67
68
    /**
69
     * Make a request to the API.
70
     *
71
     * @param string $verb      The HTTP verb
72
     * @param string $uri       The API URI (segment)
73
     * @param bool   $appendKey Whether to automatically append the API key into the URI.
74
     *                          While it's usually the case, some services (like Last.fm) requires
75
     *                          an "API signature" of the request. Appending an API key will break the request.
76
     * @param array  $params    An array of parameters
77
     *
78
     * @return object|string
79
     */
80
    public function request($verb, $uri, $appendKey = true, array $params = [])
81
    {
82
        try {
83
            $body = (string) $this->getClient()
84
                ->$verb($this->buildUrl($uri, $appendKey), ['form_params' => $params])
85
                ->getBody();
86
87
            if ($this->responseFormat === 'json') {
88
                $response = json_decode($body);
89
                
90
                if(!is_null($response)) return $response;
91
            }
92
93
            if ($this->responseFormat === 'xml') {
94
                return simplexml_load_string($body);
95
            }
96
97
            return $body;
98
        } catch (ClientException $e) {
99
            return false;
100
        }
101
    }
102
103
    /**
104
     * Make an HTTP call to the external resource.
105
     *
106
     * @param string $method The HTTP method
107
     * @param array  $args   An array of parameters
108
     *
109
     * @throws \InvalidArgumentException
110
     *
111
     * @return object
112
     */
113
    public function __call($method, $args)
114
    {
115
        if (count($args) < 1) {
116
            throw new InvalidArgumentException('Magic request methods require a URI and optional options array');
117
        }
118
119
        $uri = $args[0];
120
        $opts = isset($args[1]) ? $args[1] : [];
121
        $appendKey = isset($args[2]) ? $args[2] : true;
122
123
        return $this->request($method, $uri, $appendKey, $opts);
124
    }
125
126
    /**
127
     * Turn a URI segment into a full API URL.
128
     *
129
     * @param string $uri
130
     * @param bool   $appendKey Whether to automatically append the API key into the URL.
131
     *
132
     * @return string
133
     */
134
    public function buildUrl($uri, $appendKey = true)
135
    {
136
        if (!starts_with($uri, ['http://', 'https://'])) {
137
            if ($uri[0] !== '/') {
138
                $uri = "/$uri";
139
            }
140
141
            $uri = $this->endpoint.$uri;
142
        }
143
144
        if ($appendKey) {
145
            if (parse_url($uri, PHP_URL_QUERY)) {
146
                $uri .= "&{$this->keyParam}=".$this->getKey();
147
            } else {
148
                $uri .= "?{$this->keyParam}=".$this->getKey();
149
            }
150
        }
151
152
        return $uri;
153
    }
154
155
    /**
156
     * @return Client
157
     */
158
    public function getClient()
159
    {
160
        return $this->client;
161
    }
162
163
    /**
164
     * @param Client $client
165
     */
166
    public function setClient($client)
167
    {
168
        $this->client = $client;
169
    }
170
171
    /**
172
     * @return string
173
     */
174
    public function getKey()
175
    {
176
        return $this->key;
177
    }
178
179
    /**
180
     * @param string $key
181
     */
182
    public function setKey($key)
183
    {
184
        $this->key = $key;
185
    }
186
187
    /**
188
     * @return string
189
     */
190
    public function getSecret()
191
    {
192
        return $this->secret;
193
    }
194
195
    /**
196
     * @param string $secret
197
     */
198
    public function setSecret($secret)
199
    {
200
        $this->secret = $secret;
201
    }
202
203
    /**
204
     * @return string
205
     */
206
    public function getEndpoint()
207
    {
208
        return $this->endpoint;
209
    }
210
211
    /**
212
     * @param string $endpoint
213
     */
214
    public function setEndpoint($endpoint)
215
    {
216
        $this->endpoint = $endpoint;
217
    }
218
}
219