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

RESTfulService::request()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 12
nc 6
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' && !is_null($response = json_decode($body))) {
88
                return $response;
89
            }
90
91
            if ($this->responseFormat === 'xml') {
92
                return simplexml_load_string($body);
93
            }
94
95
            return $body;
96
        } catch (ClientException $e) {
97
            return false;
98
        }
99
    }
100
101
    /**
102
     * Make an HTTP call to the external resource.
103
     *
104
     * @param string $method The HTTP method
105
     * @param array  $args   An array of parameters
106
     *
107
     * @throws \InvalidArgumentException
108
     *
109
     * @return object
110
     */
111
    public function __call($method, $args)
112
    {
113
        if (count($args) < 1) {
114
            throw new InvalidArgumentException('Magic request methods require a URI and optional options array');
115
        }
116
117
        $uri = $args[0];
118
        $opts = isset($args[1]) ? $args[1] : [];
119
        $appendKey = isset($args[2]) ? $args[2] : true;
120
121
        return $this->request($method, $uri, $appendKey, $opts);
122
    }
123
124
    /**
125
     * Turn a URI segment into a full API URL.
126
     *
127
     * @param string $uri
128
     * @param bool   $appendKey Whether to automatically append the API key into the URL.
129
     *
130
     * @return string
131
     */
132
    public function buildUrl($uri, $appendKey = true)
133
    {
134
        if (!starts_with($uri, ['http://', 'https://'])) {
135
            if ($uri[0] !== '/') {
136
                $uri = "/$uri";
137
            }
138
139
            $uri = $this->endpoint.$uri;
140
        }
141
142
        if ($appendKey) {
143
            if (parse_url($uri, PHP_URL_QUERY)) {
144
                $uri .= "&{$this->keyParam}=".$this->getKey();
145
            } else {
146
                $uri .= "?{$this->keyParam}=".$this->getKey();
147
            }
148
        }
149
150
        return $uri;
151
    }
152
153
    /**
154
     * @return Client
155
     */
156
    public function getClient()
157
    {
158
        return $this->client;
159
    }
160
161
    /**
162
     * @param Client $client
163
     */
164
    public function setClient($client)
165
    {
166
        $this->client = $client;
167
    }
168
169
    /**
170
     * @return string
171
     */
172
    public function getKey()
173
    {
174
        return $this->key;
175
    }
176
177
    /**
178
     * @param string $key
179
     */
180
    public function setKey($key)
181
    {
182
        $this->key = $key;
183
    }
184
185
    /**
186
     * @return string
187
     */
188
    public function getSecret()
189
    {
190
        return $this->secret;
191
    }
192
193
    /**
194
     * @param string $secret
195
     */
196
    public function setSecret($secret)
197
    {
198
        $this->secret = $secret;
199
    }
200
201
    /**
202
     * @return string
203
     */
204
    public function getEndpoint()
205
    {
206
        return $this->endpoint;
207
    }
208
209
    /**
210
     * @param string $endpoint
211
     */
212
    public function setEndpoint($endpoint)
213
    {
214
        $this->endpoint = $endpoint;
215
    }
216
}
217