Passed
Branch master (8a6de3)
by Henri
02:08 queued 48s
created

Router   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 241
Duplicated Lines 0 %

Importance

Changes 22
Bugs 0 Features 1
Metric Value
eloc 109
c 22
b 0
f 1
dl 0
loc 241
rs 8.96
wmc 43

17 Methods

Rating   Name   Duplication   Size   Complexity  
A post() 0 3 1
A ajax() 0 3 1
A add() 0 3 1
A get() 0 3 1
A form() 0 3 1
A getInstance() 0 4 2
A __construct() 0 3 1
A create() 0 9 2
A any() 0 6 1
A set() 0 24 5
A group() 0 9 2
A filter() 0 21 4
A addFilter() 0 19 5
A name() 0 21 4
A byName() 0 17 3
A where() 0 9 2
B dispatch() 0 41 7

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 HnrAzevedo\Router;
4
5
use Exception;
6
7
class Router{
8
    use Helper, CheckTrait, CheckWhere;
9
10
    private static $instance = null;
11
    private array $routers = [];
12
    private ?string $prefix = null;
13
    private $group = false;
14
    private $lastReturn = null;
15
    private bool $instanced = false;
16
17
    public function __construct()
18
    {
19
        return $this;
20
    }
21
22
    public static function create(): Router
23
    {
24
        if(!self::getInstance()->instanced){
25
            self::getInstance()->checkConfig();
26
            self::getInstance()->import(ROUTER_CONFIG['path']);
27
            self::getInstance()->instanced = true;
28
        }
29
        
30
        return self::getInstance();
31
    }
32
33
    public static function getInstance(): Router
34
    {
35
        self::$instance = (is_null(self::$instance)) ? new self() : self::$instance;
36
        return self::$instance;
37
    }
38
39
    public static function any(string $uri, $walking): Router
40
    {
41
        self::getInstance()->add($uri, $walking, 'get');
42
        self::getInstance()->add($uri, $walking, 'post');
43
        self::getInstance()->add($uri, $walking, 'form');
44
        return self::getInstance()->add($uri, $walking, 'ajax');
45
    }
46
47
    public static function get(string $uri, $walking): Router
48
    {
49
        return self::getInstance()->add($uri, $walking, 'get');
50
    }
51
52
    public static function post(string $uri, $walking): Router
53
    {
54
        return self::getInstance()->add($uri, $walking, 'post');
55
    }
56
57
    public static function ajax(string $uri, $walking): Router
58
    {
59
        return self::getInstance()->add($uri, $walking, 'ajax');
60
    }
61
62
    public static function form(string $uri, $walking): Router
63
    {
64
        return self::getInstance()->add($uri, $walking, 'form');
65
    }
66
67
    public static function add(string $uri, $walking, string $protocol): Router
68
    {
69
        return self::getInstance()->set($uri, $walking, $protocol);
70
    }
71
72
    public function set($url ,$walking , string $protocol): Router
73
    {
74
		$url = (substr($url,0,1) !=='/' and strlen($url) > 0) ? "/{$url}" : $url;
75
76
    	foreach($this->routers as $key => $value){
77
    		if( md5($this->prefix . $value['url'] . $value['protocol'] ) === md5( $url . $protocol ) ){
78
                throw new Exception("There is already a route with the url {$url} and with the {$protocol} protocol configured.");
79
            }
80
        }
81
        
82
        $this->checkTypeRole($walking);
83
84
		$route = [
85
			'url' => $this->prefix.$url,
86
			'role' => $walking,
87
			'protocol' => $protocol,
88
            'filters' => null,
89
            'where' => null,
90
            'group' => self::getInstance()->group
91
		];
92
93
		$this->routers[] = $route;		
94
        
95
        return self::getInstance();
96
    }
97
98
    public static function group(string $prefix,$callback): Router
99
    {
100
        self::getInstance()->prefix = (substr($prefix,0,1) !== '/') ? "/{$prefix}" : $prefix;
101
        self::getInstance()->group = sha1(date('d/m/Y h:m:i'));
102
        $callback();
103
        self::getInstance()->group = null;
104
        self::getInstance()->prefix = null;
105
        self::getInstance()->lastReturn = true;
106
        return self::getInstance();
107
    }
108
109
    public static function where(): Router
110
    {
111
        if(self::getInstance()->lastReturn){
112
            throw new Exception("It is not possible to define parameter tests for groups of routes.");
113
        }
114
115
        self::getInstance()->callWhereAdd(func_get_args());
116
117
        return self::getInstance();
118
    }
119
120
    public static function name(string $name): Router
121
    {
122
        if(self::getInstance()->lastReturn){
123
            throw new Exception("There is no reason to call a {$name} route group.");
124
        }
125
126
        $currentRoute = end(self::getInstance()->routers);
127
128
        foreach(self::getInstance()->routers as $key => $value){
129
            if(array_key_exists($name, self::getInstance()->routers)){
130
                throw new Exception("There is already a route with the name {$name} configured.");
131
            }
132
        }
133
134
        $currentRoute['name'] = $name;
135
136
        self::getInstance()->routers[count(self::getInstance()->routers)-1] = $currentRoute;
137
138
        self::getInstance()->lastReturn = null;
139
140
        return self::getInstance();
141
    }
142
143
    private function byName(?string $routName)
144
    {
145
        if(!is_null($routName)){
146
            $currentProtocol = $this->getProtocol();
147
148
            $this->checkName($routName);
149
    
150
            $route = $this->routers[$routName];
151
    
152
            if(!$this->checkProtocol($route['protocol'], $currentProtocol)){
153
                throw new Exception('Page not found.',404);
154
            }
155
    
156
            $this->checkFiltering($route);
157
    
158
            $this->toHiking($route['role']);
159
            throw true;
160
        }
161
    }
162
163
    public static function dispatch(?string $routeName = null): bool
164
    {
165
        $instance = self::create();
166
167
        $instance->getInstance()->byName($routeName);
168
169
		$currentProtocol = $instance->getInstance()->getProtocol();
170
171
        foreach(array_reverse($instance->getInstance()->routers) as $r => $route){
172
173
            $instance->getInstance()->currentRoute = $route;
174
175
            if(!$instance->getInstance()->checkProtocol($route['protocol'], $currentProtocol)){
176
                continue;
177
            }
178
179
            $instance->getInstance()->hasProtocol($route, $currentProtocol);
180
181
            $routeLoop = $instance->getInstance()->explodeRoute( (substr($route['url'],strlen($route['url'])-1,1) === '/') , $route['url']);
182
            
183
            $_SERVER['REQUEST_URI'] = (array_key_exists('REQUEST_URI', $_SERVER)) ? $_SERVER['REQUEST_URI'] : '';
184
185
            $routeRequest = $instance->getInstance()->explodeRoute((substr($_SERVER['REQUEST_URI'],strlen($_SERVER['REQUEST_URI'])-1,1) === '/') , $_SERVER['REQUEST_URI']);
186
187
	        if($instance->getInstance()->checkNumparams($routeLoop, $routeRequest) || !$instance->getInstance()->checkParameters($routeLoop, $routeRequest)){
188
                continue;
189
            }
190
191
            if($instance->getInstance()->checkWhere($route, $routeRequest)){
192
193
                $instance->getInstance()->checkFiltering($route);
194
195
                $instance->getInstance()->toHiking($route['role']);
196
                return true;
197
            }
198
            
199
        }
200
        
201
        $instance->getInstance()->currentRoute = null;
202
203
	    throw new Exception('Page not found.',404);
204
    }
205
206
    public static function filter($filters): Router
207
    {
208
        if(self::getInstance()->lastReturn !== null){
209
            $currentGroup = end(self::getInstance()->routers)['group'];
210
211
            foreach (self::getInstance()->routers as $key => $value) {
212
213
                if($value['group'] === $currentGroup){
214
                    $currentRoute = self::getInstance()->addFilter(self::getInstance()->routers[$key],$filters);
215
                    self::getInstance()->routers[$key] = $currentRoute;
216
                }
217
218
            }
219
220
            self::getInstance()->lastReturn = null;
221
            
222
            return self::getInstance();
223
        }
224
        
225
        self::getInstance()->routers[count(self::getInstance()->routers)-1] = self::getInstance()->addFilter(end(self::getInstance()->routers),$filters);
226
        return self::getInstance();
227
    }
228
229
    public static function addFilter(array $route, $filter): array
230
    {
231
        if(is_null($route['filters'])){
232
            $route['filters'] = $filter;
233
            return $route;
234
        }
235
236
        $filters = (is_array($filter)) ? $filter : [0 => $filter];
237
238
        if(is_array($route['filters'])){
239
            foreach ($route['filters'] as $key => $value) {
240
                $filters[] = $value;
241
            }
242
        }else{
243
            $filters[] = $route['filters'];
244
        }
245
246
        $route['filters'] = $filters;
247
        return $route;
248
    }
249
250
}
251