Passed
Push — master ( 1fda10...0a1ad2 )
by D
02:57
created

Request::setNotFollowRedirection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
ccs 3
cts 3
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
     * A short way to not follow redirection
137
     *
138
     * @return self
139
     */
140 3
    public function setNotFollowRedirection()
141
    {
142
        return $this
143 3
            ->setOpt(CURLOPT_FOLLOWLOCATION, false)
144 3
            ->setOpt(CURLOPT_MAXREDIRS, 0)
145
        ;
146
    }
147
148
    /**
149
     * Call it if you want header informations.
150
     * After self::exec(), you would have this informations with getHeader();.
151
     *
152
     * @return self
153
     */
154 21
    public function setReturnHeader($only = false)
155
    {
156 21
        $this->setOpt(CURLOPT_HEADER, 1);
157 21
        $this->returnHeaders = $only ? self::RETURN_HEADER_ONLY : self::RETURN_HEADER;
158
159 21
        if ($only) {
160 3
            $this->setOpt(CURLOPT_RETURNTRANSFER, 0);
161 3
            $this->setOpt(CURLOPT_NOBODY, 1);
162
        }
163
164 21
        return $this;
165
    }
166
167 18
    public function mustReturnHeaders()
168
    {
169 18
        return $this->returnHeaders;
170
    }
171
172
    /**
173
     * An self::setOpt()'s alias to add a cookie to your request.
174
     *
175
     * @param string $cookie
176
     *
177
     * @return self
178
     */
179 3
    public function setCookie($cookie)
180
    {
181 3
        $this->setOpt(CURLOPT_COOKIE, $cookie);
182
183 3
        return $this;
184
    }
185
186
    /**
187
     * An self::setOpt()'s alias to add a referer to your request.
188
     *
189
     * @param string $referer
190
     *
191
     * @return self
192
     */
193 18
    public function setReferer($referer)
194
    {
195 18
        $this->setOpt(CURLOPT_REFERER, $referer);
196
197 18
        return $this;
198
    }
199
200
    /**
201
     * An self::setOpt()'s alias to add an user-agent to your request.
202
     *
203
     * @param string $ua
204
     *
205
     * @return self
206
     */
207 21
    public function setUserAgent(string $ua)
208
    {
209 21
        $this->userAgent = $ua;
210
211 21
        $this->setOpt(CURLOPT_USERAGENT, $ua);
212
213 21
        return $this;
214
    }
215
216 3
    public function getUserAgent()
217
    {
218 3
        return $this->userAgent;
219
    }
220
221
    /**
222
     * A short way to set post's options to cURL a web page.
223
     *
224
     * @param mixed $post if it's an array, will be converted via http build query
225
     *
226
     * @return self
227
     */
228 3
    public function setPost($post)
229
    {
230 3
        $this->setOpt(CURLOPT_CUSTOMREQUEST, 'POST');
231 3
        $this->setOpt(CURLOPT_POST, 1);
232 3
        $this->setOpt(CURLOPT_POSTFIELDS, is_array($post) ? http_build_query($post) : $post);
233
234 3
        return $this;
235
    }
236
237
    /**
238
     * If you want to request the URL and hope get the result gzipped.
239
     * The output will be automatically uncompress with exec();.
240
     *
241
     * @return self
242
     */
243 21
    public function setEncodingGzip()
244
    {
245 21
        $this->setOpt(CURLOPT_ENCODING, 'gzip, deflate');
246
247 21
        return $this;
248
    }
249
250
    /**
251
     * If you want to request the URL with a (http|socks...) proxy (public or private).
252
     *
253
     * @param string $proxy [scheme]IP:PORT[:LOGIN:PASSWORD]
254
     *                      Eg. : socks5://98.023.023.02:1098:cUrlRequestProxId:SecretPassword
255
     *
256
     * @return self
257
     */
258 3
    public function setProxy(string $proxy)
259
    {
260 3
        $scheme = Helper::getSchemeFrom($proxy);
261 3
        $proxy = explode(':', $proxy);
262 3
        $this->setOpt(CURLOPT_HTTPPROXYTUNNEL, 1);
263 3
        $this->setOpt(CURLOPT_PROXY, $scheme.$proxy[0].':'.$proxy[1]);
264 3
        if (isset($proxy[2])) {
265
            $this->setOpt(CURLOPT_PROXYUSERPWD, $proxy[2].':'.$proxy[3]);
266
        }
267
268 3
        return $this;
269
    }
270
271
    /**
272
     * @param mixed $func function wich must return boolean
273
     *
274
     * @return self
275
     */
276 18
    public function setDownloadOnlyIf(callable $func)
277
    {
278 18
        $this->setReturnHeader();
279
280 18
        $this->filter = $func;
281 18
        $this->setOpt(CURLOPT_HEADERFUNCTION, [$this, 'checkHeader']);
282 18
        $this->setOpt(CURLOPT_NOBODY, 1);
283
284 18
        return $this;
285
    }
286
287 18
    public function checkHeader($handle, $line)
288
    {
289 18
        if (is_string($line)) {
290 18
            if (call_user_func($this->filter, $line)) {
291 12
                $this->optChangeDuringRequest = true;
292 12
                $this->setOpt(CURLOPT_NOBODY, 0);
293
            }
294
        }
295
296 18
        return strlen($line);
297
    }
298
299
    /**
300
     * Execute the request.
301
     *
302
     * @return Response|int corresponding to the curl error
303
     */
304 24
    public function exec($optChange = false)
305
    {
306 24
        $return = Response::get($this);
307
308
        // Permits to transform HEAD request in GET request
309 24
        if ($this->optChangeDuringRequest && false === $optChange) {
310 12
            $this->optChangeDuringRequest = true;
311
312 12
            return $this->exec(true);
313
        }
314
315 24
        if ($return instanceof Response) {
316 18
            $this->setReferer($return->getEffectiveUrl());
317
        }
318
319 24
        return $return;
320
    }
321
322
    /**
323
     * Return the last error number (curl_errno).
324
     *
325
     * @return int the error number or 0 (zero) if no error occurred
326
     */
327 3
    public function hasError()
328
    {
329 3
        return curl_errno($this->handle);
330
    }
331
332
    /**
333
     * Return a string containing the last error for the current session (curl_error).
334
     *
335
     * @return string the error message or '' (the empty string) if no error occurred
336
     */
337 3
    public function getError()
338
    {
339 3
        return curl_error($this->handle);
340
    }
341
342
    /**
343
     * Get information regarding the request.
344
     *
345
     * @param int $opt This may be one of the following constants:
346
     *                 http://php.net/manual/en/function.curl-getinfo.php
347
     *
348
     * @return array|string|false
349
     */
350 3
    public function getInfo(?int $opt)
351
    {
352 3
        return $opt ? curl_getinfo($this->handle, $opt) : curl_getinfo($this->handle);
353
    }
354
355
    /**
356
     * Close the connexion
357
     * Call curl_reset function.
358
     */
359 3
    public function close()
360
    {
361 3
        curl_reset($this->handle);
362 3
    }
363
}
364