Completed
Push — master ( cbdc93...f04bf9 )
by Benjamin
02:26
created

Request::callBack()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 1
Metric Value
c 5
b 0
f 1
dl 0
loc 19
rs 8.8571
cc 5
eloc 12
nc 6
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 $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
        }
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;
147
        $this->options[CURLOPT_POST] = 1;
148
        if (!empty($this->post)) {
149
            $this->options[CURLOPT_POSTFIELDS] = http_build_query($this->post);
150
        }
151
    }
152
153
    /**
154
     * Getter for the post data array
155
     * @return array post data
156
     */
157
    public function getPostData()
158
    {
159
        return $this->post;
160
    }
161
162
    /**
163
     * Returns the time (msec) it took to make the request
164
     * @return float time
165
     */
166
    public function getTime()
167
    {
168
        if(isset($this->startTime) && isset($this->endTime)) {
169
            return $this->endTime - $this->startTime;
170
        }
171
    }
172
173
    /**
174
     * Start the request's internal timer
175
     * @return void
176
     */
177
    public function startTimer()
178
    {
179
        $this->startTime = microtime(true);
180
    }
181
182
    /**
183
     * Stops the request's internal timer
184
     * @return void
185
     */
186
    public function stopTimer()
187
    {
188
        $this->endTime = microtime(true);
189
    }
190
191
    /**
192
     * Get the result of a query
193
     * @return mixed result
194
     */
195
    public function getResult()
196
    {
197
        return $this->result;
198
    }
199
200
    /**
201
     * This gets called by an agent when a request has completed
202
     * @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...
203
     * @return void
204
     */
205
    public function callBack($mutliInfo)
206
    {
207
        $this->stopTimer();
208
        if(array_key_exists('result', $mutliInfo)) {
209
            $this->result = $mutliInfo['result'];
210
        }
211
212
        if(isset($this->curlHandle)) {
213
            $requestInfo = curl_getinfo($this->curlHandle);
214
            if (curl_errno($this->curlHandle) !== 0 || intval($requestInfo['http_code']) !== 200) {
215
                $this->success = false;
216
            } else {
217
                $this->success = true;
218
                $this->response;
219
            }
220
        }
221
222
        $this->notify();
223
    }
224
225
    /**
226
     * Add a listener that gets notified when the Request has completed
227
     * @param callable $function callback function
228
     * @return void
229
     */
230
    public function addListener(callable $function)
231
    {
232
        if (is_callable($function)) {
233
            $this->listeners[] = $function;
234
        }
235
    }
236
237
    /**
238
     * Notify all listeners of request completion
239
     * @return void
240
     */
241
    protected function notify()
242
    {
243
        foreach ($this->listeners as $listener) {
244
            call_user_func($listener, $this);
245
        }
246
    }
247
248
    /**
249
     * Set a timeout value for the request
250
     * @param float $timeout timeout (msec)
251
     * @return void
252
     */
253
    public function setTimeout($timeout)
254
    {
255
        if ($timeout > 0) {
256
            $this->timeout = $timeout;
257
            $this->options[CURLOPT_TIMEOUT_MS] = $this->timeout;
258
        }
259
    }
260
261
    /**
262
     * Get the timeout value registered for the request
263
     * @return float timeout
264
     */
265
    public function getTimeout()
266
    {
267
        return $this->timeout;
268
    }
269
270
    /**
271
     * Get the cUrl handle for the request
272
     * @return resource cUrl handle
273
     */
274
    public function getHandle()
275
    {
276
        if (!isset($this->curlHandle)) {
277
            $this->curlHandle = curl_init($this->url);
278
            curl_setopt_array($this->curlHandle, $this->options);
279
        }
280
281
        return $this->curlHandle;
282
    }
283
284
    /**
285
     * Add headers to the request
286
     * @param array $headers headers in ['key' => 'value] or ['key: value'] format
287
     * @return void
288
     */
289
    public function setHeaders(array $headers)
290
    {
291
        $this->headers += $this->normalize($headers);
292
        $this->options[CURLOPT_HTTPHEADER] = $this->headers;
293
    }
294
295
    /**
296
     * Get headers set for the request
297
     * @return array headers in ['key' => 'value'] format
298
     */
299
    public function getHeaders()
300
    {
301
        return $this->headers;
302
    }
303
304
    /**
305
     * Add cUrl options to the request
306
     * @param array $options options in ['key' => 'value'] format
307
     * @return void
308
     */
309
    public function setOptions(array $options)
310
    {
311
        $this->options += $options;
312
    }
313
314
    /**
315
     * Get cUrl options set for the request
316
     * @return array options in ['key' => 'value'] format
317
     */
318
    public function getOptions()
319
    {
320
        return $this->options;
321
    }
322
323
    /**
324
     * Get the response for the finished query
325
     * @return mixed response
326
     */
327
    public function getResponse()
328
    {
329
        return $this->response;
330
    }
331
}
332