router   A
last analyzed

Complexity

Total Complexity 42

Size/Duplication

Total Lines 243
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 42
eloc 90
dl 0
loc 243
rs 9.0399
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A is_post() 0 7 2
A redirect() 0 3 1
A is_production() 0 3 1
A is_header() 0 5 2
A is_reqs() 0 5 3
A is_hard_reload() 0 3 2
A get_env() 0 13 4
A is_req() 0 7 2
A no_direct() 0 5 2
B findRoute() 0 29 10
A GUID() 0 7 2
A __construct() 0 3 1
B environtment() 0 35 6
A config() 0 3 1
A safe_redirect() 0 35 3

How to fix   Complexity   

Complex Class

Complex classes like router often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use router, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace MVC;
4
5
$GLOBALS['router_state'] = [];
6
7
class router extends themes
8
{
9
  public $root;
10
  public $PHP_ERROR_FILE = PHP_ERROR_FILE;
11
12
  public function __construct()
13
  {
14
    parent::__construct();
15
  }
16
17
  /**
18
   * Safe redirect, support any conditions.
19
   */
20
  public static function safe_redirect(string $path)
21
  {
22
    if (ob_get_level()) {
23
      ob_end_clean();
24
    }
25
    ob_start();
26
    header('HTTP/1.1 503 Service Unavailable');
27
    header('Status: 503 Service Unavailable');
28
    header('Retry-After: 3600');
29
    header("refresh:5; url=$path");
30
31
    if (!headers_sent()) {
32
      header("Location: $path", true, 302);
33
    } else {
34
      echo '<!DOCTYPE html>
35
      <html>
36
37
      <head>
38
        <title>Temporarily Unavailable</title>
39
        <meta name="robots" content="none" />
40
        <meta http-equiv="refresh" content="5; url=' . $path . '" />
41
      </head>
42
43
      <body>
44
        You will redirected automatically
45
      </body>
46
      <script>
47
        location.href = `' . $path . '`;
48
        document.body.innerHTML = "";
49
        throw "";
50
      </script>
51
52
      </html>';
53
    }
54
    exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
55
  }
56
57
  public function redirect(string $path)
58
  {
59
    return self::safe_redirect($path);
0 ignored issues
show
Bug introduced by
Are you sure the usage of self::safe_redirect($path) targeting MVC\router::safe_redirect() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
60
  }
61
62
  public function no_direct()
63
  {
64
    if (1 == count(get_included_files())) {
65
      header('Location: /'); // Send to index
66
      die('403'); // Must include to stop PHP from continuing
67
    }
68
  }
69
70
  public $env;
71
72
  /**
73
   * Define environtment
74
   * * development / production.
75
   *
76
   * @return string
77
   */
78
  public function environtment($env = 'production')
79
  {
80
    $env = strtolower($env); //$GLOBALS['router']['env']
81
    switch ($env) {
82
      case 'development':
83
        //error_reporting(-1);
84
        ini_set('display_errors', 1);
85
        ini_set('display_startup_errors', 1);
86
        error_reporting(E_ALL);
87
        ini_set('log_errors', 1);
88
        ini_set('error_log', \Filemanager\file::file($this->PHP_ERROR_FILE, ''));
0 ignored issues
show
Bug introduced by
'' of type string is incompatible with the type boolean expected by parameter $create of Filemanager\file::file(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

88
        ini_set('error_log', \Filemanager\file::file($this->PHP_ERROR_FILE, /** @scrutinizer ignore-type */ ''));
Loading history...
89
        break;
90
91
      case 'production':
92
        ini_set('display_errors', 0);
93
        if (version_compare(PHP_VERSION, '5.3', '>=')) {
94
          error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
95
        } else {
96
          error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE);
97
        }
98
        break;
99
    }
100
    if (empty($env)) {
101
      if (ob_get_level()) {
102
        ob_end_clean();
103
      }
104
      header('HTTP/1.1 503 Service Unavailable.', true, 503);
105
      echo 'The application environment is not set correctly.';
106
      exit(1); // EXIT_ERROR
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
107
    }
108
109
    file_put_contents(ROOT . '/tmp/environtment.txt', $env, true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type integer expected by parameter $flags of file_put_contents(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

109
    file_put_contents(ROOT . '/tmp/environtment.txt', $env, /** @scrutinizer ignore-type */ true);
Loading history...
110
    $GLOBALS['router_state']['env'] = $this->env = $env;
111
112
    return $env;
113
  }
114
115
  public function is_production()
116
  {
117
    return 'production' == $this->get_env();
118
  }
119
120
  private static $env_status = null;
121
122
  /**
123
   * Get framework environtment.
124
   *
125
   * @return string
126
   */
127
  public static function get_env()
128
  {
129
    if (isset($GLOBALS['router_state']['env'])) {
130
      return $GLOBALS['router_state']['env'];
131
    }
132
    if (!self::$env_status) {
133
      self::$env_status = \Filemanager\file::get(\Filemanager\file::tmp() . '/environtment.txt');
134
    }
135
    if (!self::$env_status) {
136
      \Cookie\helper::del('environtment');
137
    }
138
139
    return self::$env_status;
140
  }
141
142
  public function is_req($any, $alternative = null)
143
  {
144
    if (isset($_REQUEST[(string) $any])) {
145
      return $_REQUEST[(string) $any];
146
    }
147
148
    return $alternative;
149
  }
150
151
  /**
152
   * check if one of the headers exists.
153
   *
154
   * ```php
155
   * if ($this->is_reqs(['DNT', 'Connection']))
156
   * ```
157
   *
158
   * @param array $anys
159
   *
160
   * @return bool|string
161
   */
162
  public function is_reqs(array $anys)
163
  {
164
    foreach ($anys as $any) {
165
      if (isset($_REQUEST[(string) $any])) {
166
        return $_REQUEST[(string) $any];
167
      }
168
    }
169
  }
170
171
  public function is_post($any, $alternative = null)
172
  {
173
    if (isset($_POST[(string) $any])) {
174
      return $_POST[(string) $any];
175
    }
176
177
    return $alternative;
178
  }
179
180
  /**
181
   * Check if header request has $any.
182
   *
183
   * @param string $any
184
   *
185
   * @return string|null
186
   */
187
  public function is_header(string $any)
188
  {
189
    $allHeaders = getallheaders();
190
191
    return array_key_exists($any, $allHeaders) ? $allHeaders[$any] : null;
0 ignored issues
show
Bug introduced by
It seems like $allHeaders can also be of type true; however, parameter $array of array_key_exists() does only seem to accept ArrayObject|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

191
    return array_key_exists($any, /** @scrutinizer ignore-type */ $allHeaders) ? $allHeaders[$any] : null;
Loading history...
192
  }
193
194
  /**
195
   * Check browser no-cache request (hard reload)
196
   *
197
   * @return boolean
198
   */
199
  public function is_hard_reload()
200
  {
201
    return $this->is_header('Cache-Control') == 'no-cache' && $this->is_header('Pragma') == 'no-cache';
202
  }
203
204
  /**
205
   * Find router from parameter URL.
206
   */
207
  public function findRoute()
208
  {
209
    $route = strtok($_SERVER['REQUEST_URI'], '?');
210
    if (empty($route) || preg_match('/^\//s', $route)) {
211
      $re = preg_replace('/^\//s', '', $route);
212
      $router = $re;
213
      if ($re) {
214
        if (!$re || empty($re)) {
215
          $router = 'index';
216
        } elseif (preg_match('/\/$/', $re)) {
217
          $router .= 'index';
218
        }
219
      }
220
      if (empty($re)) {
221
        $router .= 'index';
222
      }
223
    }
224
225
    if (empty($router)) {
226
      exit(var_dump($router, $re));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $router does not seem to be defined for all execution paths leading up to this point.
Loading history...
Bug introduced by
Are you sure the usage of var_dump($router, $re) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
Security Debugging Code introduced by
var_dump($router, $re) looks like debug code. Are you sure you do not want to remove it?
Loading history...
Comprehensibility Best Practice introduced by
The variable $re does not seem to be defined for all execution paths leading up to this point.
Loading history...
227
    }
228
229
    if (is_dir($router)) {
230
      echo 'Unable access';
231
232
      return;
233
    }
234
235
    return $router;
236
  }
237
238
  public function config($router)
239
  {
240
    return helper::platformSlashes($this->view . '/' . $router);
241
  }
242
243
  public function GUID()
244
  {
245
    if (true === function_exists('com_create_guid')) {
246
      return trim(com_create_guid(), '{}');
247
    }
248
249
    return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
250
  }
251
}
252