1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
if (!function_exists('rgb2hex')) { |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* @param int $red |
7
|
|
|
* @param int $green |
8
|
|
|
* @param int $blue |
9
|
|
|
* @return string |
10
|
|
|
* @see https://gist.github.com/Pushplaybang/5432844 |
11
|
|
|
*/ |
12
|
|
|
function rgb2hex(int $red, int $green, int $blue): string |
13
|
|
|
{ |
14
|
|
|
$hex = "#"; |
15
|
|
|
$hex .= str_pad(dechex($red), 2, "0", STR_PAD_LEFT); |
16
|
|
|
$hex .= str_pad(dechex($green), 2, "0", STR_PAD_LEFT); |
17
|
|
|
$hex .= str_pad(dechex($blue), 2, "0", STR_PAD_LEFT); |
18
|
|
|
|
19
|
|
|
return $hex; // returns the hex value including the number sign (#) |
20
|
|
|
} |
21
|
|
|
} |
22
|
|
|
|
23
|
|
|
if (!function_exists('hex2rgb')) { |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Takes HEX color code value and converts to a RGB value. |
27
|
|
|
* |
28
|
|
|
* @param string $color Color hex value, example: #000000, #000 or 000000, 000 |
29
|
|
|
* |
30
|
|
|
* @return string color rbd value |
31
|
|
|
*/ |
32
|
|
|
function hex2rgb($color) |
33
|
|
|
{ |
34
|
|
|
$color = str_replace('#', '', $color); |
35
|
|
|
if (strlen($color) == 3): |
36
|
|
|
list($r, $g, $b) = [$color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2]]; |
37
|
|
|
else: |
38
|
|
|
list($r, $g, $b) = [$color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5]]; |
39
|
|
|
endif; |
40
|
|
|
$r = hexdec($r); |
41
|
|
|
$g = hexdec($g); |
42
|
|
|
$b = hexdec($b); |
43
|
|
|
return 'rgb(' . $r . ', ' . $g . ', ' . $b . ')'; |
44
|
|
|
} |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @param float $val |
49
|
|
|
* @param int $precision |
50
|
|
|
* @param string $simbol |
51
|
|
|
* @param bool $prepend if true (default) prefix with $simbol, otherwise suffix with $simbol. |
52
|
|
|
* @return string |
53
|
|
|
*/ |
54
|
|
|
function format_money(float $val = 0.00, int $precision = 2, string $simbol = "", bool $prepend=true) : string |
55
|
|
|
{ |
56
|
|
|
$prefix = $simbol.' '; |
57
|
|
|
$suffix = ''; |
58
|
|
|
if(!$prepend){ |
59
|
|
|
$prefix = ''; |
60
|
|
|
$suffix = ' '.$simbol; |
61
|
|
|
} |
62
|
|
|
return $prefix . number_format($val, $precision, ',', '.').$suffix; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* Format float 1125.86 into string '&euro 1.125,86' |
67
|
|
|
* @param float $val |
68
|
|
|
* @param bool $prepend if true (default) prefix with '€ ', otherwise suffix with ' €'. |
69
|
|
|
* @return string |
70
|
|
|
*/ |
71
|
|
|
function format_euro(float $val = 0.00, bool $prepend=true) : string |
72
|
|
|
{ |
73
|
|
|
return format_money($val, 2, '€ ', $prepend); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
if (!function_exists('ordinal')) { |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Given a number, return the number + 'th' or 'rd' etc |
80
|
|
|
* @param $cdnl |
81
|
|
|
* @return string |
82
|
|
|
*/ |
83
|
|
|
function ordinal($cdnl) |
84
|
|
|
{ |
85
|
|
|
$test_c = abs($cdnl) % 10; |
86
|
|
|
$ext = ((abs($cdnl) % 100 < 21 && abs($cdnl) % 100 > 4) ? 'th' |
87
|
|
|
: (($test_c < 4) ? ($test_c < 3) ? ($test_c < 2) ? ($test_c < 1) |
88
|
|
|
? 'th' : 'st' : 'nd' : 'rd' : 'th')); |
89
|
|
|
return $cdnl . $ext; |
90
|
|
|
} |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
if (!function_exists('value')) { |
94
|
|
|
/** |
95
|
|
|
* Return the default value of the given value. |
96
|
|
|
* |
97
|
|
|
* @param mixed $value |
98
|
|
|
* @return mixed |
99
|
|
|
*/ |
100
|
|
|
function value($value) |
101
|
|
|
{ |
102
|
|
|
return $value instanceof Closure ? $value() : $value; |
103
|
|
|
} |
104
|
|
|
} |
105
|
|
|
if (!function_exists('with')) { |
106
|
|
|
/** |
107
|
|
|
* Return the given object. Useful for chaining. |
108
|
|
|
* |
109
|
|
|
* @param mixed $object |
110
|
|
|
* @return mixed |
111
|
|
|
*/ |
112
|
|
|
function with($object) |
113
|
|
|
{ |
114
|
|
|
return $object; |
115
|
|
|
} |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Set the default configuration of erro reporting for production. |
120
|
|
|
*/ |
121
|
|
|
function setErrorReportingForProduction() |
122
|
|
|
{ |
123
|
|
|
if (version_compare(PHP_VERSION, '5.4.0') >= 0) { |
124
|
|
|
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT); |
125
|
|
|
} elseif (version_compare(PHP_VERSION, '5.3.0') >= 0) { |
126
|
|
|
error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED); |
127
|
|
|
} else { |
128
|
|
|
error_reporting(E_ALL ^ E_NOTICE); |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Check if PHP script was executed by shell. |
134
|
|
|
* @return bool |
135
|
|
|
*/ |
136
|
|
|
function isExecutedByCLI() : bool |
137
|
|
|
{ |
138
|
|
|
return php_sapi_name() == 'cli'; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Convert the output of PHP's filesize() function |
143
|
|
|
* to a nice format with PB, TB, GB, MB, kB, bytes. |
144
|
|
|
* @param $bytes |
145
|
|
|
* @param int $decimals [optional] default 0. Sets the number of decimal points. |
146
|
|
|
* @return string |
147
|
|
|
*/ |
148
|
|
|
function bytes2HumanSize($bytes, $decimals=0) |
149
|
|
|
{ |
150
|
|
|
if(!isIntegerPositiveOrZero($decimals)){ |
151
|
|
|
$decimals = 0; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
if ($bytes >= 1125899906842624) { |
155
|
|
|
$bytes = number_format($bytes / 1073741824, $decimals) . ' PB'; |
156
|
|
|
} elseif ($bytes >= 1099511627776) { |
157
|
|
|
$bytes = number_format($bytes / 1073741824, $decimals) . ' TB'; |
158
|
|
|
} elseif ($bytes >= 1073741824) { |
159
|
|
|
$bytes = number_format($bytes / 1073741824, $decimals) . ' GB'; |
160
|
|
|
} elseif ($bytes >= 1048576) { |
161
|
|
|
$bytes = number_format($bytes / 1048576, $decimals) . ' MB'; |
162
|
|
|
} elseif ($bytes >= 1024) { |
163
|
|
|
$bytes = number_format($bytes / 1024, $decimals) . ' kB'; |
164
|
|
|
} elseif ($bytes > 1) { |
165
|
|
|
$bytes .= ' bytes'; |
166
|
|
|
} elseif ($bytes == 1) { |
167
|
|
|
$bytes .= ' byte'; |
168
|
|
|
} else { |
169
|
|
|
$bytes = '0 bytes'; |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
return $bytes; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* This function transforms the php.ini notation for numbers (like '2M') |
177
|
|
|
* to an integer (2*1024*1024 in this case) |
178
|
|
|
* @param string $sSize |
179
|
|
|
* @return int|string |
180
|
|
|
*/ |
181
|
|
|
function convertPHPSizeToBytes($sSize) |
182
|
|
|
{ |
183
|
|
|
if (is_numeric($sSize)) { |
184
|
|
|
return $sSize; |
185
|
|
|
} |
186
|
|
|
$sSuffix = substr($sSize, -1); |
187
|
|
|
$iValue = substr($sSize, 0, -1); |
188
|
|
|
|
189
|
|
|
switch (strtoupper($sSuffix)) { |
190
|
|
|
case 'P': |
191
|
|
|
$iValue *= 1024; |
192
|
|
|
//PB multiplier |
193
|
|
|
case 'T': |
194
|
|
|
$iValue *= 1024; |
195
|
|
|
//TB multiplier |
196
|
|
|
case 'G': |
197
|
|
|
$iValue *= 1024; |
198
|
|
|
//GB multiplier |
199
|
|
|
case 'M': |
200
|
|
|
$iValue *= 1024; |
201
|
|
|
//MB multiplier |
202
|
|
|
case 'K': |
203
|
|
|
$iValue *= 1024; |
204
|
|
|
//KB multiplier |
205
|
|
|
break; |
206
|
|
|
} |
207
|
|
|
return $iValue; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Return the Max upload size in bytes. |
212
|
|
|
* @param bool $humanFormat if set to true return size in human format (MB, kB, etc..) otherwise return in bytes. |
213
|
|
|
* @return int |
214
|
|
|
*/ |
215
|
|
|
function getMaximumFileUploadSize(bool $humanFormat = false) |
216
|
|
|
{ |
217
|
|
|
$size = min(convertPHPSizeToBytes(ini_get('post_max_size')), convertPHPSizeToBytes(ini_get('upload_max_filesize'))); |
218
|
|
|
|
219
|
|
|
if (!$humanFormat) { |
220
|
|
|
return $size; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
return bytes2HumanSize($size); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Encrypt string in asymmetrical way. |
228
|
|
|
* @param string $string to encrypt. |
229
|
|
|
* @param string $chiave the key to encrypt. if empty generate a random key on the fly. |
230
|
|
|
* @return string |
231
|
|
|
*/ |
232
|
|
|
function encryptString(string $string, string $chiave = '') |
233
|
|
|
{ |
234
|
|
|
if ($chiave == '') { |
235
|
|
|
$chiave = str_random(64); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
$key = pack('H*', $chiave); |
239
|
|
|
|
240
|
|
|
$plaintext = $string; |
241
|
|
|
|
242
|
|
|
# create a random IV to use with CBC encoding |
243
|
|
|
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); |
244
|
|
|
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); |
245
|
|
|
|
246
|
|
|
# creates a cipher text compatible with AES (Rijndael block size = 128) |
247
|
|
|
# to keep the text confidential |
248
|
|
|
# only suitable for encoded input that never ends with value 00h |
249
|
|
|
# (because of default zero padding) |
250
|
|
|
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv); |
251
|
|
|
|
252
|
|
|
# prepend the IV for it to be available for decryption |
253
|
|
|
$ciphertext = $iv . $ciphertext; |
254
|
|
|
|
255
|
|
|
# encode the resulting cipher text so it can be represented by a string |
256
|
|
|
$ciphertext_base64 = base64_encode($ciphertext); |
257
|
|
|
|
258
|
|
|
return $ciphertext_base64; |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Get a Website favicon url. |
263
|
|
|
* |
264
|
|
|
* @param string $url website url |
265
|
|
|
* |
266
|
|
|
* @return string containing complete image tag |
267
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
268
|
|
|
*/ |
269
|
|
|
function getFaviconUrl($url) : string |
270
|
|
|
{ |
271
|
|
|
$apiUrl = 'https://www.google.com/s2/favicons?domain='; |
272
|
|
|
if (strpos($url, 'http') !== false) { |
273
|
|
|
$url = str_replace('http://', '', $url); |
274
|
|
|
} |
275
|
|
|
return $apiUrl . $url; |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
/** |
279
|
|
|
* Get a Website favicon image tag. |
280
|
|
|
* |
281
|
|
|
* @param string $url website url |
282
|
|
|
* @param array $attributes Optional, additional key/value attributes to include in the IMG tag |
283
|
|
|
* |
284
|
|
|
* @return string containing complete image tag |
285
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
286
|
|
|
*/ |
287
|
|
|
function getFaviconImgTag($url, array $attributes = []) : string |
288
|
|
|
{ |
289
|
|
|
$urlFav = getFaviconUrl($url); |
290
|
|
|
$attr = arrayToString($attributes); |
291
|
|
|
return '<img src="' . $urlFav . '" ' . trim($attr) . ' />'; |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
/** |
295
|
|
|
* Check to see if the current page is being server over SSL or not. |
296
|
|
|
* Support HTTP_X_FORWARDED_PROTO to check ssl over proxy/load balancer. |
297
|
|
|
* |
298
|
|
|
* @return bool |
299
|
|
|
*/ |
300
|
|
|
function isHttps() |
301
|
|
|
{ |
302
|
|
|
$key = 'HTTPS'; |
303
|
|
|
if (isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_X_FORWARDED_PROTO')) { |
304
|
|
|
$key = 'HTTP_X_FORWARDED_PROTO'; |
305
|
|
|
} |
306
|
|
|
return isNotNullOrEmptyArrayKey($_SERVER, $key) && strtolower($_SERVER[$key]) !== 'off'; |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
/** |
310
|
|
|
* Get a QR code. |
311
|
|
|
* |
312
|
|
|
* @param string $string String to generate QR code for. |
313
|
|
|
* @param int $width QR code width |
314
|
|
|
* @param int $height QR code height |
315
|
|
|
* @param array $attributes Optional, additional key/value attributes to include in the IMG tag |
316
|
|
|
* |
317
|
|
|
* @return string containing complete image tag |
318
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
319
|
|
|
*/ |
320
|
|
|
function getQRcode($string, int $width = 150, int $height = 150, array $attributes = []) : string |
321
|
|
|
{ |
322
|
|
|
$attr = arrayToString($attributes); |
323
|
|
|
$apiUrl = getQRcodeUrl($string, $width, $height); |
324
|
|
|
return '<img src="' . $apiUrl . '" ' . trim($attr) . ' />'; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
/** |
328
|
|
|
* Get a QR code Url. |
329
|
|
|
* |
330
|
|
|
* @param string $string String to generate QR code for. |
331
|
|
|
* @param int $width QR code width |
332
|
|
|
* @param int $height QR code height |
333
|
|
|
* |
334
|
|
|
* @return string containing complete image url |
335
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
336
|
|
|
*/ |
337
|
|
|
function getQRcodeUrl($string, int $width = 150, int $height = 150) : string |
338
|
|
|
{ |
339
|
|
|
$protocol = 'http://'; |
340
|
|
|
if (isHttps()) { |
341
|
|
|
$protocol = 'https://'; |
342
|
|
|
} |
343
|
|
|
return $protocol . 'chart.apis.google.com/chart?chs=' . $width . 'x' . $height . '&cht=qr&chl=' . urlencode($string); |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
if (!function_exists('gravatarUrl')) { |
347
|
|
|
/** |
348
|
|
|
* Get a Gravatar URL from email. |
349
|
|
|
* |
350
|
|
|
* @param string $email The email address |
351
|
|
|
* @param int $size in pixels, defaults to 80px [ 1 - 2048 ] |
352
|
|
|
* @param string $default imageset to use [ 404 | mm | identicon | monsterid | wavatar ] |
353
|
|
|
* @param string $rating (inclusive) [ g | pg | r | x ] |
354
|
|
|
* @return string |
355
|
|
|
* @source http://gravatar.com/site/implement/images/php/ |
356
|
|
|
*/ |
357
|
|
|
function gravatarUrl($email, $size = 80, $default = 'mm', $rating = 'g') |
358
|
|
|
{ |
359
|
|
|
$url = 'https://www.gravatar.com'; |
360
|
|
|
$url .= '/avatar/' . md5(strtolower(trim($email))) . '?default=' . $default . '&size=' . $size . '&rating=' . $rating; |
361
|
|
|
return $url; |
362
|
|
|
} |
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
if (!function_exists('gravatar')) { |
366
|
|
|
/** |
367
|
|
|
* Get a Gravatar img tag from email. |
368
|
|
|
* |
369
|
|
|
* @param string $email The email address |
370
|
|
|
* @param int $size in pixels, defaults to 80px [ 1 - 2048 ] |
371
|
|
|
* @param string $default imageset to use [ 404 | mm | identicon | monsterid | wavatar ] |
372
|
|
|
* @param string $rating (inclusive) [ g | pg | r | x ] |
373
|
|
|
* @param array $attributes Optional, additional key/value attributes to include in the IMG tag |
374
|
|
|
* @return string |
375
|
|
|
* @source http://gravatar.com/site/implement/images/php/ |
376
|
|
|
*/ |
377
|
|
|
function gravatar($email, $size = 80, $default = 'mm', $rating = 'g', $attributes = []) |
378
|
|
|
{ |
379
|
|
|
$attr = arrayToString($attributes); |
380
|
|
|
$url = gravatarUrl($email, $size, $default, $rating); |
381
|
|
|
return '<img src="' . $url . '" width="' . $size . 'px" height="' . $size . 'px" ' . trim($attr) . ' />'; |
382
|
|
|
} |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
if (!function_exists('isAjax')) { |
386
|
|
|
|
387
|
|
|
/** |
388
|
|
|
* Determine if current page request type is ajax. |
389
|
|
|
* |
390
|
|
|
* @return bool |
391
|
|
|
*/ |
392
|
|
|
function isAjax() |
393
|
|
|
{ |
394
|
|
|
return isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_X_REQUESTED_WITH') |
395
|
|
|
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'; |
396
|
|
|
} |
397
|
|
|
} |
398
|
|
|
|
399
|
|
|
if (!function_exists('isNumberOdd')) { |
400
|
|
|
|
401
|
|
|
/** |
402
|
|
|
* Check if number is odd. |
403
|
|
|
* |
404
|
|
|
* @param int $num integer to check |
405
|
|
|
* |
406
|
|
|
* @return bool |
407
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
408
|
|
|
*/ |
409
|
|
|
function isNumberOdd($num) |
410
|
|
|
{ |
411
|
|
|
return $num % 2 !== 0; |
412
|
|
|
} |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
if (!function_exists('isNumberEven')) { |
416
|
|
|
|
417
|
|
|
/** |
418
|
|
|
* Check if number is even. |
419
|
|
|
* |
420
|
|
|
* @param int $num integer to check |
421
|
|
|
* |
422
|
|
|
* @return bool |
423
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
424
|
|
|
*/ |
425
|
|
|
function isNumberEven($num) |
426
|
|
|
{ |
427
|
|
|
return $num % 2 == 0; |
428
|
|
|
} |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
if (!function_exists('getCurrentUrlPageName')) { |
432
|
|
|
|
433
|
|
|
/** |
434
|
|
|
* Returns The Current URL PHP File Name. |
435
|
|
|
* Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return index.php |
436
|
|
|
* |
437
|
|
|
* @return string |
438
|
|
|
*/ |
439
|
|
|
function getCurrentUrlPageName() : string |
440
|
|
|
{ |
441
|
|
|
return isNotNullOrEmptyArrayKey($_SERVER, 'PHP_SELF') ? basename($_SERVER['PHP_SELF']) : ''; |
442
|
|
|
} |
443
|
|
|
} |
444
|
|
|
|
445
|
|
|
if (!function_exists('getCurrentUrlQuerystring')) { |
446
|
|
|
|
447
|
|
|
/** |
448
|
|
|
* Returns The Current URL querystring. |
449
|
|
|
* Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return one=1&two=2 |
450
|
|
|
* |
451
|
|
|
* @return string |
452
|
|
|
*/ |
453
|
|
|
function getCurrentUrlQuerystring() : string |
454
|
|
|
{ |
455
|
|
|
return isNotNullOrEmptyArrayKey($_SERVER, 'QUERY_STRING') ? $_SERVER['QUERY_STRING'] : ''; |
456
|
|
|
} |
457
|
|
|
} |
458
|
|
|
|
459
|
|
|
if (!function_exists('getCurrentUrlDirName')) { |
460
|
|
|
|
461
|
|
|
/** |
462
|
|
|
* Returns The Current URL Path Name. |
463
|
|
|
* Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return /one/two |
464
|
|
|
* |
465
|
|
|
* @return string |
466
|
|
|
*/ |
467
|
|
|
function getCurrentUrlDirName() : string |
468
|
|
|
{ |
469
|
|
|
if (isNotNullOrEmptyArrayKey($_SERVER, 'REQUEST_URI')) { |
470
|
|
|
return dirname($_SERVER['REQUEST_URI']); |
471
|
|
|
} |
472
|
|
|
return isNotNullOrEmptyArrayKey($_SERVER, 'PHP_SELF') ? dirname($_SERVER['PHP_SELF']) : ''; |
473
|
|
|
} |
474
|
|
|
} |
475
|
|
|
|
476
|
|
|
if (!function_exists('getCurrentUrlDirAbsName')) { |
477
|
|
|
|
478
|
|
|
/** |
479
|
|
|
* Returns The Current URL Absolute Path Name. |
480
|
|
|
* Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return /home/user/www/one/two |
481
|
|
|
* |
482
|
|
|
* @return string |
483
|
|
|
*/ |
484
|
|
|
function getCurrentUrlDirAbsName() : string |
485
|
|
|
{ |
486
|
|
|
return isNotNullOrEmptyArrayKey($_SERVER, 'SCRIPT_FILENAME') ? dirname($_SERVER['SCRIPT_FILENAME']) : ''; |
487
|
|
|
} |
488
|
|
|
} |
489
|
|
|
|
490
|
|
|
if (!function_exists('getCurrentURL')) { |
491
|
|
|
|
492
|
|
|
/** |
493
|
|
|
* Return the current URL. |
494
|
|
|
* Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 |
495
|
|
|
* Or |
496
|
|
|
* Ex.: https://username:[email protected]:443/one/two/index.php?one=1&two=2 |
497
|
|
|
* @return string |
498
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
499
|
|
|
*/ |
500
|
|
|
function getCurrentURL() |
501
|
|
|
{ |
502
|
|
|
$url = 'http://'; |
503
|
|
|
if (isHttps()) { |
504
|
|
|
$url = 'https://'; |
505
|
|
|
} |
506
|
|
|
if (array_key_exists_safe($_SERVER, 'PHP_AUTH_USER')) { |
507
|
|
|
$url .= $_SERVER['PHP_AUTH_USER']; |
508
|
|
|
if (array_key_exists_safe($_SERVER, 'PHP_AUTH_PW')) { |
509
|
|
|
$url .= ':' . $_SERVER['PHP_AUTH_PW']; |
510
|
|
|
} |
511
|
|
|
$url .= '@'; |
512
|
|
|
} |
513
|
|
|
if (array_key_exists_safe($_SERVER, 'HTTP_HOST')) { |
514
|
|
|
$url .= $_SERVER['HTTP_HOST']; |
515
|
|
|
} |
516
|
|
|
if (array_key_exists_safe($_SERVER, 'SERVER_PORT') && $_SERVER['SERVER_PORT'] != 80) { |
517
|
|
|
$url .= ':' . $_SERVER['SERVER_PORT']; |
518
|
|
|
} |
519
|
|
|
if (!array_key_exists_safe($_SERVER, 'REQUEST_URI')) { |
520
|
|
|
$url .= substr($_SERVER['PHP_SELF'], 1); |
521
|
|
|
if (array_key_exists_safe($_SERVER, 'QUERY_STRING')): |
522
|
|
|
$url .= '?' . $_SERVER['QUERY_STRING']; |
523
|
|
|
endif; |
524
|
|
|
} else { |
525
|
|
|
$url .= $_SERVER['REQUEST_URI']; |
526
|
|
|
} |
527
|
|
|
return $url; |
528
|
|
|
} |
529
|
|
|
} |
530
|
|
|
|
531
|
|
|
if (!function_exists('isMobile')) { |
532
|
|
|
|
533
|
|
|
/** |
534
|
|
|
* Detect if user is on mobile device. |
535
|
|
|
* |
536
|
|
|
* @return bool |
537
|
|
|
*/ |
538
|
|
|
function isMobile() |
539
|
|
|
{ |
540
|
|
|
$useragent = $_SERVER['HTTP_USER_AGENT']; |
541
|
|
|
return preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i', |
542
|
|
|
$useragent) |
543
|
|
|
|| preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', |
544
|
|
|
substr($useragent, 0, 4)); |
545
|
|
|
} |
546
|
|
|
} |
547
|
|
|
|
548
|
|
|
/** |
549
|
|
|
* Get user browser. |
550
|
|
|
* |
551
|
|
|
* @return string |
552
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
553
|
|
|
*/ |
554
|
|
|
function getBrowser() |
555
|
|
|
{ |
556
|
|
|
$u_agent = $_SERVER['HTTP_USER_AGENT']; |
557
|
|
|
$browserName = $ub = $platform = 'Unknown'; |
558
|
|
|
if (preg_match('/linux/i', $u_agent)) { |
559
|
|
|
$platform = 'Linux'; |
560
|
|
|
} elseif (preg_match('/macintosh|mac os x/i', $u_agent)) { |
561
|
|
|
$platform = 'Mac OS'; |
562
|
|
|
} elseif (preg_match('/windows|win32/i', $u_agent)) { |
563
|
|
|
$platform = 'Windows'; |
564
|
|
|
} |
565
|
|
|
if (preg_match('/MSIE/i', $u_agent) && !preg_match('/Opera/i', $u_agent)) { |
566
|
|
|
$browserName = 'Internet Explorer'; |
567
|
|
|
$ub = 'MSIE'; |
568
|
|
|
} elseif (preg_match('/Firefox/i', $u_agent)) { |
569
|
|
|
$browserName = 'Mozilla Firefox'; |
570
|
|
|
$ub = 'Firefox'; |
571
|
|
|
} elseif (preg_match('/Chrome/i', $u_agent)) { |
572
|
|
|
$browserName = 'Google Chrome'; |
573
|
|
|
$ub = 'Chrome'; |
574
|
|
|
} elseif (preg_match('/Safari/i', $u_agent)) { |
575
|
|
|
$browserName = 'Apple Safari'; |
576
|
|
|
$ub = 'Safari'; |
577
|
|
|
} elseif (preg_match('/Opera/i', $u_agent)) { |
578
|
|
|
$browserName = 'Opera'; |
579
|
|
|
$ub = 'Opera'; |
580
|
|
|
} elseif (preg_match('/Netscape/i', $u_agent)) { |
581
|
|
|
$browserName = 'Netscape'; |
582
|
|
|
$ub = 'Netscape'; |
583
|
|
|
} |
584
|
|
|
$known = ['Version', $ub, 'other']; |
585
|
|
|
$pattern = '#(?<browser>' . implode('|', $known) . ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#'; |
586
|
|
|
preg_match_all($pattern, $u_agent, $matches); |
587
|
|
|
$i = count($matches['browser']); |
588
|
|
|
if ($i != 1) { |
589
|
|
|
if (strripos($u_agent, 'Version') < strripos($u_agent, $ub)) { |
590
|
|
|
$version = $matches['version'][0]; |
591
|
|
|
} else { |
592
|
|
|
$version = $matches['version'][1]; |
593
|
|
|
} |
594
|
|
|
} else { |
595
|
|
|
$version = $matches['version'][0]; |
596
|
|
|
} |
597
|
|
|
if ($version == null || $version == '') { |
598
|
|
|
$version = '?'; |
599
|
|
|
} |
600
|
|
|
return implode(', ', [$browserName, 'Version: ' . $version, $platform]); |
601
|
|
|
} |
602
|
|
|
|
603
|
|
|
/** |
604
|
|
|
* Shorten URL via tinyurl.com service. |
605
|
|
|
* It support http or https. |
606
|
|
|
* @param string $url URL to shorten |
607
|
|
|
* |
608
|
|
|
* @return string shortend url or empty string if it fails. |
609
|
|
|
*/ |
610
|
|
|
function getTinyUrl(string $url) : string |
611
|
|
|
{ |
612
|
|
|
if (!starts_with($url, 'http')) { |
613
|
|
|
$url = (isHttps() ? 'https://' : 'http://') . $url; |
614
|
|
|
} |
615
|
|
|
$gettiny = curl('http://tinyurl.com/api-create.php?url=' . $url); |
616
|
|
|
if (isNullOrEmpty($gettiny) && isNullOrEmptyArray($gettiny)) { |
617
|
|
|
return ''; |
618
|
|
|
} |
619
|
|
|
if (isHttps()) { |
620
|
|
|
$gettiny = str_replace('http://', 'https://', $gettiny); |
621
|
|
|
} |
622
|
|
|
return $gettiny; |
623
|
|
|
} |
624
|
|
|
|
625
|
|
|
/** |
626
|
|
|
* Get information on a short URL. Find out where it goes. |
627
|
|
|
* |
628
|
|
|
* @param string $shortURL shortened URL |
629
|
|
|
* |
630
|
|
|
* @return string full url or empty string |
631
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
632
|
|
|
*/ |
633
|
|
|
function expandShortUrl(string $shortURL) : string |
634
|
|
|
{ |
635
|
|
|
if (isNullOrEmpty($shortURL)) { |
636
|
|
|
return ''; |
637
|
|
|
} |
638
|
|
|
$headers = get_headers($shortURL, 1); |
639
|
|
|
if (array_key_exists_safe($headers, 'Location')) { |
640
|
|
|
return $headers['Location']; |
641
|
|
|
} |
642
|
|
|
$data = curl($shortURL); |
643
|
|
|
preg_match_all('/<[\s]*meta[\s]*http-equiv="?' . '([^>"]*)"?[\s]*' . 'content="?([^>"]*)"?[\s]*[\/]?[\s]*>/si', |
644
|
|
|
$data, $match); |
645
|
|
|
if (isNullOrEmptyArray($match) || count($match) != 3 |
646
|
|
|
|| isNullOrEmptyArray($match[0]) || isNullOrEmptyArray($match[1]) || isNullOrEmptyArray($match[2]) |
647
|
|
|
|| count($match[0]) != count($match[1]) || count($match[1]) != count($match[2]) |
648
|
|
|
) { |
649
|
|
|
return ''; |
650
|
|
|
} |
651
|
|
|
$originals = $match[0]; |
652
|
|
|
$names = $match[1]; |
653
|
|
|
$values = $match[2]; |
654
|
|
|
$metaTags = []; |
655
|
|
|
for ($i = 0, $limit = count($names); $i < $limit; $i++) { |
656
|
|
|
$metaTags[$names[$i]] = ['html' => htmlentities($originals[$i]), 'value' => $values[$i]]; |
657
|
|
|
} |
658
|
|
|
if (!isset($metaTags['refresh']['value']) || empty($metaTags['refresh']['value'])) { |
659
|
|
|
return ''; |
660
|
|
|
} |
661
|
|
|
$returnData = explode('=', $metaTags['refresh']['value']); |
662
|
|
|
if (!isset($returnData[1]) || empty($returnData[1])) { |
663
|
|
|
return ''; |
664
|
|
|
} |
665
|
|
|
return $returnData[1]; |
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
if (!function_exists('curl')) { |
669
|
|
|
|
670
|
|
|
/** |
671
|
|
|
* Make Curl call. |
672
|
|
|
* |
673
|
|
|
* @param string $url URL to curl |
674
|
|
|
* @param string $method GET or POST, Default GET |
675
|
|
|
* @param mixed $data Data to post, Default false |
676
|
|
|
* @param string[] $headers Additional headers, example: array ("Accept: application/json") |
677
|
|
|
* @param bool $returnInfo Whether or not to retrieve curl_getinfo() |
678
|
|
|
* @param string $user |
679
|
|
|
* @param string $password |
680
|
|
|
* @param bool $sslNotVerifyHostAndPeer is set to true do not check SSL certificate. |
681
|
|
|
* @param bool $followLocation |
682
|
|
|
* @param int $timeout |
683
|
|
|
* @param string $logPath if not empty write log to this file |
684
|
|
|
* @param string $referer |
685
|
|
|
* @param string $userAgent default 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0' |
686
|
|
|
* and ignore $returnInfo (i.e. call curl_getinfo even if $returnInfo is set to false). |
687
|
|
|
* |
688
|
|
|
* @return string|array if $returnInfo is set to True, array is returned with two keys, contents (will contain response) and info (information regarding a specific transfer), otherwise response content is returned |
689
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
690
|
|
|
*/ |
691
|
|
|
function curl( |
692
|
|
|
$url, |
693
|
|
|
$method = 'GET', |
694
|
|
|
$data = false, |
695
|
|
|
array $headers = [], |
696
|
|
|
bool $returnInfo = false, |
697
|
|
|
string $user = '', |
698
|
|
|
string $password = '', |
699
|
|
|
bool $sslNotVerifyHostAndPeer = false, |
700
|
|
|
bool $followLocation = false, |
701
|
|
|
int $timeout = 10, |
702
|
|
|
string $logPath = '', |
703
|
|
|
string $referer = '', |
704
|
|
|
string $userAgent = 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0' |
705
|
|
|
) { |
706
|
|
|
$log = false; |
707
|
|
|
if (isNotNullOrEmpty($logPath)) { |
708
|
|
|
$log = true; |
709
|
|
|
$msg = "REQUEST_URI: " . (isNotNullOrEmptyArrayKey($_SERVER, |
710
|
|
|
'REQUEST_URI') ? $_SERVER['REQUEST_URI'] : '') . "\r\n" |
711
|
|
|
. "SCRIPT_NAME: " . (isNotNullOrEmptyArrayKey($_SERVER, |
712
|
|
|
'SCRIPT_NAME') ? $_SERVER['SCRIPT_NAME'] : '') . "\r\n" |
713
|
|
|
. "REMOTE ADDR: " . (isNotNullOrEmptyArrayKey($_SERVER, |
714
|
|
|
'REMOTE_ADDR') ? $_SERVER['REMOTE_ADDR'] : '') . "\r\n" |
715
|
|
|
. "HTTP_HOST: " . (isNotNullOrEmptyArrayKey($_SERVER, |
716
|
|
|
'HTTP_HOST') ? $_SERVER['HTTP_HOST'] : '') . "\r\n" |
717
|
|
|
. "SERVER_NAME: " . (isNotNullOrEmptyArrayKey($_SERVER, |
718
|
|
|
'SERVER_NAME') ? $_SERVER['SERVER_NAME'] : '') . "\r\n" |
719
|
|
|
. "HTTP_X_FORWARDED_FOR: " . (isNotNullOrEmptyArrayKey($_SERVER, |
720
|
|
|
'HTTP_X_FORWARDED_FOR') ? $_SERVER['HTTP_X_FORWARDED_FOR'] : '') . "\r\n" |
721
|
|
|
. "SERVER_ADDR: " . (isNotNullOrEmptyArrayKey($_SERVER, |
722
|
|
|
'SERVER_ADDR') ? $_SERVER['SERVER_ADDR'] : '') . "\r\n" |
723
|
|
|
. "REMOTE_PORT: " . (isNotNullOrEmptyArrayKey($_SERVER, |
724
|
|
|
'REMOTE_PORT') ? $_SERVER['REMOTE_PORT'] : '') . "\r\n" |
725
|
|
|
. "HTTPS: " . (isNotNullOrEmptyArrayKey($_SERVER, 'HTTPS') ? $_SERVER['HTTPS'] : '') . "\r\n" |
726
|
|
|
. "HTTP_X_FORWARDED_PROTO: " . (isNotNullOrEmptyArrayKey($_SERVER, |
727
|
|
|
'HTTP_X_FORWARDED_PROTO') ? $_SERVER['HTTP_X_FORWARDED_PROTO'] : '') . "\r\n" |
728
|
|
|
. "data: " . get_var_dump_output($data) . "\r\n" |
729
|
|
|
. "headers: " . get_var_dump_output($headers) . "\r\n" |
730
|
|
|
. "returnInfo: " . $returnInfo . "\r\n" |
731
|
|
|
. "url: " . $url . "\r\n" |
732
|
|
|
. "method: " . $method . "\r\n" |
733
|
|
|
. "user: " . $user . "\r\n" |
734
|
|
|
. "password: " . (strlen($password) > 2 ? substr($password, 0, 2) . str_repeat('x', |
735
|
|
|
10) . substr($password, -1) : 'xx') . "\r\n" |
736
|
|
|
. "sslNotVerifyHostAndPeer: " . $sslNotVerifyHostAndPeer . "\r\n" |
737
|
|
|
. "followLocation: " . $followLocation . "\r\n" |
738
|
|
|
. "timeout: " . $timeout . "\r\n" |
739
|
|
|
. "logPath: " . $logPath . "\r\n" |
740
|
|
|
. "referer: " . $referer . "\r\n" |
741
|
|
|
. "userAgent: " . $userAgent . "\r\n" |
742
|
|
|
. "\r\n"; |
743
|
|
|
logToFile($logPath, $msg); |
744
|
|
|
} |
745
|
|
|
if (!function_exists('curl_init') || isNullOrEmpty($url)) { |
746
|
|
|
if ($log) { |
747
|
|
|
logToFile($logPath, |
748
|
|
|
isNullOrEmpty($url) ? 'url is empty.curl abort.' : 'curl_init not exists.Probabily CURL is not installed.'); |
749
|
|
|
} |
750
|
|
|
return ''; |
751
|
|
|
} |
752
|
|
|
$ch = curl_init(); |
753
|
|
|
$info = null; |
754
|
|
|
if (strtoupper($method) == 'POST') { |
755
|
|
|
curl_setopt($ch, CURLOPT_POST, true); |
756
|
|
|
if ($data !== false) { |
757
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); |
758
|
|
|
} |
759
|
|
|
} elseif ($data !== false) { |
760
|
|
|
if (is_array($data)) { |
761
|
|
|
$dataTokens = []; |
762
|
|
|
foreach ($data as $key => $value) { |
763
|
|
|
$dataTokens[] = urlencode($key) . '=' . urlencode($value); |
764
|
|
|
} |
765
|
|
|
$data = implode('&', $dataTokens); |
766
|
|
|
} |
767
|
|
|
$url .= (strpos($url, '?') === false ? '&' : '?') . $data; |
768
|
|
|
} |
769
|
|
|
curl_setopt($ch, CURLOPT_URL, $url); |
770
|
|
|
curl_setopt($ch, CURLOPT_HEADER, false); |
771
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
772
|
|
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $followLocation ? true : false); |
773
|
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout <= 1 ? 10 : $timeout); |
774
|
|
|
if ($sslNotVerifyHostAndPeer && starts_with($url, 'https://')) { |
775
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); |
776
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); |
777
|
|
|
} |
778
|
|
|
if (isNotNullOrEmptyArray($headers)) { |
779
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); |
780
|
|
|
} |
781
|
|
|
if (isNotNullOrEmpty($user) && isNotNullOrEmpty($password)) { |
782
|
|
|
curl_setopt($ch, CURLOPT_USERPWD, $user . ':' . $password); |
783
|
|
|
} |
784
|
|
|
if (isNotNullOrEmpty($referer)) { |
785
|
|
|
curl_setopt($ch, CURLOPT_REFERER, $referer); |
786
|
|
|
} |
787
|
|
|
if (isNotNullOrEmpty($userAgent)) { |
788
|
|
|
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent); |
789
|
|
|
} |
790
|
|
|
|
791
|
|
|
if ($log) { |
792
|
|
|
logToFile($logPath, date('Y-m-d H:i:s') . "Start curl\r\n"); |
793
|
|
|
} |
794
|
|
|
$contents = curl_exec($ch); |
795
|
|
|
if ($log) { |
796
|
|
|
logToFile($logPath, date('Y-m-d H:i:s') . "FINISH curl\r\n"); |
797
|
|
|
} |
798
|
|
|
|
799
|
|
|
if ($returnInfo || $log || $contents === false || curl_errno($ch) > 0) { |
800
|
|
|
$info = curl_getinfo($ch); |
801
|
|
|
if ($log) { |
802
|
|
|
logToFile($logPath, $info, true); |
803
|
|
|
} |
804
|
|
|
} |
805
|
|
|
|
806
|
|
|
if ($contents === false || curl_errno($ch) > 0 |
807
|
|
|
|| !array_key_exists_safe($info === null ? [] : $info, 'http_code') || $info['http_code'] != 200 |
808
|
|
|
) { |
809
|
|
|
if ($log) { |
810
|
|
|
logToFile($logPath, "Error during exec CURL \r\n curl_error: " . curl_error($ch) |
811
|
|
|
. "\r\n curl_errno: " . curl_errno($ch) . "\r\n"); |
812
|
|
|
} |
813
|
|
|
} elseif ($log) { |
814
|
|
|
logToFile($logPath, "CURL IS OK\r\n RESPONSE: \r\n" . $contents); |
815
|
|
|
} |
816
|
|
|
|
817
|
|
|
curl_close($ch); |
818
|
|
|
return ($returnInfo ? ['contents' => $contents, 'info' => $info] : $contents); |
819
|
|
|
} |
820
|
|
|
} |
821
|
|
|
|
822
|
|
|
|
823
|
|
|
if (!function_exists('curl_internal_server_behind_load_balancer')) { |
824
|
|
|
|
825
|
|
|
/** |
826
|
|
|
* Make Curl call to one of the server behinds load balancer. |
827
|
|
|
* |
828
|
|
|
* @param string $url URL to curl |
829
|
|
|
* @param string $server_name The host name of the domain from the call will start. |
830
|
|
|
* if empty try to resolve from SERVER_NAME |
831
|
|
|
* @param string $localServerIpAddress the IP of one server to call that behinds load balancer. |
832
|
|
|
* if empty try to resolve from SERVER_ADDR |
833
|
|
|
* @param string $method GET or POST, Default GET |
834
|
|
|
* @param mixed $data Data to post, Default false |
835
|
|
|
* @param array $headers Additional headers, example: array ("Accept: application/json") |
836
|
|
|
* @param bool $returnInfo Whether or not to retrieve curl_getinfo() |
837
|
|
|
* @param string $user |
838
|
|
|
* @param string $password |
839
|
|
|
* @param bool $sslNotVerifyHostAndPeer is set to true do not check SSL certificate. |
840
|
|
|
* @param bool $followLocation |
841
|
|
|
* @param int $timeout |
842
|
|
|
* @param string $logPath if not empty write log to this file |
843
|
|
|
* @param string $referer |
844
|
|
|
* @param string $userAgent default 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0' |
845
|
|
|
* and ignore $returnInfo (i.e. call curl_getinfo even if $returnInfo is set to false). |
846
|
|
|
* |
847
|
|
|
* @return string|array if $returnInfo is set to True, array is returned with two keys, contents (will contain response) and info (information regarding a specific transfer), otherwise response content is returned |
848
|
|
|
*/ |
849
|
|
|
function curl_internal_server_behind_load_balancer( |
850
|
|
|
$url, |
851
|
|
|
$server_name = '', |
852
|
|
|
$localServerIpAddress = '', |
853
|
|
|
$method = 'GET', |
854
|
|
|
$data = false, |
855
|
|
|
array $headers = [], |
856
|
|
|
bool $returnInfo = false, |
857
|
|
|
string $user = '', |
858
|
|
|
string $password = '', |
859
|
|
|
bool $sslNotVerifyHostAndPeer = false, |
860
|
|
|
bool $followLocation = false, |
861
|
|
|
int $timeout = 10, |
862
|
|
|
string $logPath = '', |
863
|
|
|
string $referer = '', |
864
|
|
|
string $userAgent = 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0' |
865
|
|
|
) { |
866
|
|
|
if (isNullOrEmpty($server_name) && isNotNullOrEmptyArrayKey($_SERVER, 'SERVER_NAME')) { |
867
|
|
|
$server_name = $_SERVER['SERVER_NAME']; |
868
|
|
|
} |
869
|
|
|
|
870
|
|
View Code Duplication |
if (isNullOrEmpty($server_name) && isNotNullOrEmpty($logPath)) { |
871
|
|
|
$msg = 'No server name given for calling curl ' . $url . ' behind proxy or LB'; |
872
|
|
|
logToFile($logPath, $msg); |
873
|
|
|
return false; |
874
|
|
|
} |
875
|
|
|
|
876
|
|
|
if (isNullOrEmpty($localServerIpAddress) && isNotNullOrEmptyArrayKey($_SERVER, 'SERVER_ADDR')) { |
877
|
|
|
$localServerIpAddress = $_SERVER['SERVER_ADDR']; |
878
|
|
|
} |
879
|
|
|
|
880
|
|
View Code Duplication |
if (isNullOrEmpty($localServerIpAddress) && isNotNullOrEmpty($logPath)) { |
881
|
|
|
$msg = 'No localIPAddress given for calling curl ' . $url . ' behind proxy or LB'; |
882
|
|
|
logToFile($logPath, $msg); |
883
|
|
|
return false; |
884
|
|
|
} |
885
|
|
|
|
886
|
|
|
$url = str_replace($server_name, $localServerIpAddress, $url); |
887
|
|
|
|
888
|
|
|
//Using the host header to bypass a load balancer |
889
|
|
|
if (!is_array($headers)) { |
890
|
|
|
$headers = array(); |
891
|
|
|
} |
892
|
|
|
$headers[] = 'Host: ' . $server_name; |
893
|
|
|
|
894
|
|
|
return curl($url, $method, $data, $headers, $returnInfo, $user, $password, $sslNotVerifyHostAndPeer, |
895
|
|
|
$followLocation, $timeout, $logPath, $referer, $userAgent); |
896
|
|
|
} |
897
|
|
|
} |
898
|
|
|
|
899
|
|
|
if (!function_exists('startLayoutCapture')) { |
900
|
|
|
|
901
|
|
|
/** |
902
|
|
|
* Turn On the output buffering. |
903
|
|
|
* @return bool |
904
|
|
|
*/ |
905
|
|
|
function startLayoutCapture() : bool |
906
|
|
|
{ |
907
|
|
|
return ob_start(); |
908
|
|
|
} |
909
|
|
|
} |
910
|
|
|
|
911
|
|
|
if (!function_exists('endLayoutCapture')) { |
912
|
|
|
|
913
|
|
|
/** |
914
|
|
|
* Get the buffer contents for the topmost buffer and clean it. |
915
|
|
|
* @return string |
916
|
|
|
*/ |
917
|
|
|
function endLayoutCapture() : string |
918
|
|
|
{ |
919
|
|
|
$data = ob_get_contents(); |
920
|
|
|
ob_end_clean(); |
921
|
|
|
return $data === false ? '' : $data; |
922
|
|
|
} |
923
|
|
|
} |
924
|
|
|
|
925
|
|
|
if (!function_exists('get_var_dump_output')) { |
926
|
|
|
|
927
|
|
|
/** |
928
|
|
|
* Capture var dump $var output and return it. |
929
|
|
|
* @param $var |
930
|
|
|
* @return string |
931
|
|
|
*/ |
932
|
|
|
function get_var_dump_output($var) |
933
|
|
|
{ |
934
|
|
|
startLayoutCapture(); |
935
|
|
|
$myfunc = "var_dump"; |
936
|
|
|
$myfunc($var); |
937
|
|
|
return endLayoutCapture(); |
938
|
|
|
} |
939
|
|
|
} |
940
|
|
|
|
941
|
|
|
if (!function_exists('debug')) { |
942
|
|
|
|
943
|
|
|
/** |
944
|
|
|
* Dump information about a variable. |
945
|
|
|
* |
946
|
|
|
* @param mixed $variable Variable to debug |
947
|
|
|
* |
948
|
|
|
* @return void |
949
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
950
|
|
|
*/ |
951
|
|
|
function debug($variable) |
952
|
|
|
{ |
953
|
|
|
$output = get_var_dump_output($variable); |
954
|
|
|
$maps = [ |
955
|
|
|
'string' => "/(string\((?P<length>\d+)\)) (?P<value>\"(?<!\\\).*\")/i", |
956
|
|
|
'array' => "/\[\"(?P<key>.+)\"(?:\:\"(?P<class>[a-z0-9_\\\]+)\")?(?:\:(?P<scope>public|protected|private))?\]=>/Ui", |
957
|
|
|
'countable' => "/(?P<type>array|int|string)\((?P<count>\d+)\)/", |
958
|
|
|
'resource' => "/resource\((?P<count>\d+)\) of type \((?P<class>[a-z0-9_\\\]+)\)/", |
959
|
|
|
'bool' => "/bool\((?P<value>true|false)\)/", |
960
|
|
|
'float' => "/float\((?P<value>[0-9\.]+)\)/", |
961
|
|
|
'object' => "/object\((?P<class>\S+)\)\#(?P<id>\d+) \((?P<count>\d+)\)/i" |
962
|
|
|
]; |
963
|
|
|
foreach ($maps as $function => $pattern) { |
964
|
|
|
$output = preg_replace_callback($pattern, function ($matches) use ($function) { |
965
|
|
|
switch ($function) { |
966
|
|
|
case 'string': |
967
|
|
|
$matches['value'] = htmlspecialchars($matches['value']); |
968
|
|
|
return '<span style="color: #0000FF;">string</span>(<span style="color: #1287DB;">' . $matches['length'] . ')</span> <span style="color: #6B6E6E;">' . $matches['value'] . '</span>'; |
969
|
|
|
case 'array': |
970
|
|
|
$key = '<span style="color: #008000;">"' . $matches['key'] . '"</span>'; |
971
|
|
|
$class = ''; |
972
|
|
|
$scope = ''; |
973
|
|
|
if (isset($matches['class']) && !empty($matches['class'])) { |
974
|
|
|
$class = ':<span style="color: #4D5D94;">"' . $matches['class'] . '"</span>'; |
975
|
|
|
} |
976
|
|
|
if (isset($matches['scope']) && !empty($matches['scope'])) { |
977
|
|
|
$scope = ':<span style="color: #666666;">' . $matches['scope'] . '</span>'; |
978
|
|
|
} |
979
|
|
|
return '[' . $key . $class . $scope . ']=>'; |
980
|
|
|
case 'countable': |
981
|
|
|
$type = '<span style="color: #0000FF;">' . $matches['type'] . '</span>'; |
982
|
|
|
$count = '(<span style="color: #1287DB;">' . $matches['count'] . '</span>)'; |
983
|
|
|
return $type . $count; |
984
|
|
|
case 'bool': |
985
|
|
|
return '<span style="color: #0000FF;">bool</span>(<span style="color: #0000FF;">' . $matches['value'] . '</span>)'; |
986
|
|
|
case 'float': |
987
|
|
|
return '<span style="color: #0000FF;">float</span>(<span style="color: #1287DB;">' . $matches['value'] . '</span>)'; |
988
|
|
|
case 'resource': |
989
|
|
|
return '<span style="color: #0000FF;">resource</span>(<span style="color: #1287DB;">' . $matches['count'] . '</span>) of type (<span style="color: #4D5D94;">' . $matches['class'] . '</span>)'; |
990
|
|
|
case 'object': |
991
|
|
|
return '<span style="color: #0000FF;">object</span>(<span style="color: #4D5D94;">' . $matches['class'] . '</span>)#' . $matches['id'] . ' (<span style="color: #1287DB;">' . $matches['count'] . '</span>)'; |
992
|
|
|
} |
993
|
|
|
}, $output); |
994
|
|
|
} |
995
|
|
|
$header = ''; |
996
|
|
|
list($debugfile) = debug_backtrace(); |
997
|
|
|
if (!empty($debugfile['file'])) { |
998
|
|
|
$header = '<h4 style="border-bottom:1px solid #bbb;font-weight:bold;margin:0 0 10px 0;padding:3px 0 10px 0">' . $debugfile['file'] . '</h4>'; |
999
|
|
|
} |
1000
|
|
|
echo '<pre style="background-color: #CDDCF4;border: 1px solid #bbb;border-radius: 4px;-moz-border-radius:4px;-webkit-border-radius\:4px;font-size:12px;line-height:1.4em;margin:30px;padding:7px">' . $header . $output . '</pre>'; |
1001
|
|
|
} |
1002
|
|
|
} |
1003
|
|
|
|
1004
|
|
|
if (!function_exists('getReferer')) { |
1005
|
|
|
|
1006
|
|
|
/** |
1007
|
|
|
* Return referer page if exists otherwise return empty string. |
1008
|
|
|
* |
1009
|
|
|
* @return string |
1010
|
|
|
*/ |
1011
|
|
|
function getReferer() : string |
1012
|
|
|
{ |
1013
|
|
|
return isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_REFERER') ? $_SERVER['HTTP_REFERER'] : ''; |
1014
|
|
|
} |
1015
|
|
|
} |
1016
|
|
|
|
1017
|
|
|
if (!function_exists('isZlibOutputCompressionActive')) { |
1018
|
|
|
|
1019
|
|
|
/** |
1020
|
|
|
* Check if zlib output compression was active |
1021
|
|
|
* @return bool |
1022
|
|
|
*/ |
1023
|
|
|
function isZlibOutputCompressionActive() : bool |
1024
|
|
|
{ |
1025
|
|
|
return ini_get('zlib.output_compression') == 'On' |
1026
|
|
|
|| ini_get('zlib.output_compression_level') > 0 |
1027
|
|
|
|| ini_get('output_handler') == 'ob_gzhandler'; |
1028
|
|
|
} |
1029
|
|
|
} |
1030
|
|
|
|
1031
|
|
|
if (!function_exists('isZlibLoaded')) { |
1032
|
|
|
|
1033
|
|
|
/** |
1034
|
|
|
* Check if zlib extension was loaded |
1035
|
|
|
* @return bool |
1036
|
|
|
*/ |
1037
|
|
|
function isZlibLoaded() : bool |
1038
|
|
|
{ |
1039
|
|
|
return extension_loaded('zlib'); |
1040
|
|
|
} |
1041
|
|
|
} |
1042
|
|
|
|
1043
|
|
|
if (!function_exists('isClientAcceptGzipEncoding')) { |
1044
|
|
|
|
1045
|
|
|
/** |
1046
|
|
|
* Check if client accept gzip encoding |
1047
|
|
|
* @return bool |
1048
|
|
|
*/ |
1049
|
|
|
function isClientAcceptGzipEncoding() : bool |
1050
|
|
|
{ |
1051
|
|
|
return isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_ACCEPT_ENCODING') |
1052
|
|
|
&& strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false; |
1053
|
|
|
} |
1054
|
|
|
} |
1055
|
|
|
|
1056
|
|
|
if (!function_exists('compressHtmlPage')) { |
1057
|
|
|
|
1058
|
|
|
/** |
1059
|
|
|
* Captures output via ob_get_contents(), tries to enable gzip, |
1060
|
|
|
* removes whitespace from captured output and echos back |
1061
|
|
|
* |
1062
|
|
|
* @return string whitespace stripped output |
1063
|
|
|
* @see https://github.com/ngfw/Recipe/ |
1064
|
|
|
*/ |
1065
|
|
|
function compressHtmlPage() : string |
1066
|
|
|
{ |
1067
|
|
|
register_shutdown_function(function () { |
1068
|
|
|
$buffer = str_html_compress(ob_get_contents()); |
1069
|
|
|
ob_end_clean(); |
1070
|
|
|
if (!isZlibOutputCompressionActive() && |
1071
|
|
|
isClientAcceptGzipEncoding() && |
1072
|
|
|
isZlibLoaded() |
1073
|
|
|
) { |
1074
|
|
|
ob_start('ob_gzhandler'); |
1075
|
|
|
} |
1076
|
|
|
echo $buffer; |
1077
|
|
|
}); |
1078
|
|
|
} |
1079
|
|
|
} |
1080
|
|
|
|
1081
|
|
|
if (!function_exists('get_http_response_code')) { |
1082
|
|
|
|
1083
|
|
|
/** |
1084
|
|
|
* @param string $theURL |
1085
|
|
|
* @param bool $useGet if set to true use a GET request, otherwise use a HEAD request (more fast). |
1086
|
|
|
* @return int return the http status or 999 if it fails. |
1087
|
|
|
*/ |
1088
|
|
|
function get_http_response_code(string $theURL, bool $useGet = false) : int |
1089
|
|
|
{ |
1090
|
|
|
if (isNullOrEmpty($theURL)) { |
1091
|
|
|
return 999; |
1092
|
|
|
} |
1093
|
|
|
if (!$useGet) { |
1094
|
|
|
// By default get_headers uses a GET request to fetch the headers. If you |
1095
|
|
|
// want to send a HEAD request instead, you can do so using a stream context: |
1096
|
|
|
stream_context_set_default( |
1097
|
|
|
array( |
1098
|
|
|
'http' => array( |
1099
|
|
|
'method' => 'HEAD' |
1100
|
|
|
) |
1101
|
|
|
) |
1102
|
|
|
); |
1103
|
|
|
} |
1104
|
|
|
$headers = @get_headers($theURL); |
1105
|
|
|
|
1106
|
|
|
if ($headers === false || isNullOrEmptyArray($headers) || strlen($headers[0]) < 12) { |
1107
|
|
|
return 999; |
1108
|
|
|
} |
1109
|
|
|
$status = substr($headers[0], 9, 3); |
1110
|
|
|
return isInteger($status) ? $status : 999; |
1111
|
|
|
} |
1112
|
|
|
} |
1113
|
|
|
|
1114
|
|
|
if (!function_exists('url_exists')) { |
1115
|
|
|
|
1116
|
|
|
/** |
1117
|
|
|
* Check if URL exists (return http status code <400 |
1118
|
|
|
* @param string $url |
1119
|
|
|
* @return bool |
1120
|
|
|
*/ |
1121
|
|
|
function url_exists(string $url) : bool |
1122
|
|
|
{ |
1123
|
|
|
return get_http_response_code($url) < 400; |
1124
|
|
|
} |
1125
|
|
|
} |
1126
|
|
|
|
1127
|
|
|
if (!function_exists('logToFile')) { |
1128
|
|
|
|
1129
|
|
|
/** |
1130
|
|
|
* Log variable into log file. |
1131
|
|
|
* @param string $pathFile full path with file name. |
1132
|
|
|
* @param mixed $value value to log |
1133
|
|
|
* @param bool $varDump default false. if set to true, |
1134
|
|
|
* grab var dump output of $value and write it to log, otherwise append it to log. |
1135
|
|
|
*/ |
1136
|
|
|
function logToFile(string $pathFile, $value, bool $varDump = false) |
1137
|
|
|
{ |
1138
|
|
|
if ($varDump) { |
1139
|
|
|
$value = get_var_dump_output($value); |
1140
|
|
|
} |
1141
|
|
|
$f = fopen($pathFile, 'ab'); |
1142
|
|
|
fwrite($f, date(DATE_RFC822) . "\r\n" . $value . "\r\n----------------------------------------------\r\n"); |
1143
|
|
|
fclose($f); |
1144
|
|
|
} |
1145
|
|
|
} |
1146
|
|
|
|
1147
|
|
|
/** |
1148
|
|
|
* Check if an extension is an image type. |
1149
|
|
|
* @param string $ext extension to check |
1150
|
|
|
* @return boolean |
1151
|
|
|
* @see https://github.com/kohana/ohanzee-helpers/blob/master/src/Mime.php |
1152
|
|
|
*/ |
1153
|
|
|
function isImageExtension(string $ext) : bool |
1154
|
|
|
{ |
1155
|
|
|
return in_array(strtolower($ext), getImageExtensions()); |
1156
|
|
|
} |
1157
|
|
|
|
1158
|
|
|
/** |
1159
|
|
|
* Get a list of common image extensions. Only types that can be read by |
1160
|
|
|
* PHP's internal image methods are included! |
1161
|
|
|
* @return string[] |
1162
|
|
|
*/ |
1163
|
|
|
function getImageExtensions() : array |
1164
|
|
|
{ |
1165
|
|
|
return [ |
1166
|
|
|
'bmp', |
1167
|
|
|
'gif', |
1168
|
|
|
'jpeg', |
1169
|
|
|
'jpg', |
1170
|
|
|
'png', |
1171
|
|
|
'tif', |
1172
|
|
|
'tiff', |
1173
|
|
|
'swf', |
1174
|
|
|
]; |
1175
|
|
|
} |
1176
|
|
|
|
1177
|
|
|
/** |
1178
|
|
|
* Very simple 'template' parser. Replaces (for example) {name} with the value of $vars['name'] in strings |
1179
|
|
|
* |
1180
|
|
|
* @param $str |
1181
|
|
|
* @param array $vars |
1182
|
|
|
* @param string $openDelimiter |
1183
|
|
|
* @param string $closeDelimiter |
1184
|
|
|
* |
1185
|
|
|
* @return string |
1186
|
|
|
* @see https://github.com/laradic/support/blob/master/src/Util.php |
1187
|
|
|
* @example |
1188
|
|
|
* <?php |
1189
|
|
|
* $result = template('This is the best template parser. Created by {developerName}', ['developerName' => 'Radic']); |
1190
|
|
|
* echo $result; // This is the best template parser. Created by Radic |
1191
|
|
|
*/ |
1192
|
|
|
function template($str, array $vars = [], $openDelimiter = '{', $closeDelimiter = '}') |
1193
|
|
|
{ |
1194
|
|
|
foreach ($vars as $k => $var) { |
1195
|
|
|
if (is_array($var)) { |
1196
|
|
|
$str = template($str, $var); |
1197
|
|
|
} elseif (is_string($var)) { |
1198
|
|
|
$str = str_replace($openDelimiter . $k . $closeDelimiter, $var, $str); |
1199
|
|
|
} |
1200
|
|
|
} |
1201
|
|
|
return $str; |
1202
|
|
|
} |
1203
|
|
|
|
1204
|
|
|
/** |
1205
|
|
|
* @param int $percent |
1206
|
|
|
* @return bool |
1207
|
|
|
* @see https://github.com/laradic/support/blob/master/src/Util.php |
1208
|
|
|
*/ |
1209
|
|
|
function randomChance(int $percent = 50) : bool |
1210
|
|
|
{ |
1211
|
|
|
return random_int(0, 100) > 100 - $percent; |
1212
|
|
|
} |
1213
|
|
|
|
1214
|
|
|
/** |
1215
|
|
|
* @param Throwable $exception |
1216
|
|
|
* @return string |
1217
|
|
|
*/ |
1218
|
|
|
function getExceptionTraceAsString(\Throwable $exception) |
1219
|
|
|
{ |
1220
|
|
|
$rtn = ""; |
1221
|
|
|
$count = 0; |
1222
|
|
|
foreach ($exception->getTrace() as $frame) { |
1223
|
|
|
$args = ""; |
1224
|
|
|
if (isset($frame['args'])) { |
1225
|
|
|
$args = []; |
1226
|
|
|
foreach ($frame['args'] as $arg) { |
1227
|
|
|
if (is_string($arg)) { |
1228
|
|
|
$args[] = "'" . $arg . "'"; |
1229
|
|
|
} elseif (is_array($arg)) { |
1230
|
|
|
$args[] = "Array"; |
1231
|
|
|
} elseif (is_null($arg)) { |
1232
|
|
|
$args[] = 'NULL'; |
1233
|
|
|
} elseif (is_bool($arg)) { |
1234
|
|
|
$args[] = ($arg) ? "true" : "false"; |
1235
|
|
|
} elseif (is_object($arg)) { |
1236
|
|
|
$args[] = get_class($arg); |
1237
|
|
|
} elseif (is_resource($arg)) { |
1238
|
|
|
$args[] = get_resource_type($arg); |
1239
|
|
|
} else { |
1240
|
|
|
$args[] = $arg; |
1241
|
|
|
} |
1242
|
|
|
} |
1243
|
|
|
$args = implode(", ", $args); |
1244
|
|
|
} |
1245
|
|
|
$rtn .= sprintf("#%s %s(%s): %s(%s)\n", |
1246
|
|
|
$count, |
1247
|
|
|
isset($frame['file']) ? $frame['file'] : '', |
1248
|
|
|
isset($frame['line']) ? $frame['line'] : '', |
1249
|
|
|
$frame['function'], |
1250
|
|
|
$args); |
1251
|
|
|
$count++; |
1252
|
|
|
} |
1253
|
|
|
return $rtn; |
1254
|
|
|
} |
1255
|
|
|
|
1256
|
|
|
if (!function_exists('windows_os')) { |
1257
|
|
|
/** |
1258
|
|
|
* Determine whether the current environment is Windows based. |
1259
|
|
|
* |
1260
|
|
|
* @return bool |
1261
|
|
|
* |
1262
|
|
|
* @see https://github.com/illuminate/support/blob/master/helpers.php |
1263
|
|
|
*/ |
1264
|
|
|
function windows_os() : bool |
1265
|
|
|
{ |
1266
|
|
|
return strtolower(substr(PHP_OS, 0, 3)) === 'win'; |
1267
|
|
|
} |
1268
|
|
|
} |
1269
|
|
|
|
1270
|
|
|
if (!function_exists('getConsoleColorTagForStatusCode')) { |
1271
|
|
|
/** |
1272
|
|
|
* Get the color tag for the given status code to be use in symfony/laravel console. |
1273
|
|
|
* |
1274
|
|
|
* @param string $code |
1275
|
|
|
* |
1276
|
|
|
* @return string |
1277
|
|
|
* |
1278
|
|
|
* @see https://github.com/spatie/http-status-check/blob/master/src/CrawlLogger.php#L96 |
1279
|
|
|
*/ |
1280
|
|
|
function getConsoleColorTagForStatusCode($code) |
1281
|
|
|
{ |
1282
|
|
|
if (starts_with($code, '2')) { |
1283
|
|
|
return 'info'; |
1284
|
|
|
} |
1285
|
|
|
if (starts_with($code, '3')) { |
1286
|
|
|
return 'comment'; |
1287
|
|
|
} |
1288
|
|
|
return 'error'; |
1289
|
|
|
} |
1290
|
|
|
} |
1291
|
|
|
|
1292
|
|
|
if (!function_exists('is_32bit')) { |
1293
|
|
|
/** |
1294
|
|
|
* Check if the OS architecture is 32bit. |
1295
|
|
|
* |
1296
|
|
|
* @return bool |
1297
|
|
|
* |
1298
|
|
|
* @see http://stackoverflow.com/questions/6303241/find-windows-32-or-64-bit-using-php |
1299
|
|
|
*/ |
1300
|
|
|
function is_32bit() : bool |
1301
|
|
|
{ |
1302
|
|
|
return get_os_architecture()==32; |
1303
|
|
|
} |
1304
|
|
|
} |
1305
|
|
|
|
1306
|
|
|
if (!function_exists('is_64bit')) { |
1307
|
|
|
/** |
1308
|
|
|
* Check if the OS architecture is 64bit. |
1309
|
|
|
* |
1310
|
|
|
* @return bool |
1311
|
|
|
* |
1312
|
|
|
* @see http://stackoverflow.com/questions/6303241/find-windows-32-or-64-bit-using-php |
1313
|
|
|
*/ |
1314
|
|
|
function is_64bit() : bool |
1315
|
|
|
{ |
1316
|
|
|
return get_os_architecture()==64; |
1317
|
|
|
} |
1318
|
|
|
} |
1319
|
|
|
|
1320
|
|
|
if (!function_exists('get_os_architecture')) { |
1321
|
|
|
/** |
1322
|
|
|
* Get the OS architecture 32 or 64 bit. |
1323
|
|
|
* |
1324
|
|
|
* @return int return 32 or 64 if ok, otherwise return 0. |
1325
|
|
|
* |
1326
|
|
|
* @see http://stackoverflow.com/questions/6303241/find-windows-32-or-64-bit-using-php |
1327
|
|
|
*/ |
1328
|
|
|
function get_os_architecture() : int |
1329
|
|
|
{ |
1330
|
|
|
switch(PHP_INT_SIZE) { |
1331
|
|
|
case 4: |
1332
|
|
|
return 32; |
1333
|
|
|
case 8: |
1334
|
|
|
return 64; |
1335
|
|
|
default: |
1336
|
|
|
return 0; |
1337
|
|
|
} |
1338
|
|
|
} |
1339
|
|
|
} |
1340
|
|
|
|
1341
|
|
|
|
1342
|
|
|
if (!function_exists('isRequestFromCloudFlare')) { |
1343
|
|
|
|
1344
|
|
|
/** |
1345
|
|
|
* Check if request (by given $_SERVER) is a cloudflare request |
1346
|
|
|
* @param $server |
1347
|
|
|
* @return bool |
1348
|
|
|
*/ |
1349
|
|
|
function isRequestFromCloudFlare(array $server) : bool |
1350
|
|
|
{ |
1351
|
|
|
if (!isset($server['HTTP_CF_CONNECTING_IP']) || !isIP($server['HTTP_CF_CONNECTING_IP'])) { |
1352
|
|
|
return false; |
1353
|
|
|
} |
1354
|
|
|
|
1355
|
|
|
if (isCloudFlareIp($server['REMOTE_ADDR'])) { |
1356
|
|
|
return true; |
1357
|
|
|
} |
1358
|
|
|
|
1359
|
|
|
//in case proxy or load balancer in front the server web |
1360
|
|
|
//the chained passed IPs are in the HTTP_X_FORWARDED_FOR var in these two possible ways: |
1361
|
|
|
//2.38.87.88 |
1362
|
|
|
//2.38.87.88, 188.114.101.5 |
|
|
|
|
1363
|
|
|
if (empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { |
1364
|
|
|
return false; |
1365
|
|
|
} |
1366
|
|
|
|
1367
|
|
|
if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') === false) { |
1368
|
|
|
return isCloudFlareIp($server['HTTP_X_FORWARDED_FOR']); |
1369
|
|
|
} |
1370
|
|
|
|
1371
|
|
|
$IPs = explode(",", $_SERVER['HTTP_X_FORWARDED_FOR']); |
1372
|
|
|
if (empty($IPs) || !is_array($IPs) || count($IPs) < 1) { |
1373
|
|
|
return false; |
1374
|
|
|
} |
1375
|
|
|
|
1376
|
|
|
//usually the cloudflare ip are the last IP in the stack, so start loop by last entries |
1377
|
|
|
for ($i = count($IPs) - 1; $i >= 0; $i--) { |
1378
|
|
|
$ip = trim($IPs[$i]); |
1379
|
|
|
if (isCloudFlareIp($ip)) { |
1380
|
|
|
return true; |
1381
|
|
|
} |
1382
|
|
|
} |
1383
|
|
|
|
1384
|
|
|
return false; |
1385
|
|
|
} |
1386
|
|
|
} |
1387
|
|
|
|
1388
|
|
|
if (!function_exists('isCloudFlareIp')) { |
1389
|
|
|
|
1390
|
|
|
/** |
1391
|
|
|
* Check if given ip is a valid cloudflare ip. |
1392
|
|
|
* @param $ip |
1393
|
|
|
* @return bool |
1394
|
|
|
*/ |
1395
|
|
|
function isCloudFlareIp($ip) : bool |
1396
|
|
|
{ |
1397
|
|
|
if (!isIP($ip)) { |
1398
|
|
|
return false; |
1399
|
|
|
} |
1400
|
|
|
|
1401
|
|
|
//array given from https://www.cloudflare.com/ips-v4 |
1402
|
|
|
$cf_ip_ranges = array( |
1403
|
|
|
'103.21.244.0/22', |
1404
|
|
|
'103.22.200.0/22', |
1405
|
|
|
'103.31.4.0/22', |
1406
|
|
|
'104.16.0.0/12', |
1407
|
|
|
'108.162.192.0/18', |
1408
|
|
|
'131.0.72.0/22', |
1409
|
|
|
'141.101.64.0/18', |
1410
|
|
|
'162.158.0.0/15', |
1411
|
|
|
'172.64.0.0/13', |
1412
|
|
|
'173.245.48.0/20', |
1413
|
|
|
'188.114.96.0/20', |
1414
|
|
|
'190.93.240.0/20', |
1415
|
|
|
'197.234.240.0/22', |
1416
|
|
|
'198.41.128.0/17', |
1417
|
|
|
); |
1418
|
|
|
|
1419
|
|
|
foreach ($cf_ip_ranges as $range) { |
1420
|
|
|
if (ipInRange($ip, $range)) { |
1421
|
|
|
return true; |
1422
|
|
|
} |
1423
|
|
|
} |
1424
|
|
|
|
1425
|
|
|
return false; |
1426
|
|
|
} |
1427
|
|
|
} |
1428
|
|
|
|
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.