Completed
Push — master ( a9d5d5...81d88c )
by D
02:22
created

Request::mustReturnHeaders()   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 21
    public function __construct(?string $url = null)
40
    {
41 21
        $this->handle = curl_init();
42 21
        $this->setOpt(CURLOPT_RETURNTRANSFER, 1);
43
44 21
        if (null !== $url) {
45 21
            $this->setUrl($url);
46
        }
47 21
    }
48
49 21
    public function getHandle()
50
    {
51 21
        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 21
    public function setUrl(string $url)
67
    {
68 21
        $this->url = $url;
69 21
        $this->setOpt(CURLOPT_URL, $url);
70
71 21
        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 21
    public function setOpt($option, $value)
83
    {
84 21
        curl_setopt($this->handle, $option, $value);
85
86 21
        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
            $this->setOpt(CURLOPT_RETURNTRANSFER, 0);
148
            $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
    public function setPost($post)
216
    {
217
        $this->setOpt(CURLOPT_CUSTOMREQUEST, 'POST');
218
        $this->setOpt(CURLOPT_POST, 1);
219
        $this->setOpt(CURLOPT_POSTFIELDS, is_array($post) ? http_build_query($post) : $post);
220
221
        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
    public function setProxy($proxy)
246
    {
247
        if (!empty($proxy)) {
248
            $scheme = Helper::getSchemeFrom($proxy);
249
            $proxy = explode(':', $proxy);
250
            $this->setOpt(CURLOPT_HTTPPROXYTUNNEL, 1);
251
            $this->setOpt(CURLOPT_PROXY, $scheme.$proxy[0].':'.$proxy[1]);
252
            if (isset($proxy[2])) {
253
                $this->setOpt(CURLOPT_PROXYUSERPWD, $proxy[2].':'.$proxy[3]);
254
            }
255
        }
256
257
        return $this;
258
    }
259
260
    /**
261
     * @param mixed $func function wich must return boolean
262
     *
263
     * @return self
264
     */
265 18
    public function setDownloadOnlyIf(callable $func)
266
    {
267 18
        $this->setReturnHeader();
268
269 18
        $this->filter = $func;
270 18
        $this->setOpt(CURLOPT_HEADERFUNCTION, [$this, 'checkHeader']);
271 18
        $this->setOpt(CURLOPT_NOBODY, 1);
272
273 18
        return $this;
274
    }
275
276 18
    public function checkHeader($handle, $line)
277
    {
278 18
        if (is_string($line)) {
279 18
            if (call_user_func($this->filter, $line)) {
280 12
                $this->optChangeDuringRequest = true;
281 12
                $this->setOpt(CURLOPT_NOBODY, 0);
282
            }
283
        }
284
285 18
        return strlen($line);
286
    }
287
288
    /**
289
     * Execute the request.
290
     *
291
     * @return Response|int corresponding to the curl error
292
     */
293 21
    public function exec($optChange = false)
294
    {
295 21
        $return = Response::get($this);
296
297
        // Permits to transform HEAD request in GET request
298 21
        if ($this->optChangeDuringRequest && false === $optChange) {
299 12
            $this->optChangeDuringRequest = true;
300
301 12
            return $this->exec(true);
302
        }
303
304 21
        if ($return instanceof Response) {
305 18
            $this->setReferer($return->getEffectiveUrl());
306
        }
307
308 21
        return $return;
309
    }
310
311
    /**
312
     * Return the last error number (curl_errno).
313
     *
314
     * @return int the error number or 0 (zero) if no error occurred
315
     */
316
    public function hasError()
317
    {
318
        return curl_errno($this->handle);
319
    }
320
321
    /**
322
     * Return a string containing the last error for the current session (curl_error).
323
     *
324
     * @return string the error message or '' (the empty string) if no error occurred
325
     */
326
    public function getError()
327
    {
328
        return curl_error($this->handle);
329
    }
330
331
    /**
332
     * Get information regarding the request.
333
     *
334
     * @param int $opt This may be one of the following constants:
335
     *                 http://php.net/manual/en/function.curl-getinfo.php
336
     *
337
     * @return array|string|false
338
     */
339
    public function getInfo(?int $opt)
340
    {
341
        return $opt ? curl_getinfo($this->handle, $opt) : curl_getinfo($this->handle);
342
    }
343
344
    /**
345
     * Close the connexion
346
     * Call curl_reset function.
347
     */
348
    public function close()
349
    {
350
        curl_reset($this->handle);
351
    }
352
}
353