Completed
Push — master ( abd222...dd8eb0 )
by Benjamin
02:03
created

Request::getHttpCode()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 3
eloc 5
nc 3
nop 0
1
<?php
2
3
namespace CurlX;
4
5
/**
6
 * Class Request
7
 * @package CurlX
8
 *
9
 * @property string $url url of the Request
10
 * @property array $post_data array of post data
11
 * @property float $total_time running time of the request
12
 * @property int $timeout time (in msec) after which the request will be aborted
13
 * @property array $options cUrl options of the request
14
 * @property array $headers headers of the request
15
 * @property resource $handle cUrl handle of the request
16
 * @property callable[] $listeners array of registered listeners which will be called upon when request finishes
17
 * @property mixed $response curl's response
18
 * @property mixed $result curl result
19
 * @property int $http_code
20
 */
21
class Request implements RequestInterface
22
{
23
    protected $url;
24
    protected $post = [];
25
    protected $result;
26
    protected $listeners = [];
27
    protected $timeout;
28
    protected $curlHandle;
29
    protected $headers = [];
30
    protected $options = [];
31
    protected $success;
32
    protected $response;
33
    protected $httpCode;
34
35
    /**
36
     * Camelizes a string
37
     * @param string $str string to camelize
38
     * @return string camelized string
39
     */
40
    public static function camelize($str)
41
    {
42
        return str_replace('_', '', ucwords($str, '_'));
43
    }
44
45
    /**
46
     * Magic setter function
47
     * @param string $name attribute to set
48
     * @param mixed $value the new value
49
     * @return void
50
     */
51 View Code Duplication
    public function __set($name, $value)
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...
52
    {
53
        $c = static::camelize($name);
54
        $m = "set$c";
55
        if (method_exists($this, $m)) {
56
            $this->$m($value);
57
        } else {
58
            user_error("undefined property $name");
59
        }
60
    }
61
62
    /**
63
     * Magic getter function
64
     * @param string $name of the attribute to get
65
     * @return mixed the attribute's value
66
     */
67 View Code Duplication
    public function __get($name)
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...
68
    {
69
        $c = static::camelize($name);
70
        $m = "get$c";
71
        if (method_exists($this, $m)) {
72
            return $this->$m();
73
        } else {
74
            user_error("undefined property $name");
75
        }
76
    }
77
78
    /**
79
     * Request constructor.
80
     * @param string $url optional url
81
     */
82
    public function __construct($url = null)
83
    {
84
        $this->setUrl($url);
85
86
        // Defaults
87
        $this->options[CURLOPT_RETURNTRANSFER] = true;
88
        $this->options[CURLOPT_NOSIGNAL] = 1;
89
        $this->options[CURLOPT_FOLLOWLOCATION] = true;
90
    }
91
92
    public function __destruct()
93
    {
94
        if(isset($this->curlHandle)) {
95
            curl_close($this->curlHandle);
96
        }
97
    }
98
99
    /**
100
     * Clone the object
101
     */
102
    public function __clone()
103
    {
104
        if(isset($this->curlHandle)) {
105
            $this->curlHandle = curl_copy_handle($this->curlHandle);
106
        }
107
    }
108
109
    /**
110
     * Normalize an array
111
     * change from ['key' => 'value'] format to ['key: value']
112
     * @param array $array array to normalize
113
     * @return array normalized array
114
     */
115
    protected function normalize(array $array)
116
    {
117
        $normalized = [];
118
        foreach ($array as $key => $value) {
119
            if (is_string($key)) {
120
                $normalized[] = $key . ': ' . $value;
121
            } else {
122
                $normalized[] = $value;
123
            }
124
        }
125
        return $normalized;
126
    }
127
128
    /**
129
     * Setter for the url field
130
     * @param string $url url
131
     * @return void
132
     */
133
    public function setUrl($url)
134
    {
135
        if (!filter_var($url, FILTER_VALIDATE_URL) === false) {
136
            $this->url = $url;
137
        }
138
    }
139
140
    /**
141
     * Getter for url field
142
     * @return string url
143
     */
144
    public function getUrl()
145
    {
146
        return $this->url;
147
    }
148
149
    /**
150
     * Setter for the post data array
151
     * @param array $postData post data
152
     * @return void
153
     */
154
    public function setPostData(array $postData)
155
    {
156
        $this->post = $postData + $this->post;
157
        $this->options[CURLOPT_POST] = 1;
158
        if (!empty($this->post)) {
159
            $this->options[CURLOPT_POSTFIELDS] = http_build_query($this->post);
160
        }
161
    }
162
163
    /**
164
     * Getter for the post data array
165
     * @return array post data
166
     */
167
    public function getPostData()
168
    {
169
        return $this->post;
170
    }
171
172
    /**
173
     * Returns the time (msec) it took to make the request
174
     * @return float time
175
     */
176
    public function getTime()
177
    {
178
        if (isset($this->curlHandle)) {
179
            return curl_getinfo($this->curlHandle)['total_time'];
180
        }
181
        return (float) 0;
182
    }
183
184
    /**
185
     * Get the result of a query
186
     * @return mixed result
187
     */
188
    public function getResult()
189
    {
190
        return $this->result;
191
    }
192
193
    /**
194
     * This gets called by an agent when a request has completed
195
     * @param array $multiInfo result
196
     */
197
    public function callBack(array $multiInfo)
198
    {
199
        if(isset($this->curlHandle)) {
200
            $requestInfo = curl_getinfo($this->curlHandle);
201
202
            $this->success = curl_errno($this->curlHandle) === 0 || intval($requestInfo['http_code']) === 200;
203
        }
204
205
        $this->notify();
206
    }
207
208
    /**
209
     * Add a listener that gets notified when the Request has completed
210
     * @param callable $function callback function
211
     * @return void
212
     */
213
    public function addListener(callable $function)
214
    {
215
        if (is_callable($function)) {
216
            if(!in_array($function, $this->listeners)) {
217
                $this->listeners[] = $function;
218
            }
219
        }
220
    }
221
222
    /**
223
     * Notify all listeners of request completion
224
     * @return void
225
     */
226
    protected function notify()
227
    {
228
        foreach ($this->listeners as $listener) {
229
            call_user_func($listener, $this);
230
        }
231
    }
232
233
    /**
234
     * Set a timeout value for the request
235
     * @param float $timeout timeout (msec)
236
     * @return void
237
     */
238
    public function setTimeout($timeout)
239
    {
240
        if ($timeout > 0) {
241
            $this->timeout = $timeout;
242
            $this->options[CURLOPT_TIMEOUT_MS] = $this->timeout;
243
        }
244
    }
245
246
    /**
247
     * Get the timeout value registered for the request
248
     * @return float timeout
249
     */
250
    public function getTimeout()
251
    {
252
        return $this->timeout;
253
    }
254
255
    /**
256
     * Get the cUrl handle for the request
257
     * @return resource cUrl handle
258
     */
259
    public function getHandle()
260
    {
261
        if (!isset($this->curlHandle)) {
262
            $this->curlHandle = curl_init($this->url);
263
            curl_setopt_array($this->curlHandle, $this->options);
264
        }
265
        return $this->curlHandle;
266
    }
267
268
    /**
269
     * Add headers to the request
270
     * @param array $headers headers in ['key' => 'value] or ['key: value'] format
271
     * @return void
272
     */
273
    public function setHeaders(array $headers)
274
    {
275
        $this->headers = $headers + $this->headers;
276
        $this->options[CURLOPT_HTTPHEADER] = $this->normalize($this->headers);
277
    }
278
279
    /**
280
     * Get headers set for the request
281
     * @return array headers in ['key' => 'value'] format
282
     */
283
    public function getHeaders()
284
    {
285
        return $this->headers;
286
    }
287
288
    /**
289
     * Add cUrl options to the request
290
     * @param array $options options in ['key' => 'value'] format
291
     * @return void
292
     */
293
    public function setOptions(array $options)
294
    {
295
        $this->options = $options + $this->options;
296
    }
297
298
    /**
299
     * Get cUrl options set for the request
300
     * @return array options in ['key' => 'value'] format
301
     */
302
    public function getOptions()
303
    {
304
        return $this->options;
305
    }
306
307
    /**
308
     * Get the response for the finished query
309
     * @return mixed response
310
     */
311
    public function getResponse()
312
    {
313
        if(!isset($this->response)) {
314
            if(isset($this->curlHandle)) {
315
                $this->response = curl_multi_getcontent($this->curlHandle);
316
            }
317
        }
318
        return $this->response;
319
    }
320
321
    public function getHttpCode() {
322
        if(!isset($this->httpCode)) {
323
            if(isset($this->curlHandle)) {
324
                $this->httpCode = curl_getinfo($this->curlHandle)['http_code'];
325
            }
326
        }
327
        return $this->httpCode;
328
    }
329
}
330