Completed
Push — master ( 7b51b5...9d49f5 )
by Blackred
04:48
created

ComradeReader::getClient()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
rs 9.4285
cc 2
eloc 6
nc 2
nop 0
1
<?php
2
3
namespace ComradeReader\Service;
4
5
use ComradeReader\Exception\InvalidArgumentException;
6
use ComradeReader\Exception\ResourceNotFoundException;
7
use Doctrine\Common\Cache\CacheProvider;
8
use GuzzleHttp\Client;
9
use GuzzleHttp\ClientInterface;
10
use GuzzleHttp\Exception\ClientException;
11
use Symfony\Component\Serializer\Serializer;
12
13
/**
14
 * Comrade Reader
15
 * ==============
16
 *   Makes requests to API and allows
17
 *   to decode response to objects
18
 *
19
 * Written for Wolnościowiec as a bridge
20
 * between microservices and comrades who
21
 * wants to share the anarchist events,
22
 * articles and news
23
 *
24
 * @url http://wolnosciowiec.net
25
 * @package ComradeReader\Service
26
 */
27
class ComradeReader
28
{
29
    /** @var ClientInterface $client */
30
    protected $client;
31
32
    /** @var string $url */
33
    protected $url;
34
35
    /** @var string $secretToken */
36
    protected $secretToken;
37
38
    /** @var string $tokenFieldName */
39
    protected $tokenFieldName = 'token';
40
41
    /** @var Serializer $serializer */
42
    protected $serializer;
43
44
    /** @var CacheProvider $cache */
45
    protected $cache;
46
47
    /**
48
     * @param string        $apiUrl
49
     * @param string        $apiKey
50
     * @param Serializer    $serializer
51
     * @param CacheProvider $cache
52
     */
53
    public function __construct(
54
        $apiUrl,
55
        $apiKey,
56
        Serializer $serializer,
57
        CacheProvider $cache)
58
    {
59
        $this->url        = $apiUrl;
60
        $this->secretToken     = $apiKey;
61
        $this->serializer = $serializer;
62
        $this->cache      = $cache;
63
    }
64
65
    /**
66
     * @return ClientInterface
67
     */
68
    protected function getClient()
69
    {
70
        if (!$this->client instanceof ClientInterface) {
71
            $this->client     = new Client([
72
                'headers' => [
73
                    'Content-Type' => 'application/json'
74
                ],
75
            ]);
76
        }
77
78
        return $this->client;
79
    }
80
81
    /**
82
     * @param string $tokenFieldName
83
     * @return ComradeReader
84
     */
85
    public function setTokenFieldName($tokenFieldName)
86
    {
87
        $this->tokenFieldName = $tokenFieldName;
88
        return $this;
89
    }
90
91
    /**
92
     * @return string
93
     */
94
    public function getTokenFieldName()
95
    {
96
        return $this->tokenFieldName;
97
    }
98
99
    /**
100
     * @return array
101
     */
102
    protected function getConnectionOptions()
103
    {
104
        return [
105
            'connect_timeout' => 15,
106
            'timeout'         => 15,
107
            //'debug'           => true,
108
        ];
109
    }
110
111
    /**
112
     * Make a request to the server
113
     * and return a decoded response
114
     *
115
     * @param string       $method
116
     * @param string       $url
117
     * @param array        $parameters
118
     * @param int          $cacheLifeTime
119
     *
120
     * @throws InvalidArgumentException
121
     * @throws ResourceNotFoundException
122
     *
123
     * @return ComradeDeserializer
124
     */
125
    public function request(
126
        $method,
127
        $url,
128
        $parameters = [],
129
        $cacheLifeTime = 500
130
    )
131
    {
132
        $parameters = $this->buildParameters($url, $method, $parameters);
133
134
        // read from cache (if available)
135
        if ($cacheLifeTime >= 0 && $this->cache->fetch($this->getCacheId($method, $url, $parameters))) {
136
            return new ComradeDeserializer(
137
                $this->cache->fetch($this->getCacheId($method, $url, $parameters)),
138
                $this->serializer
139
            );
140
        }
141
142
        // send a request
143
        try {
144
            $response = $this->getClient()
145
                ->request(
146
                    $method,
147
                    $this->getPreparedRequestUrl($url),
148
                    $parameters
149
                )->getBody()->getContents();
150
151
        }
152
        catch (ClientException $e) {
153
            if ($e->getCode() === 404) {
154
                throw new ResourceNotFoundException($url);
155
            }
156
157
            throw $e;
158
        }
159
160
        // update cache with a new response from server
161
        if ($cacheLifeTime >= 0) {
162
            $this->cache->save(
163
                $this->getCacheId($method, $url, $parameters),
164
                $response,
165
                $cacheLifeTime
166
            );
167
        }
168
169
        return new ComradeDeserializer($response, $this->serializer);
170
    }
171
172
    /**
173
     * Alias to request()
174
     *
175
     * @param string $url
176
     * @param array  $parameters
177
     * @param int    $cacheLifeTime
178
     *
179
     * @throws ResourceNotFoundException
180
     * @return ComradeDeserializer
181
     */
182
    public function get(
183
        $url,
184
        $parameters = [],
185
        $cacheLifeTime = 500
186
    )
187
    {
188
        return $this->request('GET', $url, $parameters, $cacheLifeTime);
189
    }
190
191
    /**
192
     * Alias to request(), with "POST" preselected as a HTTP method
193
     *
194
     * @param string $url
195
     * @param array  $parameters
196
     * @param int    $cacheLifeTime
197
     *
198
     * @throws ResourceNotFoundException
199
     * @return ComradeDeserializer
200
     */
201
    public function post(
202
        $url,
203
        $parameters = [],
204
        $cacheLifeTime = 500
205
    )
206
    {
207
        return $this->request('POST', $url, $parameters, $cacheLifeTime);
208
    }
209
210
    /**
211
     * Alias to request(), with "PUT" preselected as a HTTP method
212
     *
213
     * @param string $url
214
     * @param array  $parameters
215
     * @param int    $cacheLifeTime
216
     *
217
     * @throws ResourceNotFoundException
218
     * @return ComradeDeserializer
219
     */
220
    public function put(
221
        $url,
222
        $parameters = [],
223
        $cacheLifeTime = 500
224
    )
225
    {
226
        return $this->request('PUT', $url, $parameters, $cacheLifeTime);
227
    }
228
229
    /**
230
     * Alias to request(), with "DELETE" preselected as a HTTP method
231
     *
232
     * @param string $url
233
     * @param array  $parameters
234
     * @param int    $cacheLifeTime
235
     *
236
     * @throws ResourceNotFoundException
237
     * @return ComradeDeserializer
238
     */
239
    public function delete(
240
        $url,
241
        $parameters = [],
242
        $cacheLifeTime = 500
243
    )
244
    {
245
        return $this->request('DELETE', $url, $parameters, $cacheLifeTime);
246
    }
247
248
    /**
249
     * @param string $path
250
     * @return string
251
     */
252
    protected function getPreparedRequestUrl($path)
253
    {
254
        return $this->url . $path;
255
    }
256
257
    /**
258
     * @param string $method
259
     * @param string $url
260
     * @param array $parameters
261
     * @return string
262
     */
263
    protected function getCacheId($method, $url, $parameters)
264
    {
265
        return md5($method . $url . json_encode($parameters));
266
    }
267
268
    /**
269
     * @param string $url
270
     * @param string $method
271
     * @param array  $parameters
272
     *
273
     * @throws \InvalidArgumentException
274
     * @return string
275
     */
276
    protected function buildParameters($url, $method, $parameters)
277
    {
278
        if (!is_array($parameters)) {
279
            throw new \InvalidArgumentException('$parameters should be of type array');
280
        }
281
282
        $query = [
283
            $this->getTokenFieldName() => $this->secretToken
284
        ];
285
286
        // merge query string from the url
287
        $extractedQueryFromUrl = parse_url($url, PHP_URL_QUERY);
288
289
        if (strlen($extractedQueryFromUrl) > 0) {
290
            parse_str($extractedQueryFromUrl, $queryArray);
291
292
            $query = array_merge($query, $queryArray);
293
        }
294
295
        if ('POST' === $method) {
296
            return array_merge($this->getConnectionOptions(), [
297
                'query'       => $query,
298
                'form_params' => $parameters,
299
            ]);
300
        }
301
302
        return array_merge($this->getConnectionOptions(), [
303
            'query' => array_merge($query, $parameters),
304
        ]);
305
    }
306
}