1 <?php
2
3 namespace Alo;
4
5 use Alo\Exception\ExtensionException as EE;
6 use Log;
7
8 if (!defined('GEN_START')) {
9 http_response_code(404);
10 die();
11 }
12
13 /**
14 * Object-oriented cURL wrapper
15 *
16 * @author Art <a.molcanovas@gmail.com>
17 */
18 class cURL {
19
20 /**
21 * The cURL resource
22 *
23 * @var resource
24 */
25 protected $ch;
26
27 /**
28 * Result of exec()
29 *
30 * @var mixed
31 * @see self::exec()
32 */
33 protected $exec;
34
35 /**
36 * Error number of exec()
37 *
38 * @var int
39 * @see self::exec()
40 */
41 protected $errno;
42
43 /**
44 * Error message of exec()
45 *
46 * @var string
47 * @see self::exec()
48 */
49 protected $error;
50
51 /**
52 * Whether the connection is open
53 *
54 * @var boolean
55 */
56 protected $is_open;
57
58 /**
59 * Instantiates the library
60 *
61 * @author Art <a.molcanovas@gmail.com>
62 * @param string $url Optionally, the URL for curl_init()
63 * @throws EE When the curl extention is not loaded
64 */
65 function __construct($url = null) {
66 if (!function_exists('curl_init')) {
67 throw new EE('cURL PHP extension not loaded', EE::E_EXT_NOT_LOADED);
68 } else {
69 $this->ch = curl_init();
70 $this->is_open = true;
71 curl_setopt_array($this->ch, [
72 CURLOPT_RETURNTRANSFER => true,
73 CURLOPT_SSLVERSION => 3,
74 CURLOPT_SSL_VERIFYPEER => true,
75 CURLOPT_FOLLOWLOCATION => true
76 ]);
77
78 Log::debug('Initialised cURL');
79
80 if ($url) {
81 $this->setURL($url);
82 }
83 }
84 }
85
86 /**
87 * Set whether cURL should time out
88 *
89 * @author Art <a.molcanovas@gmail.com>
90 * @param boolean $enabled The switch
91 * @return cURL
92 */
93 function notimeout($enabled = true) {
94 $a = $enabled ? [
95 CURLOPT_CONNECTTIMEOUT => 86400,
96 CURLOPT_TIMEOUT => 86400
97 ] : [
98 CURLOPT_CONNECTTIMEOUT => 1,
99 CURLOPT_TIMEOUT => 1
100 ];
101
102 Log::debug('cURL timeout ' . ($enabled ? 'en' : 'dis') . 'abled');
103
104 return $this->setopt_array($a);
105 }
106
107 /**
108 * Toggles lax SSL verification mode which doesn't check certificates
109 *
110 * @author Art <a.molcanovas@gmail.com>
111 * @param boolean $enabled Whether the mode is enabled or disabled
112 * @return cURL
113 */
114 function laxSSLMode($enabled = true) {
115 Log::debug(($enabled ? 'Dis' : 'En') . 'abled CURLOPT_SSL_VERIFYPEER');
116 curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, !$enabled);
117
118 return $this;
119 }
120
121 /**
122 * Returns a string representation of the object data
123 *
124 * @author Art <a.molcanovas@gmail.com>
125 * @return string
126 */
127 function __toString() {
128 return \lite_debug($this);
129 }
130
131 /**
132 * A static wrapper function for __construct()
133 *
134 * @author Art <a.molcanovas@gmail.com>
135 * @param string $url Optionally, the URL for curl_init()
136 * @return cURL
137 */
138 static function init($url = null) {
139 return new cURL($url);
140 }
141
142 /**
143 * URL encodes the given string
144 *
145 * @author Art <a.molcanovas@gmail.com>
146 * @param string $str The string
147 * @return string The escaped string
148 * @link http://php.net/manual/en/function.curl-escape.php
149 */
150 function escape($str) {
151 return curl_escape($this->ch, $str);
152 }
153
154 /**
155 * Get information regarding a specific transfer
156 *
157 * @author Art <a.molcanovas@gmail.com>
158 * @param int $opt One of the cURL constants
159 * @return mixed
160 * @link http://php.net/manual/en/function.curl-getinfo.php
161 */
162 function getinfo($opt = 0) {
163 return curl_getinfo($this->ch, $opt);
164 }
165
166 /**
167 * Pause and unpause a connection
168 *
169 * @author Art <a.molcanovas@gmail.com>
170 * @param int $bitmask One of CURLPAUSE_* constants.
171 * @return int An error code (CURLE_OK for no error).
172 * @link http://php.net/manual/en/function.curl-pause.php
173 */
174 function pause($bitmask) {
175 Log::debug('Changed the cURL pause state');
176
177 return curl_pause($this->ch, $bitmask);
178 }
179
180 /**
181 * Gets cURL version information
182 *
183 * @author Art <a.molcanovas@gmail.com>
184 * @param int $age
185 * @return array
186 * @link http://php.net/manual/en/function.curl-version.php
187 */
188 function version($age = CURLVERSION_NOW) {
189 return curl_version($age);
190 }
191
192 /**
193 * Checks whether the last transfer was successful
194 *
195 * @author Art <a.molcanovas@gmail.com>
196 * @return boolean|int If successful - true, if not & cURL error code exists
197 * - cURL error code, false otherwise
198 */
199 function wasSuccessful() {
200 if ($this->errno !== CURLE_OK) {
201 return 'cURL error #' . $this->errno;
202 } else {
203 $code = $this->getinfo(CURLINFO_HTTP_CODE);
204 if (!in_array(substr('' . $this->getinfo(CURLINFO_HTTP_CODE), 0, 1), [1, 2, 3])) {
205 return 'HTML response ' . $code;
206 } else {
207 return true;
208 }
209 }
210 }
211
212 /**
213 * Reset all options of a libcurl session handle
214 *
215 * @author Art <a.molcanovas@gmail.com>
216 * @return cURL
217 * @link http://php.net/manual/en/function.curl-reset.php
218 */
219 function reset() {
220 Log::debug('Reset cURL');
221 curl_reset($this->ch);
222 curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
223
224 return $this;
225 }
226
227 /**
228 * Decodes the given URL encoded string
229 *
230 * @author Art <a.molcanovas@gmail.com>
231 * @param string $str
232 * @return string The decoded string
233 * @link http://php.net/manual/en/function.curl-unescape.php
234 */
235 function unescape($str) {
236 return curl_unescape($this->ch, $str);
237 }
238
239 /**
240 * Auto-cleanup
241 *
242 * @author Art <a.molcanovas@gmail.com>
243 */
244 function __destruct() {
245 $this->close();
246 }
247
248 /**
249 * Sets an option
250 *
251 * @author Art <a.molcanovas@gmail.com>
252 * @param int $name The option - see cURL constants
253 * @param mixed $value The option value
254 * @return cURL
255 * @link http://php.net/manual/en/function.curl-setopt.php
256 */
257 function setopt($name, $value) {
258 if ($name === CURLOPT_POSTFIELDS) {
259 curl_setopt($this->ch, CURLOPT_POST, true);
260 }
261
262 curl_setopt($this->ch, $name, $value);
263
264 return $this;
265 }
266
267 /**
268 * Executes the cURL connection parameters
269 *
270 * @author Art <a.molcanovas@gmail.com>
271 * @return cURL
272 * @link http://php.net/manual/en/function.curl-exec.php
273 */
274 function exec() {
275 Log::debug('Started cURL exec');
276 $this->exec = curl_exec($this->ch);
277 $this->errno = curl_errno($this->ch);
278 $this->error = curl_error($this->ch);
279 Log::debug('Finished curl exec');
280
281 return $this;
282 }
283
284 /**
285 * Gets the results of a cURL exec. If $url is set, will exec on that URL
286 *
287 * @author Art <a.molcanovas@gmail.com>
288 * @param string $url Optional URL override
289 * @return mixed The results of exec()
290 */
291 function get($url = null) {
292 if ($url !== null) {
293 $this->setURL($url)->exec();
294 }
295
296 return $this->exec;
297 }
298
299 /**
300 * Closes a cURL connection
301 *
302 * @author Art <a.molcanovas@gmail.com>
303 * @return cURL
304 * @link http://php.net/manual/en/function.curl-close.php
305 */
306 function close() {
307 if ($this->is_open) {
308 @curl_close($this->ch);
309 $this->is_open = false;
310 Log::debug('Closed cURL connection');
311 }
312
313 return $this;
314 }
315
316 /**
317 * Returns the error message of the last exec()
318 *
319 * @author Art <a.molcanovas@gmail.com>
320 * @return string
321 * @see self::exec()
322 * @link http://php.net/manual/en/function.curl-error.php
323 */
324 function error() {
325 return $this->error;
326 }
327
328 /**
329 * Returns the error number of the last exec() or 0 if no error occurred
330 *
331 * @author Art <a.molcanovas@gmail.com>
332 * @return int
333 * @see self::exec()
334 * @link http://php.net/manual/en/function.curl-errno.php
335 */
336 function errno() {
337 return $this->errno;
338 }
339
340 /**
341 * Sets an array of options
342 *
343 * @author Art <a.molcanovas@gmail.com>
344 * @param array $a An array specifying which options to set and their values. The keys should be valid
345 * curl_setopt() constants or their integer equivalents.
346 * @return cURL
347 * @link http://php.net/manual/en/function.curl-setopt-array.php
348 */
349 function setopt_array(array $a) {
350 curl_setopt_array($this->ch, $a);
351
352 return $this;
353 }
354
355 /**
356 * Sets the connection URL
357 *
358 * @author Art <a.molcanovas@gmail.com>
359 * @param string $url The URL
360 * @return cURL
361 */
362 function setURL($url) {
363 Log::debug('Set cURL URL to ' . $url);
364 curl_setopt($this->ch, CURLOPT_URL, $url);
365
366 return $this;
367 }
368
369 /**
370 * Wrapper for setopt()
371 *
372 * @author Art <a.molcanovas@gmail.com>
373 * @param string $name Param name
374 * @param mixed $value Param value
375 */
376 function __set($name, $value) {
377 $this->setopt($name, $value);
378 }
379
380 }