Completed
Push — master ( 1efa22...d57925 )
by Lorenzo
02:40
created

helpers.php ➔ curl_internal_server_behind_load_balancer()   C

Complexity

Conditions 10
Paths 14

Size

Total Lines 48
Code Lines 34

Duplication

Lines 10
Ratio 20.83 %

Importance

Changes 0
Metric Value
cc 10
eloc 34
nc 14
nop 15
dl 10
loc 48
rs 5.3454
c 0
b 0
f 0

How to fix   Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
    $protocol = 'http://';
259
    if (isHttps()) {
260
        $protocol = 'https://';
261
    }
262
263
    $apiUrl = $protocol . 'www.google.com/s2/favicons?domain=';
264
    if (strpos($url, 'http') !== false) {
265
        $url = str_replace('http://', '', $url);
266
    }
267
    return $apiUrl . $url;
268
}
269
270
/**
271
 * Get a Website favicon image tag.
272
 *
273
 * @param string $url website url
274
 * @param array $attributes Optional, additional key/value attributes to include in the IMG tag
275
 *
276
 * @return string containing complete image tag
277
 * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
278
 */
279
function getFaviconImgTag($url, array $attributes = []) : string
280
{
281
    $urlFav = getFaviconUrl($url);
282
    $attr = arrayToString($attributes);
283
    return '<img src="' . $urlFav . '" ' . trim($attr) . ' />';
284
}
285
286
/**
287
 * Check to see if the current page is being server over SSL or not.
288
 * Support HTTP_X_FORWARDED_PROTO to check ssl over proxy/load balancer.
289
 *
290
 * @return bool
291
 */
292
function isHttps()
293
{
294
    $key = 'HTTPS';
295
    if (isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_X_FORWARDED_PROTO')) {
296
        $key = 'HTTP_X_FORWARDED_PROTO';
297
    }
298
    return isNotNullOrEmptyArrayKey($_SERVER, $key) && strtolower($_SERVER[$key]) !== 'off';
299
}
300
301
/**
302
 * Get a QR code.
303
 *
304
 * @param string $string String to generate QR code for.
305
 * @param int $width QR code width
306
 * @param int $height QR code height
307
 * @param array $attributes Optional, additional key/value attributes to include in the IMG tag
308
 *
309
 * @return string containing complete image tag
310
 * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
311
 */
312
function getQRcode($string, int $width = 150, int $height = 150, array $attributes = []) : string
313
{
314
    $attr = arrayToString($attributes);
315
    $apiUrl = getQRcodeUrl($string, $width, $height);
316
    return '<img src="' . $apiUrl . '" ' . trim($attr) . ' />';
317
}
318
319
/**
320
 * Get a QR code Url.
321
 *
322
 * @param string $string String to generate QR code for.
323
 * @param int $width QR code width
324
 * @param int $height QR code height
325
 *
326
 * @return string containing complete image url
327
 * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
328
 */
329
function getQRcodeUrl($string, int $width = 150, int $height = 150) : string
330
{
331
    $protocol = 'http://';
332
    if (isHttps()) {
333
        $protocol = 'https://';
334
    }
335
    return $protocol . 'chart.apis.google.com/chart?chs=' . $width . 'x' . $height . '&cht=qr&chl=' . urlencode($string);
336
}
337
338
if (!function_exists('gravatarUrl')) {
339
    /**
340
     * Get a Gravatar URL from email.
341
     *
342
     * @param string $email The email address
343
     * @param int $size in pixels, defaults to 80px [ 1 - 2048 ]
344
     * @param string $default imageset to use [ 404 | mm | identicon | monsterid | wavatar ]
345
     * @param string $rating (inclusive) [ g | pg | r | x ]
346
     * @return string
347
     * @source http://gravatar.com/site/implement/images/php/
348
     */
349
    function gravatarUrl($email, $size = 80, $default = 'mm', $rating = 'g')
350
    {
351
        $url = 'http://www.gravatar.com';
352
        if (isHttps()) {
353
            $url = 'https://secure.gravatar.com';
354
        }
355
        $url .= '/avatar.php?gravatar_id=' . md5(strtolower(trim($email))) . '&default=' . $default . '&size=' . $size . '&rating=' . $rating;
356
        return $url;
357
    }
358
}
359
360
if (!function_exists('gravatar')) {
361
    /**
362
     * Get a Gravatar img tag from email.
363
     *
364
     * @param string $email The email address
365
     * @param int $size in pixels, defaults to 80px [ 1 - 2048 ]
366
     * @param string $default imageset to use [ 404 | mm | identicon | monsterid | wavatar ]
367
     * @param string $rating (inclusive) [ g | pg | r | x ]
368
     * @param array $attributes Optional, additional key/value attributes to include in the IMG tag
369
     * @return string
370
     * @source http://gravatar.com/site/implement/images/php/
371
     */
372
    function gravatar($email, $size = 80, $default = 'mm', $rating = 'g', $attributes = [])
373
    {
374
        $attr = arrayToString($attributes);
375
        $url = gravatarUrl($email, $size, $default, $rating);
376
        return '<img src="' . $url . '" width="' . $size . 'px" height="' . $size . 'px" ' . trim($attr) . ' />';
377
    }
378
}
379
380
if (!function_exists('isAjax')) {
381
382
    /**
383
     * Determine if current page request type is ajax.
384
     *
385
     * @return bool
386
     */
387
    function isAjax()
388
    {
389
        return isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_X_REQUESTED_WITH')
390
        && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
391
    }
392
}
393
394
if (!function_exists('isNumberOdd')) {
395
396
    /**
397
     * Check if number is odd.
398
     *
399
     * @param int $num integer to check
400
     *
401
     * @return bool
402
     * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
403
     */
404
    function isNumberOdd($num)
405
    {
406
        return $num % 2 !== 0;
407
    }
408
}
409
410
if (!function_exists('isNumberEven')) {
411
412
    /**
413
     * Check if number is even.
414
     *
415
     * @param int $num integer to check
416
     *
417
     * @return bool
418
     * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
419
     */
420
    function isNumberEven($num)
421
    {
422
        return $num % 2 == 0;
423
    }
424
}
425
426
if (!function_exists('getCurrentUrlPageName')) {
427
428
    /**
429
     * Returns The Current URL PHP File Name.
430
     * Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return index.php
431
     *
432
     * @return string
433
     */
434
    function getCurrentUrlPageName() : string
435
    {
436
        return isNotNullOrEmptyArrayKey($_SERVER, 'PHP_SELF') ? basename($_SERVER['PHP_SELF']) : '';
437
    }
438
}
439
440
if (!function_exists('getCurrentUrlQuerystring')) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
441
442
}
443
/**
444
 * Returns The Current URL querystring.
445
 * Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return one=1&two=2
446
 *
447
 * @return string
448
 */
449
function getCurrentUrlQuerystring() : string
450
{
451
    return isNotNullOrEmptyArrayKey($_SERVER, 'QUERY_STRING') ? $_SERVER['QUERY_STRING'] : '';
452
}
453
454
if (!function_exists('getCurrentUrlDirName')) {
455
456
    /**
457
     * Returns The Current URL Path Name.
458
     * Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return /one/two
459
     *
460
     * @return string
461
     */
462
    function getCurrentUrlDirName() : string
463
    {
464
        if (isNotNullOrEmptyArrayKey($_SERVER, 'REQUEST_URI')) {
465
            return dirname($_SERVER['REQUEST_URI']);
466
        }
467
        return isNotNullOrEmptyArrayKey($_SERVER, 'PHP_SELF') ? dirname($_SERVER['PHP_SELF']) : '';
468
    }
469
}
470
471
if (!function_exists('getCurrentUrlDirAbsName')) {
472
473
    /**
474
     * Returns The Current URL Absolute Path Name.
475
     * Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2 return /home/user/www/one/two
476
     *
477
     * @return string
478
     */
479
    function getCurrentUrlDirAbsName() : string
480
    {
481
        return isNotNullOrEmptyArrayKey($_SERVER, 'SCRIPT_FILENAME') ? dirname($_SERVER['SCRIPT_FILENAME']) : '';
482
    }
483
}
484
485
if (!function_exists('getCurrentURL')) {
486
487
    /**
488
     * Return the current URL.
489
     * Ex.: http://www.dummy.com/one/two/index.php?one=1&two=2
490
     * Or
491
     * Ex.: https://username:[email protected]:443/one/two/index.php?one=1&two=2
492
     * @return string
493
     * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
494
     */
495
    function getCurrentURL()
496
    {
497
        $url = 'http://';
498
        if (isHttps()) {
499
            $url = 'https://';
500
        }
501
        if (array_key_exists_safe($_SERVER, 'PHP_AUTH_USER')) {
502
            $url .= $_SERVER['PHP_AUTH_USER'];
503
            if (array_key_exists_safe($_SERVER, 'PHP_AUTH_PW')) {
504
                $url .= ':' . $_SERVER['PHP_AUTH_PW'];
505
            }
506
            $url .= '@';
507
        }
508
        if (array_key_exists_safe($_SERVER, 'HTTP_HOST')) {
509
            $url .= $_SERVER['HTTP_HOST'];
510
        }
511
        if (array_key_exists_safe($_SERVER, 'SERVER_PORT') && $_SERVER['SERVER_PORT'] != 80) {
512
            $url .= ':' . $_SERVER['SERVER_PORT'];
513
        }
514
        if (!array_key_exists_safe($_SERVER, 'REQUEST_URI')) {
515
            $url .= substr($_SERVER['PHP_SELF'], 1);
516
            if (array_key_exists_safe($_SERVER, 'QUERY_STRING')):
517
                $url .= '?' . $_SERVER['QUERY_STRING'];
518
            endif;
519
        } else {
520
            $url .= $_SERVER['REQUEST_URI'];
521
        }
522
        return $url;
523
    }
524
}
525
526
if (!function_exists('isMobile')) {
527
528
    /**
529
     * Detect if user is on mobile device.
530
     *
531
     * @return bool
532
     */
533
    function isMobile()
534
    {
535
        $useragent = $_SERVER['HTTP_USER_AGENT'];
536
        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',
537
            $useragent)
538
        || 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',
539
            substr($useragent, 0, 4));
540
    }
541
}
542
543
/**
544
 * Get user browser.
545
 *
546
 * @return string
547
 * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
548
 */
549
function getBrowser()
550
{
551
    $u_agent = $_SERVER['HTTP_USER_AGENT'];
552
    $browserName = $ub = $platform = 'Unknown';
553
    if (preg_match('/linux/i', $u_agent)) {
554
        $platform = 'Linux';
555
    } elseif (preg_match('/macintosh|mac os x/i', $u_agent)) {
556
        $platform = 'Mac OS';
557
    } elseif (preg_match('/windows|win32/i', $u_agent)) {
558
        $platform = 'Windows';
559
    }
560
    if (preg_match('/MSIE/i', $u_agent) && !preg_match('/Opera/i', $u_agent)) {
561
        $browserName = 'Internet Explorer';
562
        $ub = 'MSIE';
563
    } elseif (preg_match('/Firefox/i', $u_agent)) {
564
        $browserName = 'Mozilla Firefox';
565
        $ub = 'Firefox';
566
    } elseif (preg_match('/Chrome/i', $u_agent)) {
567
        $browserName = 'Google Chrome';
568
        $ub = 'Chrome';
569
    } elseif (preg_match('/Safari/i', $u_agent)) {
570
        $browserName = 'Apple Safari';
571
        $ub = 'Safari';
572
    } elseif (preg_match('/Opera/i', $u_agent)) {
573
        $browserName = 'Opera';
574
        $ub = 'Opera';
575
    } elseif (preg_match('/Netscape/i', $u_agent)) {
576
        $browserName = 'Netscape';
577
        $ub = 'Netscape';
578
    }
579
    $known = ['Version', $ub, 'other'];
580
    $pattern = '#(?<browser>' . implode('|', $known) . ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
581
    preg_match_all($pattern, $u_agent, $matches);
582
    $i = count($matches['browser']);
583
    if ($i != 1) {
584
        if (strripos($u_agent, 'Version') < strripos($u_agent, $ub)) {
585
            $version = $matches['version'][0];
586
        } else {
587
            $version = $matches['version'][1];
588
        }
589
    } else {
590
        $version = $matches['version'][0];
591
    }
592
    if ($version == null || $version == '') {
593
        $version = '?';
594
    }
595
    return implode(', ', [$browserName, 'Version: ' . $version, $platform]);
596
}
597
598
/**
599
 * Shorten URL via tinyurl.com service.
600
 * It support http or https.
601
 * @param string $url URL to shorten
602
 *
603
 * @return string shortend url or empty string if it fails.
604
 */
605
function getTinyUrl(string $url) : string
606
{
607
    if (!starts_with($url, 'http')) {
608
        $url = (isHttps() ? 'https://' : 'http://') . $url;
609
    }
610
    $gettiny = curl('http://tinyurl.com/api-create.php?url=' . $url);
611
    if (isNullOrEmpty($gettiny) && isNullOrEmptyArray($gettiny)) {
612
        return '';
613
    }
614
    if (isHttps()) {
615
        $gettiny = str_replace('http://', 'https://', $gettiny);
616
    }
617
    return $gettiny;
618
}
619
620
/**
621
 * Get information on a short URL. Find out where it goes.
622
 *
623
 * @param string $shortURL shortened URL
624
 *
625
 * @return string full url or empty string
626
 * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
627
 */
628
function expandShortUrl(string $shortURL) : string
629
{
630
    if (isNullOrEmpty($shortURL)) {
631
        return '';
632
    }
633
    $headers = get_headers($shortURL, 1);
634
    if (array_key_exists_safe($headers, 'Location')) {
635
        return $headers['Location'];
636
    }
637
    $data = curl($shortURL);
638
    preg_match_all('/<[\s]*meta[\s]*http-equiv="?' . '([^>"]*)"?[\s]*' . 'content="?([^>"]*)"?[\s]*[\/]?[\s]*>/si',
639
        $data, $match);
640
    if (isNullOrEmptyArray($match) || count($match) != 3
641
        || isNullOrEmptyArray($match[0]) || isNullOrEmptyArray($match[1]) || isNullOrEmptyArray($match[2])
642
        || count($match[0]) != count($match[1]) || count($match[1]) != count($match[2])
643
    ) {
644
        return '';
645
    }
646
    $originals = $match[0];
647
    $names = $match[1];
648
    $values = $match[2];
649
    $metaTags = [];
650
    for ($i = 0, $limit = count($names); $i < $limit; $i++) {
651
        $metaTags[$names[$i]] = ['html' => htmlentities($originals[$i]), 'value' => $values[$i]];
652
    }
653
    if (!isset($metaTags['refresh']['value']) || empty($metaTags['refresh']['value'])) {
654
        return '';
655
    }
656
    $returnData = explode('=', $metaTags['refresh']['value']);
657
    if (!isset($returnData[1]) || empty($returnData[1])) {
658
        return '';
659
    }
660
    return $returnData[1];
661
}
662
663
if (!function_exists('curl')) {
664
665
    /**
666
     * Make Curl call.
667
     *
668
     * @param string $url URL to curl
669
     * @param string $method GET or POST, Default GET
670
     * @param mixed $data Data to post, Default false
671
     * @param array $headers Additional headers, example: array ("Accept: application/json")
672
     * @param bool $returnInfo Whether or not to retrieve curl_getinfo()
673
     * @param string $user
674
     * @param string $password
675
     * @param bool $sslNotVerifyHostAndPeer is set to true do not check SSL certificate.
676
     * @param bool $followLocation
677
     * @param int $timeout
678
     * @param string $logPath if not empty write log to this file
679
     * @param string $referer
680
     * @param string $userAgent default 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0'
681
     * and ignore $returnInfo (i.e. call curl_getinfo even if $returnInfo is set to false).
682
     *
683
     * @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
684
     * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
685
     */
686
    function curl(
687
        $url,
688
        $method = 'GET',
689
        $data = false,
690
        array $headers = [],
691
        bool $returnInfo = false,
692
        string $user = '',
693
        string $password = '',
694
        bool $sslNotVerifyHostAndPeer = false,
695
        bool $followLocation = false,
696
        int $timeout = 10,
697
        string $logPath = '',
698
        string $referer = '',
699
        string $userAgent = 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0'
700
    ) {
701
        $log = false;
702
        if (isNotNullOrEmpty($logPath)) {
703
            $log = true;
704
            $msg = "REQUEST_URI: " . (isNotNullOrEmptyArrayKey($_SERVER,
705
                    'REQUEST_URI') ? $_SERVER['REQUEST_URI'] : '') . "\r\n"
706
                . "SCRIPT_NAME: " . (isNotNullOrEmptyArrayKey($_SERVER,
707
                    'SCRIPT_NAME') ? $_SERVER['SCRIPT_NAME'] : '') . "\r\n"
708
                . "REMOTE ADDR: " . (isNotNullOrEmptyArrayKey($_SERVER,
709
                    'REMOTE_ADDR') ? $_SERVER['REMOTE_ADDR'] : '') . "\r\n"
710
                . "HTTP_HOST: " . (isNotNullOrEmptyArrayKey($_SERVER,
711
                    'HTTP_HOST') ? $_SERVER['HTTP_HOST'] : '') . "\r\n"
712
                . "SERVER_NAME: " . (isNotNullOrEmptyArrayKey($_SERVER,
713
                    'SERVER_NAME') ? $_SERVER['SERVER_NAME'] : '') . "\r\n"
714
                . "HTTP_X_FORWARDED_FOR: " . (isNotNullOrEmptyArrayKey($_SERVER,
715
                    'HTTP_X_FORWARDED_FOR') ? $_SERVER['HTTP_X_FORWARDED_FOR'] : '') . "\r\n"
716
                . "SERVER_ADDR: " . (isNotNullOrEmptyArrayKey($_SERVER,
717
                    'SERVER_ADDR') ? $_SERVER['SERVER_ADDR'] : '') . "\r\n"
718
                . "REMOTE_PORT: " . (isNotNullOrEmptyArrayKey($_SERVER,
719
                    'REMOTE_PORT') ? $_SERVER['REMOTE_PORT'] : '') . "\r\n"
720
                . "HTTPS: " . (isNotNullOrEmptyArrayKey($_SERVER, 'HTTPS') ? $_SERVER['HTTPS'] : '') . "\r\n"
721
                . "HTTP_X_FORWARDED_PROTO: " . (isNotNullOrEmptyArrayKey($_SERVER,
722
                    'HTTP_X_FORWARDED_PROTO') ? $_SERVER['HTTP_X_FORWARDED_PROTO'] : '') . "\r\n"
723
                . "data: " . get_var_dump_output($data) . "\r\n"
724
                . "headers: " . get_var_dump_output($headers) . "\r\n"
725
                . "returnInfo: " . $returnInfo . "\r\n"
726
                . "url: " . $url . "\r\n"
727
                . "method: " . $method . "\r\n"
728
                . "user: " . $user . "\r\n"
729
                . "password: " . (strlen($password) > 2 ? substr($password, 0, 2) . str_repeat('x',
730
                        10) . substr($password, -1) : 'xx') . "\r\n"
731
                . "sslNotVerifyHostAndPeer: " . $sslNotVerifyHostAndPeer . "\r\n"
732
                . "followLocation: " . $followLocation . "\r\n"
733
                . "timeout: " . $timeout . "\r\n"
734
                . "logPath: " . $logPath . "\r\n"
735
                . "referer: " . $referer . "\r\n"
736
                . "userAgent: " . $userAgent . "\r\n"
737
                . "\r\n";
738
            logToFile($logPath, $msg);
739
        }
740
        if (!function_exists('curl_init') || isNullOrEmpty($url)) {
741
            if ($log) {
742
                logToFile($logPath,
743
                    isNullOrEmpty($url) ? 'url is empty.curl abort.' : 'curl_init not exists.Probabily CURL is not installed.');
744
            }
745
            return '';
746
        }
747
        $ch = curl_init();
748
        $info = null;
749
        if (strtoupper($method) == 'POST') {
750
            curl_setopt($ch, CURLOPT_POST, true);
751
            if ($data !== false) {
752
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
753
            }
754
        } elseif ($data !== false) {
755
            if (is_array($data)) {
756
                $dataTokens = [];
757
                foreach ($data as $key => $value) {
758
                    array_push($dataTokens, urlencode($key) . '=' . urlencode($value));
759
                }
760
                $data = implode('&', $dataTokens);
761
            }
762
            $url .= (strpos($url, '?') === false ? '&' : '?') . $data;
763
        }
764
        curl_setopt($ch, CURLOPT_URL, $url);
765
        curl_setopt($ch, CURLOPT_HEADER, false);
766
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
767
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $followLocation ? true : false);
768
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout <= 1 ? 10 : $timeout);
769
        if ($sslNotVerifyHostAndPeer && starts_with($url, 'https://')) {
770
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
771
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
772
        }
773
        if (isNotNullOrEmptyArray($headers)) {
774
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
775
        }
776
        if (isNotNullOrEmpty($user) && isNotNullOrEmpty($password)) {
777
            curl_setopt($ch, CURLOPT_USERPWD, $user . ':' . $password);
778
        }
779
        if (isNotNullOrEmpty($referer)) {
780
            curl_setopt($ch, CURLOPT_REFERER, $referer);
781
        }
782
        if (isNotNullOrEmpty($userAgent)) {
783
            curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
784
        }
785
786
        if ($log) {
787
            logToFile($logPath, date('Y-m-d H:i:s') . "Start curl\r\n");
788
        }
789
        $contents = curl_exec($ch);
790
        if ($log) {
791
            logToFile($logPath, date('Y-m-d H:i:s') . "FINISH curl\r\n");
792
        }
793
794
        if ($returnInfo || $log || $contents === false || curl_errno($ch) > 0) {
795
            $info = curl_getinfo($ch);
796
            if ($log) {
797
                logToFile($logPath, $info, true);
798
            }
799
        }
800
801
        if ($contents === false || curl_errno($ch) > 0
802
            || !array_key_exists_safe($info === null ? [] : $info, 'http_code') || $info['http_code'] != 200
803
        ) {
804
            if ($log) {
805
                logToFile($logPath, "Error during exec CURL \r\n curl_error: " . curl_error($ch)
806
                    . "\r\n curl_errno: " . curl_errno($ch) . "\r\n");
807
            }
808
        } elseif ($log) {
809
            logToFile($logPath, "CURL IS OK\r\n RESPONSE: \r\n" . $contents);
810
        }
811
812
        curl_close($ch);
813
        return ($returnInfo ? ['contents' => $contents, 'info' => $info] : $contents);
814
    }
815
}
816
817
818
if (!function_exists('curl_internal_server_behind_load_balancer')) {
819
820
    /**
821
     * Make Curl call to one of the server behinds load balancer.
822
     *
823
     * @param string $url URL to curl
824
     * @param string $server_name. The host name of the domain from the call will start.
0 ignored issues
show
Documentation introduced by
There is no parameter named $server_name.. Did you maybe mean $server_name?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
825
     * if empty try to resolve from SERVER_NAME
826
     * @param string $localServerIpAddress the IP of one server to call that behinds load balancer.
827
     * if empty try to resolve from SERVER_ADDR
828
     * @param string $method GET or POST, Default GET
829
     * @param mixed $data Data to post, Default false
830
     * @param array $headers Additional headers, example: array ("Accept: application/json")
831
     * @param bool $returnInfo Whether or not to retrieve curl_getinfo()
832
     * @param string $user
833
     * @param string $password
834
     * @param bool $sslNotVerifyHostAndPeer is set to true do not check SSL certificate.
835
     * @param bool $followLocation
836
     * @param int $timeout
837
     * @param string $logPath if not empty write log to this file
838
     * @param string $referer
839
     * @param string $userAgent default 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0'
840
     * and ignore $returnInfo (i.e. call curl_getinfo even if $returnInfo is set to false).
841
     *
842
     * @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
843
     */
844
    function curl_internal_server_behind_load_balancer(
845
        $url,
846
        $server_name = '',
847
        $localServerIpAddress = '',
848
        $method = 'GET',
849
        $data = false,
850
        array $headers = [],
851
        bool $returnInfo = false,
852
        string $user = '',
853
        string $password = '',
854
        bool $sslNotVerifyHostAndPeer = false,
855
        bool $followLocation = false,
856
        int $timeout = 10,
857
        string $logPath = '',
858
        string $referer = '',
859
        string $userAgent = 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0'
860
    ) {
861
        if (isNullOrEmpty($server_name) && isNotNullOrEmptyArrayKey($_SERVER, 'SERVER_NAME')) {
862
            $server_name = $_SERVER['SERVER_NAME'];
863
        }
864
865 View Code Duplication
        if (isNullOrEmpty($server_name) && isNotNullOrEmpty($logPath)) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
866
            $msg = 'No server name given for calling curl ' . $url . ' behind proxy or LB';
867
            logToFile($logPath, $msg);
868
            return false;
869
        }
870
871
        if (isNullOrEmpty($localServerIpAddress) && isNotNullOrEmptyArrayKey($_SERVER, 'SERVER_ADDR')) {
872
            $localServerIpAddress = $_SERVER['SERVER_ADDR'];
873
        }
874
875 View Code Duplication
        if (isNullOrEmpty($localServerIpAddress) && isNotNullOrEmpty($logPath)) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
876
            $msg = 'No localIPAddress given for calling curl ' . $url . ' behind proxy or LB';
877
            logToFile($logPath, $msg);
878
            return false;
879
        }
880
881
        $url = str_replace($server_name, $localServerIpAddress, $url);
882
883
        //Using the host header to bypass a load balancer
884
        if (!is_array($headers)) {
885
            $headers = array();
886
        }
887
        $headers[] = 'Host: ' . $server_name;
888
889
        return curl($url, $method, $data, $headers, $returnInfo, $user, $password, $sslNotVerifyHostAndPeer,
890
            $followLocation, $timeout, $logPath, $referer, $userAgent);
891
    }
892
}
893
894
if (!function_exists('startLayoutCapture')) {
895
896
    /**
897
     * Turn On the output buffering.
898
     * @return bool
899
     */
900
    function startLayoutCapture() : bool
901
    {
902
        return ob_start();
903
    }
904
}
905
906
if (!function_exists('endLayoutCapture')) {
907
908
    /**
909
     * Get the buffer contents for the topmost buffer and clean it.
910
     * @return string
911
     */
912
    function endLayoutCapture() : string
913
    {
914
        $data = ob_get_contents();
915
        ob_end_clean();
916
        return $data === false ? '' : $data;
917
    }
918
}
919
920
if (!function_exists('get_var_dump_output')) {
921
922
    /**
923
     * Capture var dump $var output and return it.
924
     * @param $var
925
     * @return string
926
     */
927
    function get_var_dump_output($var)
928
    {
929
        startLayoutCapture();
930
        $myfunc = "var_dump";
931
        $myfunc($var);
932
        return endLayoutCapture();
933
    }
934
}
935
936
if (!function_exists('debug')) {
937
938
    /**
939
     * Dump information about a variable.
940
     *
941
     * @param mixed $variable Variable to debug
942
     *
943
     * @return void
944
     * @see https://github.com/ngfw/Recipe/blob/master/src/ngfw/Recipe.php
945
     */
946
    function debug($variable)
947
    {
948
        $output = get_var_dump_output($variable);
949
        $maps = [
950
            'string' => "/(string\((?P<length>\d+)\)) (?P<value>\"(?<!\\\).*\")/i",
951
            'array' => "/\[\"(?P<key>.+)\"(?:\:\"(?P<class>[a-z0-9_\\\]+)\")?(?:\:(?P<scope>public|protected|private))?\]=>/Ui",
952
            'countable' => "/(?P<type>array|int|string)\((?P<count>\d+)\)/",
953
            'resource' => "/resource\((?P<count>\d+)\) of type \((?P<class>[a-z0-9_\\\]+)\)/",
954
            'bool' => "/bool\((?P<value>true|false)\)/",
955
            'float' => "/float\((?P<value>[0-9\.]+)\)/",
956
            'object' => "/object\((?P<class>\S+)\)\#(?P<id>\d+) \((?P<count>\d+)\)/i"
957
        ];
958
        foreach ($maps as $function => $pattern) {
959
            $output = preg_replace_callback($pattern, function ($matches) use ($function) {
960
                switch ($function) {
961
                    case 'string':
962
                        $matches['value'] = htmlspecialchars($matches['value']);
963
                        return '<span style="color: #0000FF;">string</span>(<span style="color: #1287DB;">' . $matches['length'] . ')</span> <span style="color: #6B6E6E;">' . $matches['value'] . '</span>';
964
                    case 'array':
965
                        $key = '<span style="color: #008000;">"' . $matches['key'] . '"</span>';
966
                        $class = '';
967
                        $scope = '';
968
                        if (isset($matches['class']) && !empty($matches['class'])) {
969
                            $class = ':<span style="color: #4D5D94;">"' . $matches['class'] . '"</span>';
970
                        }
971
                        if (isset($matches['scope']) && !empty($matches['scope'])) {
972
                            $scope = ':<span style="color: #666666;">' . $matches['scope'] . '</span>';
973
                        }
974
                        return '[' . $key . $class . $scope . ']=>';
975
                    case 'countable':
976
                        $type = '<span style="color: #0000FF;">' . $matches['type'] . '</span>';
977
                        $count = '(<span style="color: #1287DB;">' . $matches['count'] . '</span>)';
978
                        return $type . $count;
979
                    case 'bool':
980
                        return '<span style="color: #0000FF;">bool</span>(<span style="color: #0000FF;">' . $matches['value'] . '</span>)';
981
                    case 'float':
982
                        return '<span style="color: #0000FF;">float</span>(<span style="color: #1287DB;">' . $matches['value'] . '</span>)';
983
                    case 'resource':
984
                        return '<span style="color: #0000FF;">resource</span>(<span style="color: #1287DB;">' . $matches['count'] . '</span>) of type (<span style="color: #4D5D94;">' . $matches['class'] . '</span>)';
985
                    case 'object':
986
                        return '<span style="color: #0000FF;">object</span>(<span style="color: #4D5D94;">' . $matches['class'] . '</span>)#' . $matches['id'] . ' (<span style="color: #1287DB;">' . $matches['count'] . '</span>)';
987
                }
988
            }, $output);
989
        }
990
        $header = '';
991
        list($debugfile) = debug_backtrace();
992
        if (!empty($debugfile['file'])) {
993
            $header = '<h4 style="border-bottom:1px solid #bbb;font-weight:bold;margin:0 0 10px 0;padding:3px 0 10px 0">' . $debugfile['file'] . '</h4>';
994
        }
995
        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>';
996
    }
997
}
998
999
if (!function_exists('getReferer')) {
1000
1001
    /**
1002
     * Return referer page if exists otherwise return empty string.
1003
     *
1004
     * @return string
1005
     */
1006
    function getReferer() : string
1007
    {
1008
        return isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_REFERER') ? $_SERVER['HTTP_REFERER'] : '';
1009
    }
1010
}
1011
1012
if (!function_exists('isZlibOutputCompressionActive')) {
1013
1014
    /**
1015
     * Check if zlib output compression was active
1016
     * @return bool
1017
     */
1018
    function isZlibOutputCompressionActive() : bool
1019
    {
1020
        return ini_get('zlib.output_compression') == 'On'
1021
        || ini_get('zlib.output_compression_level') > 0
1022
        || ini_get('output_handler') == 'ob_gzhandler';
1023
    }
1024
}
1025
1026
if (!function_exists('isZlibLoaded')) {
1027
1028
    /**
1029
     * Check if zlib extension was loaded
1030
     * @return bool
1031
     */
1032
    function isZlibLoaded() : bool
1033
    {
1034
        return extension_loaded('zlib');
1035
    }
1036
}
1037
1038
if (!function_exists('isClientAcceptGzipEncoding')) {
1039
1040
    /**
1041
     * Check if client accept gzip encoding
1042
     * @return bool
1043
     */
1044
    function isClientAcceptGzipEncoding() : bool
1045
    {
1046
        return isNotNullOrEmptyArrayKey($_SERVER, 'HTTP_ACCEPT_ENCODING')
1047
        && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false;
1048
    }
1049
}
1050
1051
if (!function_exists('compressHtmlPage')) {
1052
1053
    /**
1054
     * Captures output via ob_get_contents(), tries to enable gzip,
1055
     * removes whitespace from captured output and echos back
1056
     *
1057
     * @return string whitespace stripped output
1058
     * @see https://github.com/ngfw/Recipe/
1059
     */
1060
    function compressHtmlPage() : string
1061
    {
1062
        register_shutdown_function(function () {
1063
            $buffer = str_html_compress(ob_get_contents());
1064
            ob_end_clean();
1065
            if (!isZlibOutputCompressionActive() &&
1066
                isClientAcceptGzipEncoding() &&
1067
                isZlibLoaded()
1068
            ) {
1069
                ob_start('ob_gzhandler');
1070
            }
1071
            echo $buffer;
1072
        });
1073
    }
1074
}
1075
1076
if (!function_exists('get_http_response_code')) {
1077
1078
    /**
1079
     * @param string $theURL
1080
     * @param bool $useGet if set to true use a GET request, otherwise use a HEAD request (more fast).
1081
     * @return int return the http status or 999 if it fails.
1082
     */
1083
    function get_http_response_code(string $theURL, bool $useGet = false) : int
1084
    {
1085
        if (isNullOrEmpty($theURL)) {
1086
            return 999;
1087
        }
1088
        if (!$useGet) {
1089
            // By default get_headers uses a GET request to fetch the headers. If you
1090
            // want to send a HEAD request instead, you can do so using a stream context:
1091
            stream_context_set_default(
1092
                array(
1093
                    'http' => array(
1094
                        'method' => 'HEAD'
1095
                    )
1096
                )
1097
            );
1098
        }
1099
        $headers = @get_headers($theURL);
1100
1101
        if ($headers === false || isNullOrEmptyArray($headers) || strlen($headers[0]) < 12) {
1102
            return 999;
1103
        }
1104
        $status = substr($headers[0], 9, 3);
1105
        return isInteger($status) ? $status : 999;
1106
    }
1107
}
1108
1109
if (!function_exists('url_exists')) {
1110
1111
    /**
1112
     * Check if URL exists (return http status code <400
1113
     * @param string $url
1114
     * @return bool
1115
     */
1116
    function url_exists(string $url) : bool
1117
    {
1118
        return get_http_response_code($url) < 400;
1119
    }
1120
}
1121
1122
if (!function_exists('logToFile')) {
1123
1124
    /**
1125
     * Log variable into log file.
1126
     * @param string $pathFile full path with file name.
1127
     * @param mixed $value value to log
1128
     * @param bool $varDump default false. if set to true,
1129
     * grab var dump output of $value and write it to log, otherwise append it to log.
1130
     */
1131
    function logToFile(string $pathFile, $value, bool $varDump = false)
1132
    {
1133
        if ($varDump) {
1134
            $value = get_var_dump_output($value);
1135
        }
1136
        $f = fopen($pathFile, 'a');
1137
        fwrite($f, date(DATE_RFC822) . "\r\n" . $value . "\r\n----------------------------------------------\r\n");
1138
        fclose($f);
1139
    }
1140
}
1141