Completed
Push — master ( d0cfcf...43547c )
by Lorenzo
02:02
created

helpers.php ➔ template()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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