Completed
Push — master ( 1f4d94...e9d02e )
by Benjamin
01:59
created

Request::updateHandle()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
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 $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
 */
19
class Request implements RequestInterface
20
{
21
    protected $url;
22
    protected $post = [];
23
    protected $startTime;
24
    protected $endTime;
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
34
    // TODO: make __clone()
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
35
36
    /**
37
     * Camelizes a string
38
     * @param string $str string to camelize
39
     * @return string camelized string
40
     */
41
    public static function camelize($str)
42
    {
43
        return str_replace('_', '', ucwords($str, '_'));
44
    }
45
46
    /**
47
     * Magic setter function
48
     * @param string $name attribute to set
49
     * @param mixed $value the new value
50
     * @return void
51
     */
52 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...
53
    {
54
        $c = static::camelize($name);
55
        $m = "set$c";
56
        if (method_exists($this, $m)) {
57
            $this->$m($value);
58
        } else {
59
            user_error("undefined property $name");
60
        }
61
    }
62
63
    /**
64
     * Magic getter function
65
     * @param string $name of the attribute to get
66
     * @return mixed the attribute's value
67
     */
68 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...
69
    {
70
        $c = static::camelize($name);
71
        $m = "get$c";
72
        if (method_exists($this, $m)) {
73
            return $this->$m();
74
        } else {
75
            user_error("undefined property $name");
76
        }
77
    }
78
79
    /**
80
     * Request constructor.
81
     * @param string $url optional url
82
     */
83
    public function __construct($url = null)
84
    {
85
        $this->setUrl($url);
86
87
        // Defaults
88
        $this->options[CURLOPT_RETURNTRANSFER] = true;
89
        $this->options[CURLOPT_NOSIGNAL] = 1;
90
    }
91
92
    public function __destruct()
93
    {
94
        if(isset($this->handle)) {
95
            curl_close($this->handle);
96
        }
97
    }
98
99
    /**
100
     * Normalize an array
101
     * change from ['key' => 'value'] format to ['key: value']
102
     * @param array $array array to normalize
103
     * @return array normalized array
104
     */
105
    protected function normalize(array $array)
106
    {
107
        $normalized = [];
108
        foreach ($array as $key => $value) {
109
            if (is_string($key)) {
110
                $normalized[] = $key . ': ' . $value;
111
            } else {
112
                $normalized[] = $value;
113
            }
114
        }
115
        return $normalized;
116
    }
117
118
    /**
119
     * Setter for the url field
120
     * @param string $url url
121
     * @return void
122
     */
123
    public function setUrl($url)
124
    {
125
        if (!filter_var($url, FILTER_VALIDATE_URL) === false) {
126
            $this->url = $url;
127
            $this->updateHandle();
128
        }
129
    }
130
131
    /**
132
     * Getter for url field
133
     * @return string url
134
     */
135
    public function getUrl()
136
    {
137
        return $this->url;
138
    }
139
140
    /**
141
     * Setter for the post data array
142
     * @param array $postData post data
143
     * @return void
144
     */
145
    public function setPostData(array $postData)
146
    {
147
        $this->post = $postData + $this->post;
148
        $this->options[CURLOPT_POST] = 1;
149
        if (!empty($this->post)) {
150
            $this->options[CURLOPT_POSTFIELDS] = http_build_query($this->post);
151
        }
152
        $this->updateHandle();
153
    }
154
155
    /**
156
     * Getter for the post data array
157
     * @return array post data
158
     */
159
    public function getPostData()
160
    {
161
        return $this->post;
162
    }
163
164
    /**
165
     * Returns the time (msec) it took to make the request
166
     * @return float time
167
     */
168
    public function getTime()
169
    {
170
        if(isset($this->startTime) && isset($this->endTime)) {
171
            return $this->endTime - $this->startTime;
172
        }
173
    }
174
175
    /**
176
     * Start the request's internal timer
177
     * @return void
178
     */
179
    public function startTimer()
180
    {
181
        $this->startTime = microtime(true);
182
    }
183
184
    /**
185
     * Stops the request's internal timer
186
     * @return void
187
     */
188
    public function stopTimer()
189
    {
190
        $this->endTime = microtime(true);
191
    }
192
193
    /**
194
     * Get the result of a query
195
     * @return mixed result
196
     */
197
    public function getResult()
198
    {
199
        return $this->result;
200
    }
201
202
    /**
203
     * This gets called by an agent when a request has completed
204
     * @param mixed $multiInfo result
0 ignored issues
show
Bug introduced by
There is no parameter named $multiInfo. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
205
     * @return void
206
     */
207
    public function callBack($mutliInfo)
208
    {
209
        $this->stopTimer();
210
        if(array_key_exists('result', $mutliInfo)) {
211
            $this->result = $mutliInfo['result'];
212
        }
213
214
        if(isset($this->curlHandle)) {
215
            $requestInfo = curl_getinfo($this->curlHandle);
216
            if (curl_errno($this->curlHandle) !== 0 || intval($requestInfo['http_code']) !== 200) {
217
                $this->success = false;
218
            } else {
219
                $this->success = true;
220
                $this->response;
221
            }
222
        }
223
224
        $this->notify();
225
    }
226
227
    /**
228
     * Add a listener that gets notified when the Request has completed
229
     * @param callable $function callback function
230
     * @return void
231
     */
232
    public function addListener(callable $function)
233
    {
234
        if (is_callable($function)) {
235
            $this->listeners[] = $function;
236
        }
237
    }
238
239
    /**
240
     * Notify all listeners of request completion
241
     * @return void
242
     */
243
    protected function notify()
244
    {
245
        foreach ($this->listeners as $listener) {
246
            call_user_func($listener, $this);
247
        }
248
    }
249
250
    /**
251
     * Set a timeout value for the request
252
     * @param float $timeout timeout (msec)
253
     * @return void
254
     */
255
    public function setTimeout($timeout)
256
    {
257
        if ($timeout > 0) {
258
            $this->timeout = $timeout;
259
            $this->options[CURLOPT_TIMEOUT_MS] = $this->timeout;
260
            $this->updateHandle();
261
        }
262
    }
263
264
    /**
265
     * Get the timeout value registered for the request
266
     * @return float timeout
267
     */
268
    public function getTimeout()
269
    {
270
        return $this->timeout;
271
    }
272
273
    /**
274
     * Get the cUrl handle for the request
275
     * @return resource cUrl handle
276
     */
277
    public function getHandle()
278
    {
279
        if (!isset($this->curlHandle)) {
280
            $this->curlHandle = curl_init($this->url);
281
            $this->updateHandle();
282
        }
283
284
        return $this->curlHandle;
285
    }
286
287
    protected function updateHandle()
288
    {
289
        if(isset($this->handle)) {
290
            curl_setopt_array($this->curlHandle, $this->options);
291
        }
292
    }
293
294
    /**
295
     * Add headers to the request
296
     * @param array $headers headers in ['key' => 'value] or ['key: value'] format
297
     * @return void
298
     */
299
    public function setHeaders(array $headers)
300
    {
301
        $this->headers = $headers + $this->headers;
302
        $this->options[CURLOPT_HTTPHEADER] = $this->normalize($this->headers);
303
        $this->updateHandle();
304
    }
305
306
    /**
307
     * Get headers set for the request
308
     * @return array headers in ['key' => 'value'] format
309
     */
310
    public function getHeaders()
311
    {
312
        return $this->headers;
313
    }
314
315
    /**
316
     * Add cUrl options to the request
317
     * @param array $options options in ['key' => 'value'] format
318
     * @return void
319
     */
320
    public function setOptions(array $options)
321
    {
322
        $this->options = $options + $this->options;
323
        $this->updateHandle();
324
    }
325
326
    /**
327
     * Get cUrl options set for the request
328
     * @return array options in ['key' => 'value'] format
329
     */
330
    public function getOptions()
331
    {
332
        return $this->options;
333
    }
334
335
    /**
336
     * Get the response for the finished query
337
     * @return mixed response
338
     */
339
    public function getResponse()
340
    {
341
        return $this->response;
342
    }
343
}
344