Completed
Push — master ( 57f229...1fda10 )
by Dev
02:31
created

Request::getError()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PiedWeb\Curl;
4
5
class Request
6
{
7
    use UserAgentTrait;
8
9
    const  RETURN_HEADER_ONLY = 2;
10
    const  RETURN_HEADER = 1;
11
12
    /**
13
     * Curl resource handle.
14
     *
15
     * @var resource
16
     */
17
    private $handle;
18
19
    /** @var string contains targeted URL */
20
    private $url;
21
22
    /** @var string contains current UA */
23
    private $userAgent;
24
25
    /** @var int */
26
    private $returnHeaders = 0;
27
28
    /** @var mixed */
29
    private $filter;
30
31
    /** @var bool */
32
    private $optChangeDuringRequest = false;
33
34
    /**
35
     * Constructor.
36
     *
37
     * @param string $ur to request
38
     */
39 24
    public function __construct(?string $url = null)
40
    {
41 24
        $this->handle = curl_init();
42 24
        $this->setOpt(CURLOPT_RETURNTRANSFER, 1);
43
44 24
        if (null !== $url) {
45 24
            $this->setUrl($url);
46
        }
47 24
    }
48
49 24
    public function getHandle()
50
    {
51 24
        return $this->handle;
52
    }
53
54 6
    public function getUrl()
55
    {
56 6
        return $this->url;
57
    }
58
59
    /**
60
     * Change the URL to cURL.
61
     *
62
     * @param string $url to request
63
     *
64
     * @return self
65
     */
66 24
    public function setUrl(string $url)
67
    {
68 24
        $this->url = $url;
69 24
        $this->setOpt(CURLOPT_URL, $url);
70
71 24
        return $this;
72
    }
73
74
    /**
75
     * Add a cURL's option.
76
     *
77
     * @param int   $option cURL Predefined Constant
78
     * @param mixed $value
79
     *
80
     * @return self
81
     */
82 24
    public function setOpt($option, $value)
83
    {
84 24
        curl_setopt($this->handle, $option, $value);
85
86 24
        return $this;
87
    }
88
89
    /**
90
     * A short way to set some classic options to cURL a web page.
91
     *
92
     * @return self
93
     */
94 21
    public function setDefaultGetOptions(
95
        $connectTimeOut = 5,
96
        $timeOut = 10,
97
        $dnsCacheTimeOut = 600,
98
        $followLocation = true,
99
        $maxRedirs = 5
100
    ) {
101
        $this
102 21
            ->setOpt(CURLOPT_AUTOREFERER, 1)
103 21
            ->setOpt(CURLOPT_FOLLOWLOCATION, $followLocation)
104 21
            ->setOpt(CURLOPT_MAXREDIRS, $maxRedirs)
105 21
            ->setOpt(CURLOPT_CONNECTTIMEOUT, $connectTimeOut)
106 21
            ->setOpt(CURLOPT_DNS_CACHE_TIMEOUT, $dnsCacheTimeOut)
107 21
            ->setOpt(CURLOPT_TIMEOUT, $timeOut)
108
             //->setOpt(CURLOPT_SSL_VERIFYPEER,    0);
109
        ;
110
111 21
        return $this;
112
    }
113
114
    /**
115
     * A short way to set some classic options to cURL a web page quickly
116
     * (but loosing some data like header, cookie...).
117
     *
118
     * @return self
119
     */
120 6
    public function setDefaultSpeedOptions()
121
    {
122 6
        $this->setOpt(CURLOPT_SSL_VERIFYHOST, 0);
123 6
        $this->setOpt(CURLOPT_SSL_VERIFYPEER, 0);
124
125 6
        if (!$this->returnHeaders) {
126 6
            $this->setOpt(CURLOPT_HEADER, 0);
127
        }
128
129 6
        $this->setDefaultGetOptions(5, 10, 600, true, 1);
130 6
        $this->setEncodingGzip();
131
132 6
        return $this;
133
    }
134
135
    /**
136
     * Call it if you want header informations.
137
     * After self::exec(), you would have this informations with getHeader();.
138
     *
139
     * @return self
140
     */
141 21
    public function setReturnHeader($only = false)
142
    {
143 21
        $this->setOpt(CURLOPT_HEADER, 1);
144 21
        $this->returnHeaders = $only ? self::RETURN_HEADER_ONLY : self::RETURN_HEADER;
145
146 21
        if ($only) {
147 3
            $this->setOpt(CURLOPT_RETURNTRANSFER, 0);
148 3
            $this->setOpt(CURLOPT_NOBODY, 1);
149
        }
150
151 21
        return $this;
152
    }
153
154 18
    public function mustReturnHeaders()
155
    {
156 18
        return $this->returnHeaders;
157
    }
158
159
    /**
160
     * An self::setOpt()'s alias to add a cookie to your request.
161
     *
162
     * @param string $cookie
163
     *
164
     * @return self
165
     */
166 3
    public function setCookie($cookie)
167
    {
168 3
        $this->setOpt(CURLOPT_COOKIE, $cookie);
169
170 3
        return $this;
171
    }
172
173
    /**
174
     * An self::setOpt()'s alias to add a referer to your request.
175
     *
176
     * @param string $referer
177
     *
178
     * @return self
179
     */
180 18
    public function setReferer($referer)
181
    {
182 18
        $this->setOpt(CURLOPT_REFERER, $referer);
183
184 18
        return $this;
185
    }
186
187
    /**
188
     * An self::setOpt()'s alias to add an user-agent to your request.
189
     *
190
     * @param string $ua
191
     *
192
     * @return self
193
     */
194 21
    public function setUserAgent(string $ua)
195
    {
196 21
        $this->userAgent = $ua;
197
198 21
        $this->setOpt(CURLOPT_USERAGENT, $ua);
199
200 21
        return $this;
201
    }
202
203 3
    public function getUserAgent()
204
    {
205 3
        return $this->userAgent;
206
    }
207
208
    /**
209
     * A short way to set post's options to cURL a web page.
210
     *
211
     * @param mixed $post if it's an array, will be converted via http build query
212
     *
213
     * @return self
214
     */
215 3
    public function setPost($post)
216
    {
217 3
        $this->setOpt(CURLOPT_CUSTOMREQUEST, 'POST');
218 3
        $this->setOpt(CURLOPT_POST, 1);
219 3
        $this->setOpt(CURLOPT_POSTFIELDS, is_array($post) ? http_build_query($post) : $post);
220
221 3
        return $this;
222
    }
223
224
    /**
225
     * If you want to request the URL and hope get the result gzipped.
226
     * The output will be automatically uncompress with exec();.
227
     *
228
     * @return self
229
     */
230 21
    public function setEncodingGzip()
231
    {
232 21
        $this->setOpt(CURLOPT_ENCODING, 'gzip, deflate');
233
234 21
        return $this;
235
    }
236
237
    /**
238
     * If you want to request the URL with a (http|socks...) proxy (public or private).
239
     *
240
     * @param string $proxy [scheme]IP:PORT[:LOGIN:PASSWORD]
241
     *                      Eg. : socks5://98.023.023.02:1098:cUrlRequestProxId:SecretPassword
242
     *
243
     * @return self
244
     */
245 3
    public function setProxy(string $proxy)
246
    {
247 3
        $scheme = Helper::getSchemeFrom($proxy);
248 3
        $proxy = explode(':', $proxy);
249 3
        $this->setOpt(CURLOPT_HTTPPROXYTUNNEL, 1);
250 3
        $this->setOpt(CURLOPT_PROXY, $scheme.$proxy[0].':'.$proxy[1]);
251 3
        if (isset($proxy[2])) {
252
            $this->setOpt(CURLOPT_PROXYUSERPWD, $proxy[2].':'.$proxy[3]);
253
        }
254
255 3
        return $this;
256
    }
257
258
    /**
259
     * @param mixed $func function wich must return boolean
260
     *
261
     * @return self
262
     */
263 18
    public function setDownloadOnlyIf(callable $func)
264
    {
265 18
        $this->setReturnHeader();
266
267 18
        $this->filter = $func;
268 18
        $this->setOpt(CURLOPT_HEADERFUNCTION, [$this, 'checkHeader']);
269 18
        $this->setOpt(CURLOPT_NOBODY, 1);
270
271 18
        return $this;
272
    }
273
274 18
    public function checkHeader($handle, $line)
275
    {
276 18
        if (is_string($line)) {
277 18
            if (call_user_func($this->filter, $line)) {
278 12
                $this->optChangeDuringRequest = true;
279 12
                $this->setOpt(CURLOPT_NOBODY, 0);
280
            }
281
        }
282
283 18
        return strlen($line);
284
    }
285
286
    /**
287
     * Execute the request.
288
     *
289
     * @return Response|int corresponding to the curl error
290
     */
291 24
    public function exec($optChange = false)
292
    {
293 24
        $return = Response::get($this);
294
295
        // Permits to transform HEAD request in GET request
296 24
        if ($this->optChangeDuringRequest && false === $optChange) {
297 12
            $this->optChangeDuringRequest = true;
298
299 12
            return $this->exec(true);
300
        }
301
302 24
        if ($return instanceof Response) {
303 18
            $this->setReferer($return->getEffectiveUrl());
304
        }
305
306 24
        return $return;
307
    }
308
309
    /**
310
     * Return the last error number (curl_errno).
311
     *
312
     * @return int the error number or 0 (zero) if no error occurred
313
     */
314 3
    public function hasError()
315
    {
316 3
        return curl_errno($this->handle);
317
    }
318
319
    /**
320
     * Return a string containing the last error for the current session (curl_error).
321
     *
322
     * @return string the error message or '' (the empty string) if no error occurred
323
     */
324 3
    public function getError()
325
    {
326 3
        return curl_error($this->handle);
327
    }
328
329
    /**
330
     * Get information regarding the request.
331
     *
332
     * @param int $opt This may be one of the following constants:
333
     *                 http://php.net/manual/en/function.curl-getinfo.php
334
     *
335
     * @return array|string|false
336
     */
337 3
    public function getInfo(?int $opt)
338
    {
339 3
        return $opt ? curl_getinfo($this->handle, $opt) : curl_getinfo($this->handle);
340
    }
341
342
    /**
343
     * Close the connexion
344
     * Call curl_reset function.
345
     */
346 3
    public function close()
347
    {
348 3
        curl_reset($this->handle);
349 3
    }
350
}
351