Completed
Push — master ( e9d02e...810a04 )
by Benjamin
01:56
created

Request::callBack()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 1
Metric Value
c 6
b 0
f 1
dl 0
loc 12
rs 9.4285
cc 3
eloc 5
nc 3
nop 1
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
 */
20
class Request implements RequestInterface
21
{
22
    protected $url;
23
    protected $post = [];
24
    protected $result;
25
    protected $listeners = [];
26
    protected $timeout;
27
    protected $curlHandle;
28
    protected $headers = [];
29
    protected $options = [];
30
    protected $success;
31
    protected $response;
32
33
    // 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...
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
    }
90
91
    public function __destruct()
92
    {
93
        if(isset($this->handle)) {
94
            curl_close($this->handle);
95
        }
96
    }
97
98
    /**
99
     * Normalize an array
100
     * change from ['key' => 'value'] format to ['key: value']
101
     * @param array $array array to normalize
102
     * @return array normalized array
103
     */
104
    protected function normalize(array $array)
105
    {
106
        $normalized = [];
107
        foreach ($array as $key => $value) {
108
            if (is_string($key)) {
109
                $normalized[] = $key . ': ' . $value;
110
            } else {
111
                $normalized[] = $value;
112
            }
113
        }
114
        return $normalized;
115
    }
116
117
    /**
118
     * Setter for the url field
119
     * @param string $url url
120
     * @return void
121
     */
122
    public function setUrl($url)
123
    {
124
        if (!filter_var($url, FILTER_VALIDATE_URL) === false) {
125
            $this->url = $url;
126
            $this->updateHandle();
127
        }
128
    }
129
130
    /**
131
     * Getter for url field
132
     * @return string url
133
     */
134
    public function getUrl()
135
    {
136
        return $this->url;
137
    }
138
139
    /**
140
     * Setter for the post data array
141
     * @param array $postData post data
142
     * @return void
143
     */
144
    public function setPostData(array $postData)
145
    {
146
        $this->post = $postData + $this->post;
147
        $this->options[CURLOPT_POST] = 1;
148
        if (!empty($this->post)) {
149
            $this->options[CURLOPT_POSTFIELDS] = http_build_query($this->post);
150
        }
151
        $this->updateHandle();
152
    }
153
154
    /**
155
     * Getter for the post data array
156
     * @return array post data
157
     */
158
    public function getPostData()
159
    {
160
        return $this->post;
161
    }
162
163
    /**
164
     * Returns the time (msec) it took to make the request
165
     * @return float time
166
     */
167
    public function getTime()
168
    {
169
        if (isset($this->handle)) {
170
            return curl_getinfo($this->handle)['total_time'];
171
        }
172
        return (float) 0;
173
    }
174
175
    /**
176
     * Get the result of a query
177
     * @return mixed result
178
     */
179
    public function getResult()
180
    {
181
        return $this->result;
182
    }
183
184
    /**
185
     * This gets called by an agent when a request has completed
186
     * @param array $multiInfo result
187
     */
188
    public function callBack(array $multiInfo)
189
    {
190
        // var_dump($multiInfo);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
191
192
        if(isset($this->curlHandle)) {
193
            $requestInfo = curl_getinfo($this->curlHandle);
194
195
            $this->succes = curl_errno($this->curlHandle) === 0 || intval($requestInfo['http_code']) === 200;
0 ignored issues
show
Bug introduced by
The property succes does not seem to exist. Did you mean success?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

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