Passed
Push — master ( 2b7dc8...9b52b9 )
by Lars
03:48
created

Bootup::get_random_bytes()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

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