Request::unsetOptions()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php namespace CodeZero\Curl;
2
3
class Request
4
{
5
    /**
6
     * cURL Wrapper
7
     *
8
     * @var Curl
9
     */
10
    private $curl;
11
12
    /**
13
     * Option Parser
14
     *
15
     * @var OptionParser
16
     */
17
    private $optionParser;
18
19
    /**
20
     * Response Factory
21
     *
22
     * @var ResponseFactory
23
     */
24
    private $responseFactory;
25
26
    /**
27
     * cURL Options
28
     *
29
     * @var array
30
     */
31
    private $options = [];
32
33
    /**
34
     * Constructor
35
     *
36
     * @param Curl $curl
37
     * @param OptionParser $optionParser
38
     * @param ResponseFactory $responseFactory
39
     */
40
    public function __construct(Curl $curl = null, OptionParser $optionParser = null, ResponseFactory $responseFactory = null)
41
    {
42
        $this->curl = $curl ?: new Curl();
43
        $this->optionParser = $optionParser ?: new OptionParser();
44
        $this->responseFactory = $responseFactory ?: new ResponseFactory();
45
46
        $this->setDefaultOptions();
47
    }
48
49
    /**
50
     * Send GET request
51
     *
52
     * @param string $url
53
     * @param array $data
54
     * @param array $headers
55
     *
56
     * @return Response
57
     */
58
    public function get($url, array $data = [], array $headers = [])
59
    {
60
        $url = $this->optionParser->parseUrl($url, $data);
61
62
        $this->unsetOption(CURLOPT_POST);
63
64
        $this->setOptions([
65
            CURLOPT_CUSTOMREQUEST => 'GET',
66
            CURLOPT_HTTPGET => true
67
        ]);
68
69
        return $this->send($url, [], $headers);
70
    }
71
72
    /**
73
     * Send POST request
74
     *
75
     * @param string $url
76
     * @param array $data
77
     * @param array $headers
78
     *
79
     * @return Response
80
     */
81 View Code Duplication
    public function post($url, array $data = [], array $headers = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
82
    {
83
        $this->unsetOption(CURLOPT_HTTPGET);
84
85
        $this->setOptions([
86
            CURLOPT_CUSTOMREQUEST => 'POST',
87
            CURLOPT_POST => true
88
        ]);
89
90
        return $this->send($url, $data, $headers);
91
    }
92
93
    /**
94
     * Send PUT request
95
     *
96
     * @param string $url
97
     * @param array $data
98
     * @param array $headers
99
     *
100
     * @return Response
101
     */
102 View Code Duplication
    public function put($url, array $data = [], array $headers = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
103
    {
104
        $this->unsetOptions([CURLOPT_HTTPGET, CURLOPT_POST]);
105
106
        $this->setOption(CURLOPT_CUSTOMREQUEST, 'PUT');
107
108
        return $this->send($url, $data, $headers);
109
    }
110
111
    /**
112
     * Send PATCH request
113
     *
114
     * @param string $url
115
     * @param array $data
116
     * @param array $headers
117
     *
118
     * @return Response
119
     */
120 View Code Duplication
    public function patch($url, array $data = [], array $headers = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
121
    {
122
        $this->unsetOptions([CURLOPT_HTTPGET, CURLOPT_POST]);
123
124
        $this->setOption(CURLOPT_CUSTOMREQUEST, 'PATCH');
125
126
        return $this->send($url, $data, $headers);
127
    }
128
129
    /**
130
     * Send DELETE request
131
     *
132
     * @param string $url
133
     * @param array $data
134
     * @param array $headers
135
     *
136
     * @return Response
137
     */
138 View Code Duplication
    public function delete($url, array $data = [], array $headers = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
139
    {
140
        $this->unsetOptions([CURLOPT_HTTPGET, CURLOPT_POST]);
141
142
        $this->setOption(CURLOPT_CUSTOMREQUEST, 'DELETE');
143
144
        return $this->send($url, $data, $headers);
145
    }
146
147
    /**
148
     * Set or overwrite a cURL option
149
     *
150
     * @param $option
151
     * @param $value
152
     *
153
     * @return void
154
     */
155
    public function setOption($option, $value)
156
    {
157
        $this->options[$option] = $value;
158
    }
159
160
    /**
161
     * Set or overwrite multiple cURL options
162
     *
163
     * @param array $options
164
     *
165
     * @return void
166
     */
167
    public function setOptions(array $options)
168
    {
169
        foreach ($options as $option => $value)
170
        {
171
            $this->setOption($option, $value);
172
        }
173
    }
174
175
    /**
176
     * Unset a cURL option
177
     *
178
     * @param $option
179
     *
180
     * @return void
181
     */
182
    public function unsetOption($option)
183
    {
184
        if (array_key_exists($option, $this->options))
185
        {
186
            unset($this->options[$option]);
187
        }
188
    }
189
190
    /**
191
     * Unset multiple cURL options
192
     *
193
     * @param array $options
194
     *
195
     * @return void
196
     */
197
    public function unsetOptions(array $options)
198
    {
199
        foreach ($options as $option)
200
        {
201
            $this->unsetOption($option);
202
        }
203
    }
204
205
    /**
206
     * Check if an option is set
207
     *
208
     * @param $option
209
     *
210
     * @return bool
211
     */
212
    public function isOptionSet($option)
213
    {
214
        return array_key_exists($option, $this->options);
215
    }
216
217
    /**
218
     * Get the value of an option if it is set
219
     *
220
     * @param $option
221
     *
222
     * @return mixed|null
223
     */
224
    public function getOptionValue($option)
225
    {
226
        if (array_key_exists($option, $this->options))
227
        {
228
            return $this->options[$option];
229
        }
230
231
        return null;
232
    }
233
234
    /**
235
     * Set basic authentication
236
     *
237
     * @param string $username
238
     * @param string $password
239
     *
240
     * @return void
241
     */
242
    public function setBasicAuthentication($username, $password)
243
    {
244
        $this->setOptions([
245
            CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
246
            CURLOPT_USERPWD => "$username:$password"
247
        ]);
248
    }
249
250
    /**
251
     * Unset basic authentication
252
     *
253
     * @return void
254
     */
255
    public function unsetBasicAuthentication()
256
    {
257
        $this->unsetOptions([CURLOPT_HTTPAUTH, CURLOPT_USERPWD]);
258
    }
259
260
    /**
261
     * Set default cURL options
262
     *
263
     * @return void
264
     */
265
    private function setDefaultOptions()
266
    {
267
        $this->setOptions([
268
            CURLOPT_SSL_VERIFYPEER => true,
269
            CURLOPT_HEADER => false,
270
            CURLOPT_RETURNTRANSFER => true, //=> return response instead of boolean
271
            CURLOPT_FAILONERROR => false //=> also return an error when there is a http error >= 400
272
        ]);
273
    }
274
275
    /**
276
     * Set cURL request URL
277
     *
278
     * @param string $url
279
     *
280
     * @return void
281
     */
282
    private function setUrl($url)
283
    {
284
        $this->setOption(CURLOPT_URL, $url);
285
    }
286
287
    /**
288
     * Set request post fields
289
     *
290
     * @param array $data
291
     *
292
     * @return void
293
     */
294
    private function setData(array $data)
295
    {
296
        if ( ! empty($data))
297
        {
298
            $this->setOption(CURLOPT_POSTFIELDS, $this->optionParser->parseData($data));
299
        }
300
        else
301
        {
302
            $this->unsetOption(CURLOPT_POSTFIELDS);
303
        }
304
    }
305
306
    /**
307
     * Set request headers
308
     *
309
     * @param array $headers
310
     *
311
     * @return void
312
     */
313
    private function setHeaders(array $headers)
314
    {
315
        if ( ! empty($headers))
316
        {
317
            $this->setOption(CURLOPT_HTTPHEADER, $this->optionParser->parseHeaders($headers));
318
        }
319
        else
320
        {
321
            $this->unsetOption(CURLOPT_HTTPHEADER);
322
        }
323
    }
324
325
    /**
326
     * Send a request
327
     *
328
     * @param string $url
329
     * @param array $data
330
     * @param array $headers
331
     *
332
     * @return Response
333
     * @throws RequestException
334
     */
335
    private function send($url, array $data = [], array $headers = [])
336
    {
337
        // Set incoming parameters as cURL options
338
        $this->setUrl($url);
339
        $this->setData($data);
340
        $this->setHeaders($headers);
341
342
        return $this->executeCurlRequest();
343
    }
344
345
    /**
346
     * Execute the cURL request
347
     *
348
     * @return Response
349
     * @throws RequestException
350
     */
351
    private function executeCurlRequest()
352
    {
353
        // Send the request and capture the response
354
        $rawResponse = $this->curl->sendRequest($this->options);
355
356
        // Fetch additional information about the request
357
        $responseInfo = $this->curl->getRequestInfo();
358
359
        if ( ! is_array($responseInfo))
360
        {
361
            throw new RequestException('Unable to retrieve request info array!');
362
        }
363
364
        // Get the error (if any)
365
        $errorCode = $this->curl->getErrorCode();
366
        $errorDescription = $this->curl->getErrorDescription();
367
368
        // Close Curl
369
        $this->curl->close();
370
371
        if ($errorCode > 0)
372
        {
373
            // There was a cURL error...
374
            throw new RequestException($errorDescription, $errorCode);
375
        }
376
377
        // Generate a response with the collected information
378
        return $this->responseFactory->make($rawResponse, $responseInfo);
379
    }
380
}
381