ComradeReader::buildParameters()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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