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
|
|
|
* @return string |
52
|
|
|
*/ |
53
|
|
|
function format_money(float $val = 0, int $precision = 2, string $simbol = "") : string |
54
|
|
|
{ |
55
|
|
|
return "$simbol " . number_format($val, $precision, ',', '.'); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Format float 1125.86 into string '&euro 1.125,86' |
60
|
|
|
* @param float $val |
61
|
|
|
* @return string |
62
|
|
|
*/ |
63
|
|
|
function format_euro(float $val = 0) : string |
64
|
|
|
{ |
65
|
|
|
return format_money($val, 2, '€ '); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
if (!function_exists('ordinal')) { |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* Given a number, return the number + 'th' or 'rd' etc |
72
|
|
|
* @param $cdnl |
73
|
|
|
* @return string |
74
|
|
|
*/ |
75
|
|
|
function ordinal($cdnl) |
76
|
|
|
{ |
77
|
|
|
$test_c = abs($cdnl) % 10; |
78
|
|
|
$ext = ((abs($cdnl) % 100 < 21 && abs($cdnl) % 100 > 4) ? 'th' |
79
|
|
|
: (($test_c < 4) ? ($test_c < 3) ? ($test_c < 2) ? ($test_c < 1) |
80
|
|
|
? 'th' : 'st' : 'nd' : 'rd' : 'th')); |
81
|
|
|
return $cdnl . $ext; |
82
|
|
|
} |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
if (!function_exists('value')) { |
86
|
|
|
/** |
87
|
|
|
* Return the default value of the given value. |
88
|
|
|
* |
89
|
|
|
* @param mixed $value |
90
|
|
|
* @return mixed |
91
|
|
|
*/ |
92
|
|
|
function value($value) |
93
|
|
|
{ |
94
|
|
|
return $value instanceof Closure ? $value() : $value; |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
if (!function_exists('with')) { |
98
|
|
|
/** |
99
|
|
|
* Return the given object. Useful for chaining. |
100
|
|
|
* |
101
|
|
|
* @param mixed $object |
102
|
|
|
* @return mixed |
103
|
|
|
*/ |
104
|
|
|
function with($object) |
105
|
|
|
{ |
106
|
|
|
return $object; |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Set the default configuration of erro reporting for production. |
112
|
|
|
*/ |
113
|
|
|
function setErrorReportingForProduction() |
114
|
|
|
{ |
115
|
|
|
if (version_compare(PHP_VERSION, '5.4.0') >= 0) { |
116
|
|
|
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT); |
117
|
|
|
} elseif (version_compare(PHP_VERSION, '5.3.0') >= 0) { |
118
|
|
|
error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED); |
119
|
|
|
} else { |
120
|
|
|
error_reporting(E_ALL ^ E_NOTICE); |
121
|
|
|
} |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Check if PHP script was executed by shell. |
126
|
|
|
* @return bool |
127
|
|
|
*/ |
128
|
|
|
function isExecutedByCLI() : bool |
129
|
|
|
{ |
130
|
|
|
return php_sapi_name() == 'cli'; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Convert the output of PHP's filesize() function |
135
|
|
|
* to a nice format with PB, TB, GB, MB, kB, bytes. |
136
|
|
|
* @param $bytes |
137
|
|
|
* @return string |
138
|
|
|
*/ |
139
|
|
|
function bytes2HumanSize($bytes) |
140
|
|
|
{ |
141
|
|
|
if ($bytes >= 1125899906842624) { |
142
|
|
|
$bytes = number_format($bytes / 1073741824, 2) . ' PB'; |
143
|
|
|
} elseif ($bytes >= 1099511627776) { |
144
|
|
|
$bytes = number_format($bytes / 1073741824, 2) . ' TB'; |
145
|
|
|
} elseif ($bytes >= 1073741824) { |
146
|
|
|
$bytes = number_format($bytes / 1073741824, 2) . ' GB'; |
147
|
|
|
} elseif ($bytes >= 1048576) { |
148
|
|
|
$bytes = number_format($bytes / 1048576, 2) . ' MB'; |
149
|
|
|
} elseif ($bytes >= 1024) { |
150
|
|
|
$bytes = number_format($bytes / 1024, 2) . ' kB'; |
151
|
|
|
} elseif ($bytes > 1) { |
152
|
|
|
$bytes .= ' bytes'; |
153
|
|
|
} elseif ($bytes == 1) { |
154
|
|
|
$bytes .= ' byte'; |
155
|
|
|
} else { |
156
|
|
|
$bytes = '0 bytes'; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
return $bytes; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* This function transforms the php.ini notation for numbers (like '2M') |
164
|
|
|
* to an integer (2*1024*1024 in this case) |
165
|
|
|
* @param string $sSize |
166
|
|
|
* @return int|string |
167
|
|
|
*/ |
168
|
|
|
function convertPHPSizeToBytes($sSize) |
169
|
|
|
{ |
170
|
|
|
if (is_numeric($sSize)) { |
171
|
|
|
return $sSize; |
172
|
|
|
} |
173
|
|
|
$sSuffix = substr($sSize, -1); |
174
|
|
|
$iValue = substr($sSize, 0, -1); |
175
|
|
|
|
176
|
|
|
switch (strtoupper($sSuffix)) { |
177
|
|
|
case 'P': |
178
|
|
|
$iValue *= 1024; |
179
|
|
|
//PB multiplier |
180
|
|
|
case 'T': |
181
|
|
|
$iValue *= 1024; |
182
|
|
|
//TB multiplier |
183
|
|
|
case 'G': |
184
|
|
|
$iValue *= 1024; |
185
|
|
|
//GB multiplier |
186
|
|
|
case 'M': |
187
|
|
|
$iValue *= 1024; |
188
|
|
|
//MB multiplier |
189
|
|
|
case 'K': |
190
|
|
|
$iValue *= 1024; |
191
|
|
|
//KB multiplier |
192
|
|
|
break; |
193
|
|
|
} |
194
|
|
|
return $iValue; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* Return the Max upload size in bytes. |
199
|
|
|
* @param bool $humanFormat if set to true return size in human format (MB, kB, etc..) otherwise return in bytes. |
200
|
|
|
* @return int |
201
|
|
|
*/ |
202
|
|
|
function getMaximumFileUploadSize(bool $humanFormat = false) |
203
|
|
|
{ |
204
|
|
|
$size = min(convertPHPSizeToBytes(ini_get('post_max_size')), convertPHPSizeToBytes(ini_get('upload_max_filesize'))); |
205
|
|
|
|
206
|
|
|
if (!$humanFormat) { |
207
|
|
|
return $size; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
return bytes2HumanSize($size); |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
/** |
214
|
|
|
* Encrypt string. |
215
|
|
|
* @param string $string to encrypt. |
216
|
|
|
* @param string $chiave the key to encrypt. if empty generate a random key on the fly. |
217
|
|
|
* @return string |
218
|
|
|
*/ |
219
|
|
|
function encryptString(string $string, string $chiave = '') |
220
|
|
|
{ |
221
|
|
|
if ($chiave == '') { |
222
|
|
|
$chiave = str_random(64); |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
$key = pack('H*', $chiave); |
226
|
|
|
|
227
|
|
|
$plaintext = $string; |
228
|
|
|
|
229
|
|
|
# create a random IV to use with CBC encoding |
230
|
|
|
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); |
231
|
|
|
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); |
232
|
|
|
|
233
|
|
|
# creates a cipher text compatible with AES (Rijndael block size = 128) |
234
|
|
|
# to keep the text confidential |
235
|
|
|
# only suitable for encoded input that never ends with value 00h |
236
|
|
|
# (because of default zero padding) |
237
|
|
|
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv); |
238
|
|
|
|
239
|
|
|
# prepend the IV for it to be available for decryption |
240
|
|
|
$ciphertext = $iv . $ciphertext; |
241
|
|
|
|
242
|
|
|
# encode the resulting cipher text so it can be represented by a string |
243
|
|
|
$ciphertext_base64 = base64_encode($ciphertext); |
244
|
|
|
|
245
|
|
|
return $ciphertext_base64; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* Get a Website favicon url. |
250
|
|
|
* |
251
|
|
|
* @param string $url website url |
252
|
|
|
* |
253
|
|
|
* @return string containing complete image tag |
254
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
255
|
|
|
*/ |
256
|
|
|
function getFaviconUrl($url) : string |
257
|
|
|
{ |
258
|
|
|
$protocol = 'http://'; |
259
|
|
|
if (isHttps()) { |
260
|
|
|
$protocol = 'https://'; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
$apiUrl = $protocol . 'www.google.com/s2/favicons?domain='; |
264
|
|
|
if (strpos($url, 'http') !== false) { |
265
|
|
|
$url = str_replace('http://', '', $url); |
266
|
|
|
} |
267
|
|
|
return $apiUrl . $url; |
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
/** |
271
|
|
|
* Get a Website favicon image tag. |
272
|
|
|
* |
273
|
|
|
* @param string $url website url |
274
|
|
|
* @param array $attributes Optional, additional key/value attributes to include in the IMG tag |
275
|
|
|
* |
276
|
|
|
* @return string containing complete image tag |
277
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
278
|
|
|
*/ |
279
|
|
|
function getFaviconImgTag($url, array $attributes = []) : string |
280
|
|
|
{ |
281
|
|
|
$urlFav = getFaviconUrl($url); |
282
|
|
|
$attr = arrayToString($attributes); |
283
|
|
|
return '<img src="' . $urlFav . '" ' . trim($attr) . ' />'; |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
/** |
287
|
|
|
* Check to see if the current page is being server over SSL or not. |
288
|
|
|
* |
289
|
|
|
* @return bool |
290
|
|
|
*/ |
291
|
|
|
function isHttps() |
292
|
|
|
{ |
293
|
|
|
return isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'; |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
/** |
297
|
|
|
* Get a QR code. |
298
|
|
|
* |
299
|
|
|
* @param string $string String to generate QR code for. |
300
|
|
|
* @param int $width QR code width |
301
|
|
|
* @param int $height QR code height |
302
|
|
|
* @param array $attributes Optional, additional key/value attributes to include in the IMG tag |
303
|
|
|
* |
304
|
|
|
* @return string containing complete image tag |
305
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
306
|
|
|
*/ |
307
|
|
|
function getQRcode($string, int $width = 150, int $height = 150, array $attributes = []) : string |
308
|
|
|
{ |
309
|
|
|
$attr = arrayToString($attributes); |
310
|
|
|
$apiUrl = getQRcodeUrl($string, $width, $height); |
311
|
|
|
return '<img src="' . $apiUrl . '" ' . trim($attr) . ' />'; |
312
|
|
|
} |
313
|
|
|
|
314
|
|
|
/** |
315
|
|
|
* Get a QR code Url. |
316
|
|
|
* |
317
|
|
|
* @param string $string String to generate QR code for. |
318
|
|
|
* @param int $width QR code width |
319
|
|
|
* @param int $height QR code height |
320
|
|
|
* |
321
|
|
|
* @return string containing complete image url |
322
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
323
|
|
|
*/ |
324
|
|
|
function getQRcodeUrl($string, int $width = 150, int $height = 150) : string |
325
|
|
|
{ |
326
|
|
|
$protocol = 'http://'; |
327
|
|
|
if (isHttps()) { |
328
|
|
|
$protocol = 'https://'; |
329
|
|
|
} |
330
|
|
|
return $protocol . 'chart.apis.google.com/chart?chs=' . $width . 'x' . $height . '&cht=qr&chl=' . urlencode($string); |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
if (!function_exists('gravatarUrl')) { |
334
|
|
|
/** |
335
|
|
|
* Get a Gravatar URL from email. |
336
|
|
|
* |
337
|
|
|
* @param string $email The email address |
338
|
|
|
* @param int $size in pixels, defaults to 80px [ 1 - 2048 ] |
339
|
|
|
* @param string $default imageset to use [ 404 | mm | identicon | monsterid | wavatar ] |
340
|
|
|
* @param string $rating (inclusive) [ g | pg | r | x ] |
341
|
|
|
* @return string |
342
|
|
|
* @source http://gravatar.com/site/implement/images/php/ |
343
|
|
|
*/ |
344
|
|
|
function gravatarUrl($email, $size = 80, $default = 'mm', $rating = 'g') |
345
|
|
|
{ |
346
|
|
|
$url = 'http://www.gravatar.com'; |
347
|
|
|
if (isHttps()) { |
348
|
|
|
$url = 'https://secure.gravatar.com'; |
349
|
|
|
} |
350
|
|
|
$url .= '/avatar.php?gravatar_id=' . md5(strtolower(trim($email))) . '&default=' . $default . '&size=' . $size . '&rating=' . $rating; |
351
|
|
|
return $url; |
352
|
|
|
} |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
if (!function_exists('gravatar')) { |
356
|
|
|
/** |
357
|
|
|
* Get a Gravatar img tag from email. |
358
|
|
|
* |
359
|
|
|
* @param string $email The email address |
360
|
|
|
* @param int $size in pixels, defaults to 80px [ 1 - 2048 ] |
361
|
|
|
* @param string $default imageset to use [ 404 | mm | identicon | monsterid | wavatar ] |
362
|
|
|
* @param string $rating (inclusive) [ g | pg | r | x ] |
363
|
|
|
* @param array $attributes Optional, additional key/value attributes to include in the IMG tag |
364
|
|
|
* @return string |
365
|
|
|
* @source http://gravatar.com/site/implement/images/php/ |
366
|
|
|
*/ |
367
|
|
|
function gravatar($email, $size = 80, $default = 'mm', $rating = 'g', $attributes = []) |
368
|
|
|
{ |
369
|
|
|
$attr = arrayToString($attributes); |
370
|
|
|
$url = gravatarUrl($email, $size, $default, $rating); |
371
|
|
|
return '<img src="' . $url . '" width="' . $size . 'px" height="' . $size . 'px" ' . trim($attr) . ' />'; |
372
|
|
|
} |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
if (!function_exists('isAjax')) { |
376
|
|
|
|
377
|
|
|
/** |
378
|
|
|
* Determine if current page request type is ajax. |
379
|
|
|
* |
380
|
|
|
* @return bool |
381
|
|
|
*/ |
382
|
|
|
function isAjax() |
383
|
|
|
{ |
384
|
|
|
return $_SERVER !== null && array_key_exists_safe($_SERVER, |
385
|
|
|
'HTTP_X_REQUESTED_WITH') && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'; |
386
|
|
|
} |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
if (!function_exists('isNumberOdd')) { |
390
|
|
|
|
391
|
|
|
/** |
392
|
|
|
* Check if number is odd. |
393
|
|
|
* |
394
|
|
|
* @param int $num integer to check |
395
|
|
|
* |
396
|
|
|
* @return bool |
397
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
398
|
|
|
*/ |
399
|
|
|
function isNumberOdd($num) |
400
|
|
|
{ |
401
|
|
|
return $num % 2 !== 0; |
402
|
|
|
} |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
if (!function_exists('isNumberEven')) { |
406
|
|
|
|
407
|
|
|
/** |
408
|
|
|
* Check if number is even. |
409
|
|
|
* |
410
|
|
|
* @param int $num integer to check |
411
|
|
|
* |
412
|
|
|
* @return bool |
413
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
414
|
|
|
*/ |
415
|
|
|
function isNumberEven($num) |
416
|
|
|
{ |
417
|
|
|
return $num % 2 == 0; |
418
|
|
|
} |
419
|
|
|
} |
420
|
|
|
|
421
|
|
|
if (!function_exists('getCurrentURL')) { |
422
|
|
|
|
423
|
|
|
/** |
424
|
|
|
* Return the current URL. |
425
|
|
|
* |
426
|
|
|
* @return string |
427
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
428
|
|
|
*/ |
429
|
|
|
function getCurrentURL() |
430
|
|
|
{ |
431
|
|
|
$url = 'http://'; |
432
|
|
|
if (isHttps()) { |
433
|
|
|
$url = 'https://'; |
434
|
|
|
} |
435
|
|
|
if (array_key_exists_safe($_SERVER, 'PHP_AUTH_USER')) { |
436
|
|
|
$url .= $_SERVER['PHP_AUTH_USER']; |
437
|
|
|
if (array_key_exists_safe($_SERVER, 'PHP_AUTH_PW')) { |
438
|
|
|
$url .= ':' . $_SERVER['PHP_AUTH_PW']; |
439
|
|
|
} |
440
|
|
|
$url .= '@'; |
441
|
|
|
} |
442
|
|
|
if (array_key_exists_safe($_SERVER, 'HTTP_HOST')) { |
443
|
|
|
$url .= $_SERVER['HTTP_HOST']; |
444
|
|
|
} |
445
|
|
|
if (array_key_exists_safe($_SERVER, 'SERVER_PORT') && $_SERVER['SERVER_PORT'] != 80) { |
446
|
|
|
$url .= ':' . $_SERVER['SERVER_PORT']; |
447
|
|
|
} |
448
|
|
|
if (!array_key_exists_safe($_SERVER, 'REQUEST_URI')) { |
449
|
|
|
$url .= substr($_SERVER['PHP_SELF'], 1); |
450
|
|
|
if (array_key_exists_safe($_SERVER, 'QUERY_STRING')): |
451
|
|
|
$url .= '?' . $_SERVER['QUERY_STRING']; |
452
|
|
|
endif; |
453
|
|
|
} else { |
454
|
|
|
$url .= $_SERVER['REQUEST_URI']; |
455
|
|
|
} |
456
|
|
|
return $url; |
457
|
|
|
} |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
if (!function_exists('isMobile')) { |
461
|
|
|
|
462
|
|
|
/** |
463
|
|
|
* Detect if user is on mobile device. |
464
|
|
|
* |
465
|
|
|
* @return bool |
466
|
|
|
*/ |
467
|
|
|
function isMobile() |
468
|
|
|
{ |
469
|
|
|
$useragent = $_SERVER['HTTP_USER_AGENT']; |
470
|
|
|
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', |
471
|
|
|
$useragent) |
472
|
|
|
|| 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', |
473
|
|
|
substr($useragent, 0, 4)); |
474
|
|
|
} |
475
|
|
|
} |
476
|
|
|
|
477
|
|
|
/** |
478
|
|
|
* Get user browser. |
479
|
|
|
* |
480
|
|
|
* @return string |
481
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
482
|
|
|
*/ |
483
|
|
|
function getBrowser() |
484
|
|
|
{ |
485
|
|
|
$u_agent = $_SERVER['HTTP_USER_AGENT']; |
486
|
|
|
$browserName = $ub = $platform = 'Unknown'; |
487
|
|
|
if (preg_match('/linux/i', $u_agent)) { |
488
|
|
|
$platform = 'Linux'; |
489
|
|
|
} elseif (preg_match('/macintosh|mac os x/i', $u_agent)) { |
490
|
|
|
$platform = 'Mac OS'; |
491
|
|
|
} elseif (preg_match('/windows|win32/i', $u_agent)) { |
492
|
|
|
$platform = 'Windows'; |
493
|
|
|
} |
494
|
|
|
if (preg_match('/MSIE/i', $u_agent) && !preg_match('/Opera/i', $u_agent)) { |
495
|
|
|
$browserName = 'Internet Explorer'; |
496
|
|
|
$ub = 'MSIE'; |
497
|
|
|
} elseif (preg_match('/Firefox/i', $u_agent)) { |
498
|
|
|
$browserName = 'Mozilla Firefox'; |
499
|
|
|
$ub = 'Firefox'; |
500
|
|
|
} elseif (preg_match('/Chrome/i', $u_agent)) { |
501
|
|
|
$browserName = 'Google Chrome'; |
502
|
|
|
$ub = 'Chrome'; |
503
|
|
|
} elseif (preg_match('/Safari/i', $u_agent)) { |
504
|
|
|
$browserName = 'Apple Safari'; |
505
|
|
|
$ub = 'Safari'; |
506
|
|
|
} elseif (preg_match('/Opera/i', $u_agent)) { |
507
|
|
|
$browserName = 'Opera'; |
508
|
|
|
$ub = 'Opera'; |
509
|
|
|
} elseif (preg_match('/Netscape/i', $u_agent)) { |
510
|
|
|
$browserName = 'Netscape'; |
511
|
|
|
$ub = 'Netscape'; |
512
|
|
|
} |
513
|
|
|
$known = ['Version', $ub, 'other']; |
514
|
|
|
$pattern = '#(?<browser>' . implode('|', $known) . ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#'; |
515
|
|
|
preg_match_all($pattern, $u_agent, $matches); |
516
|
|
|
$i = count($matches['browser']); |
517
|
|
|
if ($i != 1) { |
518
|
|
|
if (strripos($u_agent, 'Version') < strripos($u_agent, $ub)) { |
519
|
|
|
$version = $matches['version'][0]; |
520
|
|
|
} else { |
521
|
|
|
$version = $matches['version'][1]; |
522
|
|
|
} |
523
|
|
|
} else { |
524
|
|
|
$version = $matches['version'][0]; |
525
|
|
|
} |
526
|
|
|
if ($version == null || $version == '') { |
527
|
|
|
$version = '?'; |
528
|
|
|
} |
529
|
|
|
return implode(', ', [$browserName, 'Version: ' . $version, $platform]); |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
/** |
533
|
|
|
* Shorten URL via tinyurl.com service. |
534
|
|
|
* It support http or https. |
535
|
|
|
* @param string $url URL to shorten |
536
|
|
|
* |
537
|
|
|
* @return string shortend url or empty string if it fails. |
538
|
|
|
*/ |
539
|
|
|
function getTinyUrl(string $url) : string |
540
|
|
|
{ |
541
|
|
|
if (!starts_with($url, 'http')) { |
542
|
|
|
$url = (isHttps() ? 'https://' : 'http://') . $url; |
543
|
|
|
} |
544
|
|
|
$gettiny = curl('http://tinyurl.com/api-create.php?url=' . $url); |
545
|
|
|
if (isNullOrEmpty($gettiny) && isNullOrEmptyArray($gettiny)) { |
546
|
|
|
return ''; |
547
|
|
|
} |
548
|
|
|
if (isHttps()) { |
549
|
|
|
$gettiny = str_replace('http://', 'https://', $gettiny); |
550
|
|
|
} |
551
|
|
|
return $gettiny; |
552
|
|
|
} |
553
|
|
|
|
554
|
|
|
/** |
555
|
|
|
* Get information on a short URL. Find out where it goes. |
556
|
|
|
* |
557
|
|
|
* @param string $shortURL shortened URL |
558
|
|
|
* |
559
|
|
|
* @return string full url or empty string |
560
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
561
|
|
|
*/ |
562
|
|
|
function expandShortUrl(string $shortURL) : string |
563
|
|
|
{ |
564
|
|
|
if (isNullOrEmpty($shortURL)) { |
565
|
|
|
return ''; |
566
|
|
|
} |
567
|
|
|
$headers = get_headers($shortURL, 1); |
568
|
|
|
if (array_key_exists_safe($headers, 'Location')) { |
569
|
|
|
return $headers['Location']; |
570
|
|
|
} |
571
|
|
|
$data = curl($shortURL); |
572
|
|
|
preg_match_all('/<[\s]*meta[\s]*http-equiv="?' . '([^>"]*)"?[\s]*' . 'content="?([^>"]*)"?[\s]*[\/]?[\s]*>/si', |
573
|
|
|
$data, $match); |
574
|
|
|
if (isNullOrEmptyArray($match) || count($match) != 3 |
575
|
|
|
|| isNullOrEmptyArray($match[0]) || isNullOrEmptyArray($match[1]) || isNullOrEmptyArray($match[2]) |
576
|
|
|
|| count($match[0]) != count($match[1]) || count($match[1]) != count($match[2]) |
577
|
|
|
) { |
578
|
|
|
return ''; |
579
|
|
|
} |
580
|
|
|
$originals = $match[0]; |
581
|
|
|
$names = $match[1]; |
582
|
|
|
$values = $match[2]; |
583
|
|
|
$metaTags = []; |
584
|
|
|
for ($i = 0, $limit = count($names); $i < $limit; $i++) { |
585
|
|
|
$metaTags[$names[$i]] = ['html' => htmlentities($originals[$i]), 'value' => $values[$i]]; |
586
|
|
|
} |
587
|
|
|
if (!isset($metaTags['refresh']['value']) || empty($metaTags['refresh']['value'])) { |
588
|
|
|
return ''; |
589
|
|
|
} |
590
|
|
|
$returnData = explode('=', $metaTags['refresh']['value']); |
591
|
|
|
if (!isset($returnData[1]) || empty($returnData[1])) { |
|
|
|
|
592
|
|
|
} |
593
|
|
|
return $returnData[1]; |
594
|
|
|
} |
595
|
|
|
|
596
|
|
|
if (!function_exists('curl')) { |
597
|
|
|
|
598
|
|
|
/** |
599
|
|
|
* Make Curl call. |
600
|
|
|
* |
601
|
|
|
* @param string $url URL to curl |
602
|
|
|
* @param string $method GET or POST, Default GET |
603
|
|
|
* @param mixed $data Data to post, Default false |
604
|
|
|
* @param mixed $headers Additional headers, example: array ("Accept: application/json") |
605
|
|
|
* @param bool $returnInfo Whether or not to retrieve curl_getinfo() |
606
|
|
|
* |
607
|
|
|
* @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 |
608
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
609
|
|
|
*/ |
610
|
|
|
function curl($url, $method = 'GET', $data = false, $headers = false, $returnInfo = false) |
611
|
|
|
{ |
612
|
|
|
$ch = curl_init(); |
613
|
|
|
$info = null; |
614
|
|
|
if (strtoupper($method) == 'POST') { |
615
|
|
|
curl_setopt($ch, CURLOPT_POST, true); |
616
|
|
|
if ($data !== false) { |
617
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); |
618
|
|
|
} |
619
|
|
|
} elseif ($data !== false) { |
620
|
|
|
if (is_array($data)) { |
621
|
|
|
$dataTokens = []; |
622
|
|
|
foreach ($data as $key => $value) { |
623
|
|
|
array_push($dataTokens, urlencode($key) . '=' . urlencode($value)); |
624
|
|
|
} |
625
|
|
|
$data = implode('&', $dataTokens); |
626
|
|
|
} |
627
|
|
|
$url .= '?' . $data; |
628
|
|
|
} |
629
|
|
|
curl_setopt($ch, CURLOPT_URL, $url); |
630
|
|
|
curl_setopt($ch, CURLOPT_HEADER, false); |
631
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
632
|
|
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); |
633
|
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 10); |
634
|
|
|
if ($headers !== false) { |
635
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); |
636
|
|
|
} |
637
|
|
|
$contents = curl_exec($ch); |
638
|
|
|
if ($returnInfo) { |
639
|
|
|
$info = curl_getinfo($ch); |
640
|
|
|
} |
641
|
|
|
curl_close($ch); |
642
|
|
|
return ($returnInfo ? ['contents' => $contents, 'info' => $info] : $contents); |
643
|
|
|
} |
644
|
|
|
} |
645
|
|
|
|
646
|
|
|
if (!function_exists('debug')) { |
647
|
|
|
|
648
|
|
|
/** |
649
|
|
|
* Dump information about a variable. |
650
|
|
|
* |
651
|
|
|
* @param mixed $variable Variable to debug |
652
|
|
|
* |
653
|
|
|
* @return void |
654
|
|
|
* @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php |
655
|
|
|
*/ |
656
|
|
|
function debug($variable) |
657
|
|
|
{ |
658
|
|
|
ob_start(); |
659
|
|
|
var_dump($variable); |
|
|
|
|
660
|
|
|
$output = ob_get_clean(); |
661
|
|
|
$maps = [ |
662
|
|
|
'string' => "/(string\((?P<length>\d+)\)) (?P<value>\"(?<!\\\).*\")/i", |
663
|
|
|
'array' => "/\[\"(?P<key>.+)\"(?:\:\"(?P<class>[a-z0-9_\\\]+)\")?(?:\:(?P<scope>public|protected|private))?\]=>/Ui", |
664
|
|
|
'countable' => "/(?P<type>array|int|string)\((?P<count>\d+)\)/", |
665
|
|
|
'resource' => "/resource\((?P<count>\d+)\) of type \((?P<class>[a-z0-9_\\\]+)\)/", |
666
|
|
|
'bool' => "/bool\((?P<value>true|false)\)/", |
667
|
|
|
'float' => "/float\((?P<value>[0-9\.]+)\)/", |
668
|
|
|
'object' => "/object\((?P<class>\S+)\)\#(?P<id>\d+) \((?P<count>\d+)\)/i" |
669
|
|
|
]; |
670
|
|
|
foreach ($maps as $function => $pattern) { |
671
|
|
|
$output = preg_replace_callback($pattern, function ($matches) use ($function) { |
672
|
|
|
switch ($function) { |
673
|
|
|
case 'string': |
674
|
|
|
$matches['value'] = htmlspecialchars($matches['value']); |
675
|
|
|
return '<span style="color: #0000FF;">string</span>(<span style="color: #1287DB;">' . $matches['length'] . ')</span> <span style="color: #6B6E6E;">' . $matches['value'] . '</span>'; |
676
|
|
|
case 'array': |
677
|
|
|
$key = '<span style="color: #008000;">"' . $matches['key'] . '"</span>'; |
678
|
|
|
$class = ''; |
679
|
|
|
$scope = ''; |
680
|
|
|
if (isset($matches['class']) && !empty($matches['class'])) { |
681
|
|
|
$class = ':<span style="color: #4D5D94;">"' . $matches['class'] . '"</span>'; |
682
|
|
|
} |
683
|
|
|
if (isset($matches['scope']) && !empty($matches['scope'])) { |
684
|
|
|
$scope = ':<span style="color: #666666;">' . $matches['scope'] . '</span>'; |
685
|
|
|
} |
686
|
|
|
return '[' . $key . $class . $scope . ']=>'; |
687
|
|
|
case 'countable': |
688
|
|
|
$type = '<span style="color: #0000FF;">' . $matches['type'] . '</span>'; |
689
|
|
|
$count = '(<span style="color: #1287DB;">' . $matches['count'] . '</span>)'; |
690
|
|
|
return $type . $count; |
691
|
|
|
case 'bool': |
692
|
|
|
return '<span style="color: #0000FF;">bool</span>(<span style="color: #0000FF;">' . $matches['value'] . '</span>)'; |
693
|
|
|
case 'float': |
694
|
|
|
return '<span style="color: #0000FF;">float</span>(<span style="color: #1287DB;">' . $matches['value'] . '</span>)'; |
695
|
|
|
case 'resource': |
696
|
|
|
return '<span style="color: #0000FF;">resource</span>(<span style="color: #1287DB;">' . $matches['count'] . '</span>) of type (<span style="color: #4D5D94;">' . $matches['class'] . '</span>)'; |
697
|
|
|
case 'object': |
698
|
|
|
return '<span style="color: #0000FF;">object</span>(<span style="color: #4D5D94;">' . $matches['class'] . '</span>)#' . $matches['id'] . ' (<span style="color: #1287DB;">' . $matches['count'] . '</span>)'; |
699
|
|
|
} |
700
|
|
|
}, $output); |
701
|
|
|
} |
702
|
|
|
$header = ''; |
703
|
|
|
list($debugfile) = debug_backtrace(); |
704
|
|
|
if (!empty($debugfile['file'])) { |
705
|
|
|
$header = '<h4 style="border-bottom:1px solid #bbb;font-weight:bold;margin:0 0 10px 0;padding:3px 0 10px 0">' . $debugfile['file'] . '</h4>'; |
706
|
|
|
} |
707
|
|
|
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>'; |
708
|
|
|
} |
709
|
|
|
} |
710
|
|
|
|
This check looks for the bodies of
if
statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.These
if
bodies can be removed. If you have an empty if but statements in theelse
branch, consider inverting the condition.could be turned into
This is much more concise to read.