Passed
Push — master ( b2052d...98cca6 )
by Lars
03:19
created

Bootup   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 198
Duplicated Lines 0 %

Test Coverage

Coverage 93.94%

Importance

Changes 0
Metric Value
eloc 64
dl 0
loc 198
ccs 62
cts 66
cp 0.9394
rs 10
c 0
b 0
f 0
wmc 19

6 Methods

Rating   Name   Duplication   Size   Complexity  
A filterRequestInputs() 0 36 5
A get_random_bytes() 0 13 3
A is_php() 0 11 2
A initAll() 0 3 1
A filterString() 0 3 1
B filterRequestUri() 0 65 7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace voku\helper;
6
7
class Bootup
8
{
9
    /**
10
     * filter request inputs
11
     *
12
     * Ensures inputs are well formed UTF-8
13
     * When not, assumes Windows-1252 and converts to UTF-8
14
     * Tests only values, not keys
15
     *
16
     * @param int    $normalization_form
17
     * @param string $leading_combining
18
     *
19
     * @return void
20
     */
21 1
    public static function filterRequestInputs($normalization_form = \Normalizer::NFC, $leading_combining = '◌')
22
    {
23
        $a = [
24 1
            &$_FILES,
25 1
            &$_ENV,
26 1
            &$_GET,
27 1
            &$_POST,
28 1
            &$_COOKIE,
29 1
            &$_SERVER,
30 1
            &$_REQUEST,
31
        ];
32
33
        /** @noinspection ReferenceMismatchInspection */
34
        /** @noinspection ForeachSourceInspection */
35 1
        foreach ($a[0] as &$r) {
36 1
            $a[] = [
37 1
                &$r['name'],
38 1
                &$r['type'],
39
            ];
40
        }
41 1
        unset($r, $a[0]);
42
43 1
        $len = \count($a) + 1;
44 1
        for ($i = 1; $i < $len; ++$i) {
45
            /** @noinspection ReferenceMismatchInspection */
46
            /** @noinspection ForeachSourceInspection */
47 1
            foreach ($a[$i] as &$r) {
48
                /** @noinspection ReferenceMismatchInspection */
49 1
                $s = $r; // $r is a reference, $s a copy
50 1
                if (\is_array($s)) {
51 1
                    $a[$len++] = &$r;
52
                } else {
53 1
                    $r = self::filterString($s, $normalization_form, $leading_combining);
54
                }
55
            }
56 1
            unset($r, $a[$i]);
57
        }
58 1
    }
59
60
    /**
61
     * Filter current REQUEST_URI .
62
     *
63
     * @param string|null $uri <p>If null is set, then the server REQUEST_URI will be used.</p>
64
     * @param bool        $exit
65
     *
66
     * @return mixed
67
     */
68 1
    public static function filterRequestUri($uri = null, $exit = true)
69
    {
70 1
        if ($uri === null) {
71 1
            if (!isset($_SERVER['REQUEST_URI'])) {
72 1
                return false;
73
            }
74
75 1
            $uri = (string)$_SERVER['REQUEST_URI'];
76
        }
77
78 1
        $uriOrig = $uri;
79
80
        //
81
        // Ensures the URL is well formed UTF-8
82
        //
83
84 1
        if (UTF8::is_utf8(\rawurldecode($uri)) === true) {
85 1
            return $uri;
86
        }
87
88
        //
89
        // When not, assumes Windows-1252 and redirects to the corresponding UTF-8 encoded URL
90
        //
91
92 1
        $uri = (string)\preg_replace_callback(
93 1
            '/[\x80-\xFF]+/',
94
            /**
95
             * @param array $m
96
             *
97
             * @return string
98
             */
99
            static function (array $m): string {
100 1
                return \rawurlencode($m[0]);
101 1
            },
102 1
            $uri
103
        );
104
105 1
        $uri = (string)\preg_replace_callback(
106 1
            '/(?:%[89A-F][0-9A-F])+/i',
107
            /**
108
             * @param array $m
109
             *
110
             * @return string
111
             */
112
            static function (array $m): string {
113 1
                return \rawurlencode(UTF8::rawurldecode($m[0]));
114 1
            },
115 1
            $uri
116
        );
117
118
        if (
119 1
            $uri !== $uriOrig
120
            &&
121 1
            $exit === true
122
            &&
123 1
            \headers_sent() === false
124
        ) {
125
            // Use ob_start() to buffer content and avoid problem of headers already sent...
126
            $severProtocol = ($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1');
127
            \header($severProtocol . ' 301 Moved Permanently');
128
            \header('Location: ' . $uri);
129
            exit();
130
        }
131
132 1
        return $uri;
133
    }
134
135
    /**
136
     * Normalizes to UTF-8 NFC, converting from WINDOWS-1252 when needed.
137
     *
138
     * @param mixed  $input
139
     * @param int    $normalization_form
140
     * @param string $leading_combining
141
     *
142
     * @return mixed
143
     */
144 1
    public static function filterString($input, int $normalization_form = \Normalizer::NFC, string $leading_combining = '◌')
145
    {
146 1
        return UTF8::filter($input, $normalization_form, $leading_combining);
147
    }
148
149
    /**
150
     * Get random bytes via "random_bytes()"
151
     *
152
     * @param int $length <p>output length</p>
153
     *
154
     * @return false|string
155
     *                      <strong>false</strong> on error
156
     * @throws \Exception if it was not possible to gather sufficient entropy
157
     *
158
     */
159 1
    public static function get_random_bytes($length)
160
    {
161 1
        if (!$length) {
162 1
            return false;
163
        }
164
165 1
        $length = (int)$length;
166
167 1
        if ($length <= 0) {
168 1
            return false;
169
        }
170
171 1
        return \random_bytes($length);
172
    }
173
174
    /**
175
     * bootstrap
176
     *
177
     * @return void
178
     */
179 1
    public static function initAll()
180
    {
181 1
        \ini_set('default_charset', 'UTF-8');
182
183
        // everything is init via composer, so we are done here ...
184 1
    }
185
186
    /**
187
     * Determines if the current version of PHP is equal to or greater than the supplied value.
188
     *
189
     * @param string $version <p>e.g. "7.1"<p>
190
     *
191
     * @return bool
192
     *              Return <strong>true</strong> if the current version is $version or higher
193
     */
194 11
    public static function is_php($version): bool
195
    {
196 11
        static $_IS_PHP;
197
198 11
        $version = (string)$version;
199
200 11
        if (!isset($_IS_PHP[$version])) {
201 3
            $_IS_PHP[$version] = \version_compare(\PHP_VERSION, $version, '>=');
202
        }
203
204 11
        return $_IS_PHP[$version];
205
    }
206
}
207