Completed
Push — master ( 094d27...3dcc20 )
by Benjamin
02:16
created

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