Completed
Push — master ( 82ec76...807838 )
by Lars
11:59
created

Bootup::initMbstring()   D

Complexity

Conditions 13
Paths 131

Size

Total Lines 80
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 38
CRAP Score 22.0555

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 80
c 1
b 0
f 0
ccs 38
cts 61
cp 0.623
rs 4.7183
cc 13
eloc 49
nc 131
nop 0
crap 22.0555

How to fix   Long Method    Complexity   

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:

1
<?php
2
3
namespace voku\helper;
4
5
use Patchwork\PHP\Shim\Normalizer;
6
7
/**
8
 * Class Bootup
9
 *
10
 * this is a bootstrap for the polyfills (iconv / intl / mbstring / normalizer / xml)
11
 *
12
 * @package voku\helper
13
 */
14
class Bootup
15
{
16
  /**
17
   * bootstrap
18
   */
19
  public static function initAll()
20
  {
21
    \Patchwork\Utf8\Bootup::initAll();
22
  }
23
24
  /**
25
   * Get random bytes
26
   *
27
   * @ref https://github.com/paragonie/random_compat/
28
   *
29 1
   * @param  int $length Output length
30
   *
31 1
   * @return  string|false false on error
32
   */
33 1
  public static function get_random_bytes($length)
34 1
  {
35 1
    if (!$length) {
36 1
      return false;
37 1
    }
38 1
39 1
    $length = (int)$length;
40 1
41
    if ($length <= 0) {
42
      return false;
43
    }
44
45 1
    return random_bytes($length);
0 ignored issues
show
Unused Code introduced by
The call to random_bytes() has too many arguments starting with $length.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
46
  }
47 1
48 1
  /**
49
   * Determines if the current version of PHP is equal to or greater than the supplied value
50
   *
51
   * @param  string
52
   * @param string $version
53 1
   *
54
   * @return  bool  TRUE if the current version is $version or higher
55 1
   */
56 1
  public static function is_php($version)
57
  {
58
    static $_is_php;
59
60
    $version = (string)$version;
61 1
    if (!isset($_is_php[$version])) {
62
      $_is_php[$version] = version_compare(PHP_VERSION, $version, '>=');
63 1
    }
64 1
65 1
    return $_is_php[$version];
66 1
  }
67
68 1
  /**
69 1
   * filter request-uri
70 1
   *
71
   * @param null $uri
72 1
   * @param bool $exit
73 1
   *
74 1
   * @return bool|mixed|null
75 1
   */
76
  public static function filterRequestUri($uri = null, $exit = true)
0 ignored issues
show
Coding Style introduced by
filterRequestUri uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
77
  {
78 1
    if (!isset($uri)) {
79
      if (!isset($_SERVER['REQUEST_URI'])) {
80
        return false;
81
      } else {
82
        $uri = $_SERVER['REQUEST_URI'];
83 1
      }
84
    }
85 1
86
    // Ensures the URL is well formed UTF-8
87
    // When not, assumes Windows-1252 and redirects to the corresponding UTF-8 encoded URL
88 1
89
    if (!preg_match('//u', urldecode($uri))) {
90 1
      $uri = preg_replace_callback(
91 1
          '/[\x80-\xFF]+/',
92
          function($m) {
93 1
            return urlencode($m[0]);
94 1
          },
95 1
          $uri
96 1
      );
97
98 1
      $uri = preg_replace_callback(
99 1
          '/(?:%[89A-F][0-9A-F])+/i',
100 1
          function($m) {
101
            return urlencode(UTF8::encode('UTF-8', urldecode($m[0])));
102
          },
103
          $uri
104
      );
105
106
      if ($exit === true) {
107
        // Use ob_start() to buffer content and avoid problem of headers already sent...
108
        if (headers_sent() === false) {
109
          $severProtocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1');
110 1
          header($severProtocol . ' 301 Moved Permanently');
111
          header('Location: ' . $uri);
0 ignored issues
show
Security Response Splitting introduced by
'Location: ' . $uri can contain request data and is used in response header context(s) leading to a potential security vulnerability.

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
112
          exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method filterRequestUri() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
113
        }
114
      }
115
    }
116
117 1
    return $uri;
118
  }
119
120
  /**
121 1
   * filter request inputs
122 1
   *
123 1
   * Ensures inputs are well formed UTF-8
124 1
   * When not, assumes Windows-1252 and converts to UTF-8
125
   * Tests only values, not keys
126 1
   *
127
   * @param int    $normalization_form
128
   * @param string $leading_combining
129
   */
130 1
  public static function filterRequestInputs($normalization_form = 4 /* n::NFC */, $leading_combining = '◌')
0 ignored issues
show
Coding Style introduced by
filterRequestInputs uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
filterRequestInputs uses the super-global variable $_ENV which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
filterRequestInputs uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
filterRequestInputs uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
filterRequestInputs uses the super-global variable $_COOKIE which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
filterRequestInputs uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
filterRequestInputs uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
131 1
  {
132 1
    $a = array(
133
        &$_FILES,
134 1
        &$_ENV,
135 1
        &$_GET,
136
        &$_POST,
137 1
        &$_COOKIE,
138 1
        &$_SERVER,
139 1
        &$_REQUEST,
140
    );
141 1
142 1
    foreach ($a[0] as &$r) {
143
      $a[] = array(
144
          &$r['name'],
145
          &$r['type'],
146 1
      );
147 1
    }
148
    unset($r);
149 1
    unset($a[0]);
150 1
151 1
    $len = count($a) + 1;
152
    for ($i = 1; $i < $len; ++$i) {
153 1
      foreach ($a[$i] as &$r) {
154 1
        $s = $r; // $r is a ref, $s a copy
155
        if (is_array($s)) {
156
          $a[$len++] = & $r;
157 1
        } else {
158
          $r = self::filterString($s, $normalization_form, $leading_combining);
159
        }
160
      }
161
      unset($r);
162 1
      unset($a[$i]);
163
    }
164
  }
165
166
  /**
167 1
   * @param        $s
168
   * @param int    $normalization_form
169 1
   * @param string $leading_combining
170 1
   *
171 1
   * @return array|bool|mixed|string
172 1
   */
173
  public static function filterString($s, $normalization_form = 4 /* n::NFC */, $leading_combining = '◌')
174 1
  {
175 View Code Duplication
    if (false !== strpos($s, "\r")) {
0 ignored issues
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...
176
      // Workaround https://bugs.php.net/65732
177 1
      $s = str_replace(array("\r\n", "\r"), "\n", $s);
178 1
    }
179
180 View Code Duplication
    if (preg_match('/[\x80-\xFF]/', $s)) {
0 ignored issues
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...
181
      if (Normalizer::isNormalized($s, $normalization_form)) {
182
        $n = '-';
183 1
      } else {
184
        $n = Normalizer::normalize($s, $normalization_form);
185 1
        if (isset($n[0])) {
186
          $s = $n;
187
        } else {
188
          $s = UTF8::encode('UTF-8', $s);
189 1
        }
190
      }
191 1
192
      if ($s[0] >= "\x80" && isset($n[0], $leading_combining[0]) && preg_match('/^\p{Mn}/u', $s)) {
193
        // Prevent leading combining chars
194
        // for NFC-safe concatenations.
195
        $s = $leading_combining . $s;
196
      }
197 1
    }
198
199
    return $s;
200
  }
201
}
202