Passed
Push — master ( d657dc...438755 )
by Alex
07:49
created

CustomClient::setDeleteTraitMethod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
namespace Mezon\CustomClient;
3
4
/**
5
 * Class CustomClient
6
 *
7
 * @package Mezon
8
 * @subpackage CustomClient
9
 * @author Dodonov A.A.
10
 * @version v.1.0 (2019/08/07)
11
 * @copyright Copyright (c) 2019, aeon.org
12
 */
13
14
/**
15
 * Custom API client class
16
 */
17
class CustomClient
18
{
19
20
    /**
21
     * Server host
22
     *
23
     * @var string
24
     */
25
    protected $url = false;
26
27
    /**
28
     * Headers
29
     *
30
     * @var array
31
     */
32
    protected $headers = [];
33
34
    /**
35
     * Idempotence key
36
     *
37
     * @var string
38
     */
39
    protected $idempotencyKey = '';
40
41
    /**
42
     * Trait PUT requests as POST
43
     *
44
     * @var boolean
45
     */
46
    private $traitPutAsPost = false;
47
48
    /**
49
     * Trait DELETE requests as POST
50
     *
51
     * @var boolean
52
     */
53
    private $traitDeleteAsPost = false;
54
55
    /**
56
     * Constructor
57
     *
58
     * @param string $url
59
     *            Service URL
60
     * @param array $headers
61
     *            HTTP headers
62
     */
63
    public function __construct(string $url, array $headers = [])
64
    {
65
        if ($url === '') {
66
            throw (new \Exception(
67
                'Service URL must be set in class ' . __CLASS__ . ' extended in ' . get_called_class() .
68
                ' and called from ' . ($_SERVER['SERVER_NAME'] ?? 'console') . ($_SERVER['REQUEST_URI'] ?? ''),
69
                - 23));
70
        }
71
72
        $this->url = rtrim($url, '/');
73
74
        $this->headers = $headers;
75
    }
76
77
    /**
78
     * Method send request to the URL
79
     *
80
     * @param string $url
81
     *            URL
82
     * @param array $headers
83
     *            Headers
84
     * @param string $method
85
     *            Request HTTP Method
86
     * @param array $data
87
     *            Request data
88
     * @return array Response body and HTTP code
89
     * @codeCoverageIgnore
90
     */
91
    protected function sendRequest(string $url, array $headers, string $method, array $data = []): array
92
    {
93
        return CurlWrapper::sendRequest($url, $headers, $method, $data);
94
    }
95
96
    /**
97
     * Method gets result and validates it.
98
     *
99
     * @param string $url
100
     *            request URL
101
     * @param int $code
102
     *            response HTTP code
103
     * @param mixed $body
104
     *            response body
105
     * @return mixed Request result
106
     */
107
    protected function dispatchResult(string $url, int $code, $body)
108
    {
109
        if ($code == 0) {
110
            throw (new \Exception("No response from URL : " . $url));
111
        } elseif ($code == 404) {
112
            throw (new \Exception("URL: $url not found"));
113
        } elseif ($code == 400) {
114
            throw (new \Exception("Bad request on URL $url"));
115
        } elseif ($code == 403) {
116
            throw (new \Exception("Auth error"));
117
        }
118
119
        return $body;
120
    }
121
122
    /**
123
     * Method returns common headers
124
     *
125
     * @return array Headers
126
     */
127
    protected function getCommonHeaders(): array
128
    {
129
        $result = $this->headers;
130
131
        if ($this->idempotencyKey !== '') {
132
            $result[] = 'Idempotency-Key: ' . $this->idempotencyKey;
133
        }
134
135
        $result[] = 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0';
136
137
        return $result;
138
    }
139
140
    /**
141
     * Method compiles post headers
142
     *
143
     * @return array Header
144
     */
145
    protected function getFormHeaders(): array
146
    {
147
        $fullHeaders = $this->getCommonHeaders();
148
149
        $fullHeaders[] = 'Content-type: application/x-www-form-urlencoded';
150
151
        return $fullHeaders;
152
    }
153
154
    /**
155
     * Method sends request on server
156
     *
157
     * @param string $method
158
     *            HTTP method (POST|PUT|DELETE)
159
     * @param string $endpoint
160
     *            Calling endpoint
161
     * @param mixed $data
162
     *            Request data
163
     */
164
    protected function sendFormRequest(string $method, string $endpoint, array $data = [])
165
    {
166
        $fullUrl = $this->url . '/' . ltrim($endpoint, '/');
167
168
        list ($body, $code) = $this->sendRequest($fullUrl, $this->getFormHeaders(), $method, $data);
169
170
        return $this->dispatchResult($fullUrl, $code, $body);
171
    }
172
173
    /**
174
     * Method sends POST request to server
175
     *
176
     * @param string $endpoint
177
     *            Calling endpoint
178
     * @param array $data
179
     *            Request data
180
     * @return mixed Result of the request
181
     */
182
    public function sendPostRequest(string $endpoint, array $data = [])
183
    {
184
        return $this->sendFormRequest('POST', $endpoint, $data);
185
    }
186
187
    /**
188
     * Method sends PUT request to server
189
     *
190
     * @param string $endpoint
191
     *            Calling endpoint
192
     * @param array $data
193
     *            Request data
194
     * @return mixed Result of the request
195
     */
196
    public function sendPutRequest(string $endpoint, array $data = [])
197
    {
198
        if ($this->traitPutAsPost) {
199
            return $this->sendPostRequest($endpoint, $data);
200
        } else {
201
            return $this->sendFormRequest('PUT', $endpoint, $data);
202
        }
203
    }
204
205
    /**
206
     * Method sends DELETE request to server
207
     *
208
     * @param string $endpoint
209
     *            Calling endpoint
210
     * @param array $data
211
     *            Request data
212
     * @return mixed Result of the request
213
     */
214
    public function sendDeleteRequest(string $endpoint, array $data = [])
215
    {
216
        if ($this->traitDeleteAsPost) {
217
            return $this->sendPostRequest($endpoint, $data);
218
        } else {
219
            return $this->sendFormRequest('DELETE', $endpoint, $data);
220
        }
221
    }
222
223
    /**
224
     * Method sends GET request to server.
225
     *
226
     * @param string $endpoint
227
     *            Calling endpoint.
228
     * @return mixed Result of the remote call.
229
     */
230
    public function sendGetRequest(string $endpoint)
231
    {
232
        $fullUrl = $this->url . '/' . ltrim($endpoint, '/');
233
234
        $fullUrl = str_replace(' ', '%20', $fullUrl);
235
236
        list ($body, $code) = $this->sendRequest($fullUrl, $this->getCommonHeaders(), 'GET');
237
238
        return $this->dispatchResult($fullUrl, $code, $body);
239
    }
240
241
    /**
242
     * Method sets idempotence key.
243
     * To remove the key just call this method the second time with the '' parameter
244
     *
245
     * @param string $key
246
     *            Idempotence key
247
     */
248
    public function setIdempotencyKey(string $key): void
249
    {
250
        $this->idempotencyKey = $key;
251
    }
252
253
    /**
254
     * Method returns idempotency key
255
     *
256
     * @return string Idempotency key
257
     */
258
    public function getIdempotencyKey(): string
259
    {
260
        return $this->idempotencyKey;
261
    }
262
263
    /**
264
     * Method returns URL
265
     *
266
     * @return string URL
267
     */
268
    public function getUrl(): string
269
    {
270
        return $this->url;
271
    }
272
273
    /**
274
     * Method returns headers
275
     *
276
     * @return array Headers
277
     */
278
    public function getHeaders(): array
279
    {
280
        return $this->headers;
281
    }
282
283
    /**
284
     * Method traits PUT as POST
285
     *
286
     * @param bool $flag
287
     */
288
    public function setPutTraitMethod(bool $flag): void
289
    {
290
        $this->traitPutAsPost = $flag;
291
    }
292
293
    /**
294
     * Method traits DELETE as POST
295
     *
296
     * @param bool $flag
297
     */
298
    public function setDeleteTraitMethod(bool $flag): void
299
    {
300
        $this->traitDeleteAsPost = $flag;
301
    }
302
}
303