Passed
Push — master ( c8f5a7...7a8579 )
by Lars
03:43
created

Bootup   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 204
Duplicated Lines 0 %

Test Coverage

Coverage 93.94%

Importance

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