Completed
Push — master ( ec6ab3...598217 )
by Lorenzo
03:27
created

helpers.php ➔ get_os_architecture()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 0
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
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.00, 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.00) : string
64
{
65
    return format_money($val, 2, '&euro; ');
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 in asymmetrical way.
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
    $apiUrl = 'https://www.google.com/s2/favicons?domain=';
259
    if (strpos($url, 'http') !== false) {
260
        $url = str_replace('http://', '', $url);
261
    }
262
    return $apiUrl . $url;
263
}
264
265
/**
266
 * Get a Website favicon image tag.
267
 *
268
 * @param string $url website url
269
 * @param array $attributes Optional, additional key/value attributes to include in the IMG tag
270
 *
271
 * @return string containing complete image tag
272
 * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
273
 */
274
function getFaviconImgTag($url, array $attributes = []) : string
275
{
276
    $urlFav = getFaviconUrl($url);
277
    $attr = arrayToString($attributes);
278
    return '<img src="' . $urlFav . '" ' . trim($attr) . ' />';
279
}
280
281
/**
282
 * Check to see if the current page is being server over SSL or not.
283
 * Support HTTP_X_FORWARDED_PROTO to check ssl over proxy/load balancer.
284
 *
285
 * @return bool
286
 */
287
function isHttps()
288
{
289
    $key = 'HTTPS';
290
    if (isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_X_FORWARDED_PROTO')) {
291
        $key = 'HTTP_X_FORWARDED_PROTO';
292
    }
293
    return isNotNullOrEmptyArrayKey($_SERVER, $key) && strtolower($_SERVER[$key]) !== '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 = 'https://www.gravatar.com';
347
        $url .= '/avatar/' . md5(strtolower(trim($email))) . '?default=' . $default . '&size=' . $size . '&rating=' . $rating;
348
        return $url;
349
    }
350
}
351
352
if (!function_exists('gravatar')) {
353
    /**
354
     * Get a Gravatar img tag from email.
355
     *
356
     * @param string $email The email address
357
     * @param int $size in pixels, defaults to 80px [ 1 - 2048 ]
358
     * @param string $default imageset to use [ 404 | mm | identicon | monsterid | wavatar ]
359
     * @param string $rating (inclusive) [ g | pg | r | x ]
360
     * @param array $attributes Optional, additional key/value attributes to include in the IMG tag
361
     * @return string
362
     * @source http://gravatar.com/site/implement/images/php/
363
     */
364
    function gravatar($email, $size = 80, $default = 'mm', $rating = 'g', $attributes = [])
365
    {
366
        $attr = arrayToString($attributes);
367
        $url = gravatarUrl($email, $size, $default, $rating);
368
        return '<img src="' . $url . '" width="' . $size . 'px" height="' . $size . 'px" ' . trim($attr) . ' />';
369
    }
370
}
371
372
if (!function_exists('isAjax')) {
373
374
    /**
375
     * Determine if current page request type is ajax.
376
     *
377
     * @return bool
378
     */
379
    function isAjax()
380
    {
381
        return isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_X_REQUESTED_WITH')
382
        && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
383
    }
384
}
385
386
if (!function_exists('isNumberOdd')) {
387
388
    /**
389
     * Check if number is odd.
390
     *
391
     * @param int $num integer to check
392
     *
393
     * @return bool
394
     * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
395
     */
396
    function isNumberOdd($num)
397
    {
398
        return $num % 2 !== 0;
399
    }
400
}
401
402
if (!function_exists('isNumberEven')) {
403
404
    /**
405
     * Check if number is even.
406
     *
407
     * @param int $num integer to check
408
     *
409
     * @return bool
410
     * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
411
     */
412
    function isNumberEven($num)
413
    {
414
        return $num % 2 == 0;
415
    }
416
}
417
418
if (!function_exists('getCurrentUrlPageName')) {
419
420
    /**
421
     * Returns The Current URL PHP File Name.
422
     * Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return index.php
423
     *
424
     * @return string
425
     */
426
    function getCurrentUrlPageName() : string
427
    {
428
        return isNotNullOrEmptyArrayKey($_SERVER, 'PHP_SELF') ? basename($_SERVER['PHP_SELF']) : '';
429
    }
430
}
431
432
if (!function_exists('getCurrentUrlQuerystring')) {
433
434
    /**
435
     * Returns The Current URL querystring.
436
     * Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return one=1&two=2
437
     *
438
     * @return string
439
     */
440
    function getCurrentUrlQuerystring() : string
441
    {
442
        return isNotNullOrEmptyArrayKey($_SERVER, 'QUERY_STRING') ? $_SERVER['QUERY_STRING'] : '';
443
    }
444
}
445
446
if (!function_exists('getCurrentUrlDirName')) {
447
448
    /**
449
     * Returns The Current URL Path Name.
450
     * Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return /one/two
451
     *
452
     * @return string
453
     */
454
    function getCurrentUrlDirName() : string
455
    {
456
        if (isNotNullOrEmptyArrayKey($_SERVER, 'REQUEST_URI')) {
457
            return dirname($_SERVER['REQUEST_URI']);
458
        }
459
        return isNotNullOrEmptyArrayKey($_SERVER, 'PHP_SELF') ? dirname($_SERVER['PHP_SELF']) : '';
460
    }
461
}
462
463
if (!function_exists('getCurrentUrlDirAbsName')) {
464
465
    /**
466
     * Returns The Current URL Absolute Path Name.
467
     * Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return /home/user/www/one/two
468
     *
469
     * @return string
470
     */
471
    function getCurrentUrlDirAbsName() : string
472
    {
473
        return isNotNullOrEmptyArrayKey($_SERVER, 'SCRIPT_FILENAME') ? dirname($_SERVER['SCRIPT_FILENAME']) : '';
474
    }
475
}
476
477
if (!function_exists('getCurrentURL')) {
478
479
    /**
480
     * Return the current URL.
481
     * Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2
482
     * Or
483
     * Ex.: https://username:[email protected]:443/one/two/index.php?one=1&two=2
484
     * @return string
485
     * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
486
     */
487
    function getCurrentURL()
488
    {
489
        $url = 'http://';
490
        if (isHttps()) {
491
            $url = 'https://';
492
        }
493
        if (array_key_exists_safe($_SERVER, 'PHP_AUTH_USER')) {
494
            $url .= $_SERVER['PHP_AUTH_USER'];
495
            if (array_key_exists_safe($_SERVER, 'PHP_AUTH_PW')) {
496
                $url .= ':' . $_SERVER['PHP_AUTH_PW'];
497
            }
498
            $url .= '@';
499
        }
500
        if (array_key_exists_safe($_SERVER, 'HTTP_HOST')) {
501
            $url .= $_SERVER['HTTP_HOST'];
502
        }
503
        if (array_key_exists_safe($_SERVER, 'SERVER_PORT') && $_SERVER['SERVER_PORT'] != 80) {
504
            $url .= ':' . $_SERVER['SERVER_PORT'];
505
        }
506
        if (!array_key_exists_safe($_SERVER, 'REQUEST_URI')) {
507
            $url .= substr($_SERVER['PHP_SELF'], 1);
508
            if (array_key_exists_safe($_SERVER, 'QUERY_STRING')):
509
                $url .= '?' . $_SERVER['QUERY_STRING'];
510
            endif;
511
        } else {
512
            $url .= $_SERVER['REQUEST_URI'];
513
        }
514
        return $url;
515
    }
516
}
517
518
if (!function_exists('isMobile')) {
519
520
    /**
521
     * Detect if user is on mobile device.
522
     *
523
     * @return bool
524
     */
525
    function isMobile()
526
    {
527
        $useragent = $_SERVER['HTTP_USER_AGENT'];
528
        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',
529
            $useragent)
530
        || 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',
531
            substr($useragent, 0, 4));
532
    }
533
}
534
535
/**
536
 * Get user browser.
537
 *
538
 * @return string
539
 * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
540
 */
541
function getBrowser()
542
{
543
    $u_agent = $_SERVER['HTTP_USER_AGENT'];
544
    $browserName = $ub = $platform = 'Unknown';
545
    if (preg_match('/linux/i', $u_agent)) {
546
        $platform = 'Linux';
547
    } elseif (preg_match('/macintosh|mac os x/i', $u_agent)) {
548
        $platform = 'Mac OS';
549
    } elseif (preg_match('/windows|win32/i', $u_agent)) {
550
        $platform = 'Windows';
551
    }
552
    if (preg_match('/MSIE/i', $u_agent) && !preg_match('/Opera/i', $u_agent)) {
553
        $browserName = 'Internet Explorer';
554
        $ub = 'MSIE';
555
    } elseif (preg_match('/Firefox/i', $u_agent)) {
556
        $browserName = 'Mozilla Firefox';
557
        $ub = 'Firefox';
558
    } elseif (preg_match('/Chrome/i', $u_agent)) {
559
        $browserName = 'Google Chrome';
560
        $ub = 'Chrome';
561
    } elseif (preg_match('/Safari/i', $u_agent)) {
562
        $browserName = 'Apple Safari';
563
        $ub = 'Safari';
564
    } elseif (preg_match('/Opera/i', $u_agent)) {
565
        $browserName = 'Opera';
566
        $ub = 'Opera';
567
    } elseif (preg_match('/Netscape/i', $u_agent)) {
568
        $browserName = 'Netscape';
569
        $ub = 'Netscape';
570
    }
571
    $known = ['Version', $ub, 'other'];
572
    $pattern = '#(?<browser>' . implode('|', $known) . ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
573
    preg_match_all($pattern, $u_agent, $matches);
574
    $i = count($matches['browser']);
575
    if ($i != 1) {
576
        if (strripos($u_agent, 'Version') < strripos($u_agent, $ub)) {
577
            $version = $matches['version'][0];
578
        } else {
579
            $version = $matches['version'][1];
580
        }
581
    } else {
582
        $version = $matches['version'][0];
583
    }
584
    if ($version == null || $version == '') {
585
        $version = '?';
586
    }
587
    return implode(', ', [$browserName, 'Version: ' . $version, $platform]);
588
}
589
590
/**
591
 * Shorten URL via tinyurl.com service.
592
 * It support http or https.
593
 * @param string $url URL to shorten
594
 *
595
 * @return string shortend url or empty string if it fails.
596
 */
597
function getTinyUrl(string $url) : string
598
{
599
    if (!starts_with($url, 'http')) {
600
        $url = (isHttps() ? 'https://' : 'http://') . $url;
601
    }
602
    $gettiny = curl('http://tinyurl.com/api-create.php?url=' . $url);
603
    if (isNullOrEmpty($gettiny) && isNullOrEmptyArray($gettiny)) {
604
        return '';
605
    }
606
    if (isHttps()) {
607
        $gettiny = str_replace('http://', 'https://', $gettiny);
608
    }
609
    return $gettiny;
610
}
611
612
/**
613
 * Get information on a short URL. Find out where it goes.
614
 *
615
 * @param string $shortURL shortened URL
616
 *
617
 * @return string full url or empty string
618
 * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
619
 */
620
function expandShortUrl(string $shortURL) : string
621
{
622
    if (isNullOrEmpty($shortURL)) {
623
        return '';
624
    }
625
    $headers = get_headers($shortURL, 1);
626
    if (array_key_exists_safe($headers, 'Location')) {
627
        return $headers['Location'];
628
    }
629
    $data = curl($shortURL);
630
    preg_match_all('/<[\s]*meta[\s]*http-equiv="?' . '([^>"]*)"?[\s]*' . 'content="?([^>"]*)"?[\s]*[\/]?[\s]*>/si',
631
        $data, $match);
632
    if (isNullOrEmptyArray($match) || count($match) != 3
633
        || isNullOrEmptyArray($match[0]) || isNullOrEmptyArray($match[1]) || isNullOrEmptyArray($match[2])
634
        || count($match[0]) != count($match[1]) || count($match[1]) != count($match[2])
635
    ) {
636
        return '';
637
    }
638
    $originals = $match[0];
639
    $names = $match[1];
640
    $values = $match[2];
641
    $metaTags = [];
642
    for ($i = 0, $limit = count($names); $i < $limit; $i++) {
643
        $metaTags[$names[$i]] = ['html' => htmlentities($originals[$i]), 'value' => $values[$i]];
644
    }
645
    if (!isset($metaTags['refresh']['value']) || empty($metaTags['refresh']['value'])) {
646
        return '';
647
    }
648
    $returnData = explode('=', $metaTags['refresh']['value']);
649
    if (!isset($returnData[1]) || empty($returnData[1])) {
650
        return '';
651
    }
652
    return $returnData[1];
653
}
654
655
if (!function_exists('curl')) {
656
657
    /**
658
     * Make Curl call.
659
     *
660
     * @param string $url URL to curl
661
     * @param string $method GET or POST, Default GET
662
     * @param mixed $data Data to post, Default false
663
     * @param string[] $headers Additional headers, example: array ("Accept: application/json")
664
     * @param bool $returnInfo Whether or not to retrieve curl_getinfo()
665
     * @param string $user
666
     * @param string $password
667
     * @param bool $sslNotVerifyHostAndPeer is set to true do not check SSL certificate.
668
     * @param bool $followLocation
669
     * @param int $timeout
670
     * @param string $logPath if not empty write log to this file
671
     * @param string $referer
672
     * @param string $userAgent default 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0'
673
     * and ignore $returnInfo (i.e. call curl_getinfo even if $returnInfo is set to false).
674
     *
675
     * @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
676
     * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
677
     */
678
    function curl(
679
        $url,
680
        $method = 'GET',
681
        $data = false,
682
        array $headers = [],
683
        bool $returnInfo = false,
684
        string $user = '',
685
        string $password = '',
686
        bool $sslNotVerifyHostAndPeer = false,
687
        bool $followLocation = false,
688
        int $timeout = 10,
689
        string $logPath = '',
690
        string $referer = '',
691
        string $userAgent = 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0'
692
    ) {
693
        $log = false;
694
        if (isNotNullOrEmpty($logPath)) {
695
            $log = true;
696
            $msg = "REQUEST_URI: " . (isNotNullOrEmptyArrayKey($_SERVER,
697
                    'REQUEST_URI') ? $_SERVER['REQUEST_URI'] : '') . "\r\n"
698
                . "SCRIPT_NAME: " . (isNotNullOrEmptyArrayKey($_SERVER,
699
                    'SCRIPT_NAME') ? $_SERVER['SCRIPT_NAME'] : '') . "\r\n"
700
                . "REMOTE ADDR: " . (isNotNullOrEmptyArrayKey($_SERVER,
701
                    'REMOTE_ADDR') ? $_SERVER['REMOTE_ADDR'] : '') . "\r\n"
702
                . "HTTP_HOST: " . (isNotNullOrEmptyArrayKey($_SERVER,
703
                    'HTTP_HOST') ? $_SERVER['HTTP_HOST'] : '') . "\r\n"
704
                . "SERVER_NAME: " . (isNotNullOrEmptyArrayKey($_SERVER,
705
                    'SERVER_NAME') ? $_SERVER['SERVER_NAME'] : '') . "\r\n"
706
                . "HTTP_X_FORWARDED_FOR: " . (isNotNullOrEmptyArrayKey($_SERVER,
707
                    'HTTP_X_FORWARDED_FOR') ? $_SERVER['HTTP_X_FORWARDED_FOR'] : '') . "\r\n"
708
                . "SERVER_ADDR: " . (isNotNullOrEmptyArrayKey($_SERVER,
709
                    'SERVER_ADDR') ? $_SERVER['SERVER_ADDR'] : '') . "\r\n"
710
                . "REMOTE_PORT: " . (isNotNullOrEmptyArrayKey($_SERVER,
711
                    'REMOTE_PORT') ? $_SERVER['REMOTE_PORT'] : '') . "\r\n"
712
                . "HTTPS: " . (isNotNullOrEmptyArrayKey($_SERVER, 'HTTPS') ? $_SERVER['HTTPS'] : '') . "\r\n"
713
                . "HTTP_X_FORWARDED_PROTO: " . (isNotNullOrEmptyArrayKey($_SERVER,
714
                    'HTTP_X_FORWARDED_PROTO') ? $_SERVER['HTTP_X_FORWARDED_PROTO'] : '') . "\r\n"
715
                . "data: " . get_var_dump_output($data) . "\r\n"
716
                . "headers: " . get_var_dump_output($headers) . "\r\n"
717
                . "returnInfo: " . $returnInfo . "\r\n"
718
                . "url: " . $url . "\r\n"
719
                . "method: " . $method . "\r\n"
720
                . "user: " . $user . "\r\n"
721
                . "password: " . (strlen($password) > 2 ? substr($password, 0, 2) . str_repeat('x',
722
                        10) . substr($password, -1) : 'xx') . "\r\n"
723
                . "sslNotVerifyHostAndPeer: " . $sslNotVerifyHostAndPeer . "\r\n"
724
                . "followLocation: " . $followLocation . "\r\n"
725
                . "timeout: " . $timeout . "\r\n"
726
                . "logPath: " . $logPath . "\r\n"
727
                . "referer: " . $referer . "\r\n"
728
                . "userAgent: " . $userAgent . "\r\n"
729
                . "\r\n";
730
            logToFile($logPath, $msg);
731
        }
732
        if (!function_exists('curl_init') || isNullOrEmpty($url)) {
733
            if ($log) {
734
                logToFile($logPath,
735
                    isNullOrEmpty($url) ? 'url is empty.curl abort.' : 'curl_init not exists.Probabily CURL is not installed.');
736
            }
737
            return '';
738
        }
739
        $ch = curl_init();
740
        $info = null;
741
        if (strtoupper($method) == 'POST') {
742
            curl_setopt($ch, CURLOPT_POST, true);
743
            if ($data !== false) {
744
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
745
            }
746
        } elseif ($data !== false) {
747
            if (is_array($data)) {
748
                $dataTokens = [];
749
                foreach ($data as $key => $value) {
750
                    $dataTokens[] = urlencode($key) . '=' . urlencode($value);
751
                }
752
                $data = implode('&', $dataTokens);
753
            }
754
            $url .= (strpos($url, '?') === false ? '&' : '?') . $data;
755
        }
756
        curl_setopt($ch, CURLOPT_URL, $url);
757
        curl_setopt($ch, CURLOPT_HEADER, false);
758
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
759
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $followLocation ? true : false);
760
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout <= 1 ? 10 : $timeout);
761
        if ($sslNotVerifyHostAndPeer && starts_with($url, 'https://')) {
762
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
763
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
764
        }
765
        if (isNotNullOrEmptyArray($headers)) {
766
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
767
        }
768
        if (isNotNullOrEmpty($user) && isNotNullOrEmpty($password)) {
769
            curl_setopt($ch, CURLOPT_USERPWD, $user . ':' . $password);
770
        }
771
        if (isNotNullOrEmpty($referer)) {
772
            curl_setopt($ch, CURLOPT_REFERER, $referer);
773
        }
774
        if (isNotNullOrEmpty($userAgent)) {
775
            curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
776
        }
777
778
        if ($log) {
779
            logToFile($logPath, date('Y-m-d H:i:s') . "Start curl\r\n");
780
        }
781
        $contents = curl_exec($ch);
782
        if ($log) {
783
            logToFile($logPath, date('Y-m-d H:i:s') . "FINISH curl\r\n");
784
        }
785
786
        if ($returnInfo || $log || $contents === false || curl_errno($ch) > 0) {
787
            $info = curl_getinfo($ch);
788
            if ($log) {
789
                logToFile($logPath, $info, true);
790
            }
791
        }
792
793
        if ($contents === false || curl_errno($ch) > 0
794
            || !array_key_exists_safe($info === null ? [] : $info, 'http_code') || $info['http_code'] != 200
795
        ) {
796
            if ($log) {
797
                logToFile($logPath, "Error during exec CURL \r\n curl_error: " . curl_error($ch)
798
                    . "\r\n curl_errno: " . curl_errno($ch) . "\r\n");
799
            }
800
        } elseif ($log) {
801
            logToFile($logPath, "CURL IS OK\r\n RESPONSE: \r\n" . $contents);
802
        }
803
804
        curl_close($ch);
805
        return ($returnInfo ? ['contents' => $contents, 'info' => $info] : $contents);
806
    }
807
}
808
809
810
if (!function_exists('curl_internal_server_behind_load_balancer')) {
811
812
    /**
813
     * Make Curl call to one of the server behinds load balancer.
814
     *
815
     * @param string $url URL to curl
816
     * @param string $server_name The host name of the domain from the call will start.
817
     * if empty try to resolve from SERVER_NAME
818
     * @param string $localServerIpAddress the IP of one server to call that behinds load balancer.
819
     * if empty try to resolve from SERVER_ADDR
820
     * @param string $method GET or POST, Default GET
821
     * @param mixed $data Data to post, Default false
822
     * @param array $headers Additional headers, example: array ("Accept: application/json")
823
     * @param bool $returnInfo Whether or not to retrieve curl_getinfo()
824
     * @param string $user
825
     * @param string $password
826
     * @param bool $sslNotVerifyHostAndPeer is set to true do not check SSL certificate.
827
     * @param bool $followLocation
828
     * @param int $timeout
829
     * @param string $logPath if not empty write log to this file
830
     * @param string $referer
831
     * @param string $userAgent default 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0'
832
     * and ignore $returnInfo (i.e. call curl_getinfo even if $returnInfo is set to false).
833
     *
834
     * @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
835
     */
836
    function curl_internal_server_behind_load_balancer(
837
        $url,
838
        $server_name = '',
839
        $localServerIpAddress = '',
840
        $method = 'GET',
841
        $data = false,
842
        array $headers = [],
843
        bool $returnInfo = false,
844
        string $user = '',
845
        string $password = '',
846
        bool $sslNotVerifyHostAndPeer = false,
847
        bool $followLocation = false,
848
        int $timeout = 10,
849
        string $logPath = '',
850
        string $referer = '',
851
        string $userAgent = 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0'
852
    ) {
853
        if (isNullOrEmpty($server_name) && isNotNullOrEmptyArrayKey($_SERVER, 'SERVER_NAME')) {
854
            $server_name = $_SERVER['SERVER_NAME'];
855
        }
856
857 View Code Duplication
        if (isNullOrEmpty($server_name) && isNotNullOrEmpty($logPath)) {
858
            $msg = 'No server name given for calling curl ' . $url . ' behind proxy or LB';
859
            logToFile($logPath, $msg);
860
            return false;
861
        }
862
863
        if (isNullOrEmpty($localServerIpAddress) && isNotNullOrEmptyArrayKey($_SERVER, 'SERVER_ADDR')) {
864
            $localServerIpAddress = $_SERVER['SERVER_ADDR'];
865
        }
866
867 View Code Duplication
        if (isNullOrEmpty($localServerIpAddress) && isNotNullOrEmpty($logPath)) {
868
            $msg = 'No localIPAddress given for calling curl ' . $url . ' behind proxy or LB';
869
            logToFile($logPath, $msg);
870
            return false;
871
        }
872
873
        $url = str_replace($server_name, $localServerIpAddress, $url);
874
875
        //Using the host header to bypass a load balancer
876
        if (!is_array($headers)) {
877
            $headers = array();
878
        }
879
        $headers[] = 'Host: ' . $server_name;
880
881
        return curl($url, $method, $data, $headers, $returnInfo, $user, $password, $sslNotVerifyHostAndPeer,
882
            $followLocation, $timeout, $logPath, $referer, $userAgent);
883
    }
884
}
885
886
if (!function_exists('startLayoutCapture')) {
887
888
    /**
889
     * Turn On the output buffering.
890
     * @return bool
891
     */
892
    function startLayoutCapture() : bool
893
    {
894
        return ob_start();
895
    }
896
}
897
898
if (!function_exists('endLayoutCapture')) {
899
900
    /**
901
     * Get the buffer contents for the topmost buffer and clean it.
902
     * @return string
903
     */
904
    function endLayoutCapture() : string
905
    {
906
        $data = ob_get_contents();
907
        ob_end_clean();
908
        return $data === false ? '' : $data;
909
    }
910
}
911
912
if (!function_exists('get_var_dump_output')) {
913
914
    /**
915
     * Capture var dump $var output and return it.
916
     * @param $var
917
     * @return string
918
     */
919
    function get_var_dump_output($var)
920
    {
921
        startLayoutCapture();
922
        $myfunc = "var_dump";
923
        $myfunc($var);
924
        return endLayoutCapture();
925
    }
926
}
927
928
if (!function_exists('debug')) {
929
930
    /**
931
     * Dump information about a variable.
932
     *
933
     * @param mixed $variable Variable to debug
934
     *
935
     * @return void
936
     * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
937
     */
938
    function debug($variable)
939
    {
940
        $output = get_var_dump_output($variable);
941
        $maps = [
942
            'string' => "/(string\((?P<length>\d+)\)) (?P<value>\"(?<!\\\).*\")/i",
943
            'array' => "/\[\"(?P<key>.+)\"(?:\:\"(?P<class>[a-z0-9_\\\]+)\")?(?:\:(?P<scope>public|protected|private))?\]=>/Ui",
944
            'countable' => "/(?P<type>array|int|string)\((?P<count>\d+)\)/",
945
            'resource' => "/resource\((?P<count>\d+)\) of type \((?P<class>[a-z0-9_\\\]+)\)/",
946
            'bool' => "/bool\((?P<value>true|false)\)/",
947
            'float' => "/float\((?P<value>[0-9\.]+)\)/",
948
            'object' => "/object\((?P<class>\S+)\)\#(?P<id>\d+) \((?P<count>\d+)\)/i"
949
        ];
950
        foreach ($maps as $function => $pattern) {
951
            $output = preg_replace_callback($pattern, function ($matches) use ($function) {
952
                switch ($function) {
953
                    case 'string':
954
                        $matches['value'] = htmlspecialchars($matches['value']);
955
                        return '<span style="color: #0000FF;">string</span>(<span style="color: #1287DB;">' . $matches['length'] . ')</span> <span style="color: #6B6E6E;">' . $matches['value'] . '</span>';
956
                    case 'array':
957
                        $key = '<span style="color: #008000;">"' . $matches['key'] . '"</span>';
958
                        $class = '';
959
                        $scope = '';
960
                        if (isset($matches['class']) && !empty($matches['class'])) {
961
                            $class = ':<span style="color: #4D5D94;">"' . $matches['class'] . '"</span>';
962
                        }
963
                        if (isset($matches['scope']) && !empty($matches['scope'])) {
964
                            $scope = ':<span style="color: #666666;">' . $matches['scope'] . '</span>';
965
                        }
966
                        return '[' . $key . $class . $scope . ']=>';
967
                    case 'countable':
968
                        $type = '<span style="color: #0000FF;">' . $matches['type'] . '</span>';
969
                        $count = '(<span style="color: #1287DB;">' . $matches['count'] . '</span>)';
970
                        return $type . $count;
971
                    case 'bool':
972
                        return '<span style="color: #0000FF;">bool</span>(<span style="color: #0000FF;">' . $matches['value'] . '</span>)';
973
                    case 'float':
974
                        return '<span style="color: #0000FF;">float</span>(<span style="color: #1287DB;">' . $matches['value'] . '</span>)';
975
                    case 'resource':
976
                        return '<span style="color: #0000FF;">resource</span>(<span style="color: #1287DB;">' . $matches['count'] . '</span>) of type (<span style="color: #4D5D94;">' . $matches['class'] . '</span>)';
977
                    case 'object':
978
                        return '<span style="color: #0000FF;">object</span>(<span style="color: #4D5D94;">' . $matches['class'] . '</span>)#' . $matches['id'] . ' (<span style="color: #1287DB;">' . $matches['count'] . '</span>)';
979
                }
980
            }, $output);
981
        }
982
        $header = '';
983
        list($debugfile) = debug_backtrace();
984
        if (!empty($debugfile['file'])) {
985
            $header = '<h4 style="border-bottom:1px solid #bbb;font-weight:bold;margin:0 0 10px 0;padding:3px 0 10px 0">' . $debugfile['file'] . '</h4>';
986
        }
987
        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>';
988
    }
989
}
990
991
if (!function_exists('getReferer')) {
992
993
    /**
994
     * Return referer page if exists otherwise return empty string.
995
     *
996
     * @return string
997
     */
998
    function getReferer() : string
999
    {
1000
        return isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_REFERER') ? $_SERVER['HTTP_REFERER'] : '';
1001
    }
1002
}
1003
1004
if (!function_exists('isZlibOutputCompressionActive')) {
1005
1006
    /**
1007
     * Check if zlib output compression was active
1008
     * @return bool
1009
     */
1010
    function isZlibOutputCompressionActive() : bool
1011
    {
1012
        return ini_get('zlib.output_compression') == 'On'
1013
        || ini_get('zlib.output_compression_level') > 0
1014
        || ini_get('output_handler') == 'ob_gzhandler';
1015
    }
1016
}
1017
1018
if (!function_exists('isZlibLoaded')) {
1019
1020
    /**
1021
     * Check if zlib extension was loaded
1022
     * @return bool
1023
     */
1024
    function isZlibLoaded() : bool
1025
    {
1026
        return extension_loaded('zlib');
1027
    }
1028
}
1029
1030
if (!function_exists('isClientAcceptGzipEncoding')) {
1031
1032
    /**
1033
     * Check if client accept gzip encoding
1034
     * @return bool
1035
     */
1036
    function isClientAcceptGzipEncoding() : bool
1037
    {
1038
        return isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_ACCEPT_ENCODING')
1039
        && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false;
1040
    }
1041
}
1042
1043
if (!function_exists('compressHtmlPage')) {
1044
1045
    /**
1046
     * Captures output via ob_get_contents(), tries to enable gzip,
1047
     * removes whitespace from captured output and echos back
1048
     *
1049
     * @return string whitespace stripped output
1050
     * @see https://github.com/ngfw/Recipe/
1051
     */
1052
    function compressHtmlPage() : string
1053
    {
1054
        register_shutdown_function(function () {
1055
            $buffer = str_html_compress(ob_get_contents());
1056
            ob_end_clean();
1057
            if (!isZlibOutputCompressionActive() &&
1058
                isClientAcceptGzipEncoding() &&
1059
                isZlibLoaded()
1060
            ) {
1061
                ob_start('ob_gzhandler');
1062
            }
1063
            echo $buffer;
1064
        });
1065
    }
1066
}
1067
1068
if (!function_exists('get_http_response_code')) {
1069
1070
    /**
1071
     * @param string $theURL
1072
     * @param bool $useGet if set to true use a GET request, otherwise use a HEAD request (more fast).
1073
     * @return int return the http status or 999 if it fails.
1074
     */
1075
    function get_http_response_code(string $theURL, bool $useGet = false) : int
1076
    {
1077
        if (isNullOrEmpty($theURL)) {
1078
            return 999;
1079
        }
1080
        if (!$useGet) {
1081
            // By default get_headers uses a GET request to fetch the headers. If you
1082
            // want to send a HEAD request instead, you can do so using a stream context:
1083
            stream_context_set_default(
1084
                array(
1085
                    'http' => array(
1086
                        'method' => 'HEAD'
1087
                    )
1088
                )
1089
            );
1090
        }
1091
        $headers = @get_headers($theURL);
1092
1093
        if ($headers === false || isNullOrEmptyArray($headers) || strlen($headers[0]) < 12) {
1094
            return 999;
1095
        }
1096
        $status = substr($headers[0], 9, 3);
1097
        return isInteger($status) ? $status : 999;
1098
    }
1099
}
1100
1101
if (!function_exists('url_exists')) {
1102
1103
    /**
1104
     * Check if URL exists (return http status code <400
1105
     * @param string $url
1106
     * @return bool
1107
     */
1108
    function url_exists(string $url) : bool
1109
    {
1110
        return get_http_response_code($url) < 400;
1111
    }
1112
}
1113
1114
if (!function_exists('logToFile')) {
1115
1116
    /**
1117
     * Log variable into log file.
1118
     * @param string $pathFile full path with file name.
1119
     * @param mixed $value value to log
1120
     * @param bool $varDump default false. if set to true,
1121
     * grab var dump output of $value and write it to log, otherwise append it to log.
1122
     */
1123
    function logToFile(string $pathFile, $value, bool $varDump = false)
1124
    {
1125
        if ($varDump) {
1126
            $value = get_var_dump_output($value);
1127
        }
1128
        $f = fopen($pathFile, 'ab');
1129
        fwrite($f, date(DATE_RFC822) . "\r\n" . $value . "\r\n----------------------------------------------\r\n");
1130
        fclose($f);
1131
    }
1132
}
1133
1134
/**
1135
 * Check if an extension is an image type.
1136
 * @param  string $ext extension to check
1137
 * @return boolean
1138
 * @see https://github.com/kohana/ohanzee-helpers/blob/master/src/Mime.php
1139
 */
1140
function isImageExtension(string $ext) : bool
1141
{
1142
    return in_array(strtolower($ext), getImageExtensions());
1143
}
1144
1145
/**
1146
 * Get a list of common image extensions. Only types that can be read by
1147
 * PHP's internal image methods are included!
1148
 * @return string[]
1149
 */
1150
function getImageExtensions() : array
1151
{
1152
    return [
1153
        'bmp',
1154
        'gif',
1155
        'jpeg',
1156
        'jpg',
1157
        'png',
1158
        'tif',
1159
        'tiff',
1160
        'swf',
1161
    ];
1162
}
1163
1164
/**
1165
 * Very simple 'template' parser. Replaces (for example) {name} with the value of $vars['name'] in strings
1166
 *
1167
 * @param        $str
1168
 * @param array $vars
1169
 * @param string $openDelimiter
1170
 * @param string $closeDelimiter
1171
 *
1172
 * @return string
1173
 * @see https://github.com/laradic/support/blob/master/src/Util.php
1174
 * @example
1175
 * <?php
1176
 * $result = template('This is the best template parser. Created by {developerName}', ['developerName' => 'Radic']);
1177
 * echo $result; // This is the best template parser. Created by Radic
1178
 */
1179
function template($str, array $vars = [], $openDelimiter = '{', $closeDelimiter = '}')
1180
{
1181
    foreach ($vars as $k => $var) {
1182
        if (is_array($var)) {
1183
            $str = template($str, $var);
1184
        } elseif (is_string($var)) {
1185
            $str = str_replace($openDelimiter . $k . $closeDelimiter, $var, $str);
1186
        }
1187
    }
1188
    return $str;
1189
}
1190
1191
/**
1192
 * @param int $percent
1193
 * @return bool
1194
 * @see https://github.com/laradic/support/blob/master/src/Util.php
1195
 */
1196
function randomChance(int $percent = 50) : bool
1197
{
1198
    return random_int(0, 100) > 100 - $percent;
1199
}
1200
1201
/**
1202
 * @param Throwable $exception
1203
 * @return string
1204
 */
1205
function getExceptionTraceAsString(\Throwable $exception)
1206
{
1207
    $rtn = "";
1208
    $count = 0;
1209
    foreach ($exception->getTrace() as $frame) {
1210
        $args = "";
1211
        if (isset($frame['args'])) {
1212
            $args = [];
1213
            foreach ($frame['args'] as $arg) {
1214
                if (is_string($arg)) {
1215
                    $args[] = "'" . $arg . "'";
1216
                } elseif (is_array($arg)) {
1217
                    $args[] = "Array";
1218
                } elseif (is_null($arg)) {
1219
                    $args[] = 'NULL';
1220
                } elseif (is_bool($arg)) {
1221
                    $args[] = ($arg) ? "true" : "false";
1222
                } elseif (is_object($arg)) {
1223
                    $args[] = get_class($arg);
1224
                } elseif (is_resource($arg)) {
1225
                    $args[] = get_resource_type($arg);
1226
                } else {
1227
                    $args[] = $arg;
1228
                }
1229
            }
1230
            $args = implode(", ", $args);
1231
        }
1232
        $rtn .= sprintf("#%s %s(%s): %s(%s)\n",
1233
            $count,
1234
            isset($frame['file']) ? $frame['file'] : '',
1235
            isset($frame['line']) ? $frame['line'] : '',
1236
            $frame['function'],
1237
            $args);
1238
        $count++;
1239
    }
1240
    return $rtn;
1241
}
1242
1243
if (!function_exists('windows_os')) {
1244
    /**
1245
     * Determine whether the current environment is Windows based.
1246
     *
1247
     * @return bool
1248
     *
1249
     * @see https://github.com/illuminate/support/blob/master/helpers.php
1250
     */
1251
    function windows_os() : bool
1252
    {
1253
        return strtolower(substr(PHP_OS, 0, 3)) === 'win';
1254
    }
1255
}
1256
1257
if (!function_exists('getConsoleColorTagForStatusCode')) {
1258
    /**
1259
     * Get the color tag for the given status code to be use in symfony/laravel console.
1260
     *
1261
     * @param string $code
1262
     *
1263
     * @return string
1264
     *
1265
     * @see https://github.com/spatie/http-status-check/blob/master/src/CrawlLogger.php#L96
1266
     */
1267
    function getConsoleColorTagForStatusCode($code)
1268
    {
1269
        if (starts_with($code, '2')) {
1270
            return 'info';
1271
        }
1272
        if (starts_with($code, '3')) {
1273
            return 'comment';
1274
        }
1275
        return 'error';
1276
    }
1277
}
1278
1279
if (!function_exists('is_32bit')) {
1280
    /**
1281
     * Check if the OS architecture is 32bit.
1282
     *
1283
     * @return bool
1284
     *
1285
     * @see http://stackoverflow.com/questions/6303241/find-windows-32-or-64-bit-using-php
1286
     */
1287
    function is_32bit() : bool
1288
    {
1289
        return get_os_architecture()==32;
1290
    }
1291
}
1292
1293
if (!function_exists('is_64bit')) {
1294
    /**
1295
     * Check if the OS architecture is 64bit.
1296
     *
1297
     * @return bool
1298
     *
1299
     * @see http://stackoverflow.com/questions/6303241/find-windows-32-or-64-bit-using-php
1300
     */
1301
    function is_64bit() : bool
1302
    {
1303
        return get_os_architecture()==64;
1304
    }
1305
}
1306
1307
if (!function_exists('get_os_architecture')) {
1308
    /**
1309
     * Get the OS architecture 32 or 64 bit.
1310
     *
1311
     * @return int return 32 or 64 if ok, otherwise return 0.
1312
     *
1313
     * @see http://stackoverflow.com/questions/6303241/find-windows-32-or-64-bit-using-php
1314
     */
1315
    function get_os_architecture() : int
1316
    {
1317
        switch(PHP_INT_SIZE) {
1318
            case 4:
1319
                return 32;
1320
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1321
            case 8:
1322
                return 64;
1323
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1324
            default:
1325
                return 0;
1326
        }
1327
    }
1328
}
1329
1330
if (!function_exists('is_64bit')) {
1331
    /**
1332
     * Check if the OS architecture is 64bit.
1333
     *
1334
     * @return bool
1335
     *
1336
     * @see http://stackoverflow.com/questions/6303241/find-windows-32-or-64-bit-using-php
1337
     */
1338
    function is_64bit() : bool
0 ignored issues
show
Best Practice introduced by
The function is_64bit() has been defined more than once; this definition is ignored, only the first definition in this file (L1301-1304) is considered.

This check looks for functions that have already been defined in the same file.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
1339
    {
1340
        return PHP_INT_SIZE==8;
1341
    }
1342
}
1343