Passed
Branch master (3f372a)
by Henri
02:05 queued 52s
created

Router   A

Complexity

Total Complexity 38

Size/Duplication

Total Lines 219
Duplicated Lines 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 101
c 6
b 0
f 0
dl 0
loc 219
rs 9.36
wmc 38

15 Methods

Rating   Name   Duplication   Size   Complexity  
A set() 0 21 5
A getInstance() 0 4 2
A post() 0 3 1
A name() 0 22 4
A ajax() 0 3 1
A add() 0 3 1
A get() 0 3 1
A __construct() 0 3 1
A form() 0 3 1
A group() 0 9 2
A create() 0 5 1
A filter() 0 19 4
A addFilter() 0 19 5
A byName() 0 15 2
B dispatch() 0 45 7
1
<?php
2
3
namespace HnrAzevedo\Router;
4
5
use Exception;
6
7
class Router{
8
    use Helper, CheckTrait;
9
10
    private static $instance = null;
11
    private array $routers = [];
12
    private ?string $prefix = null;
13
    private $protocol = null;
0 ignored issues
show
introduced by
The private property $protocol is not used, and could be removed.
Loading history...
14
    private $filtersSet = null;
0 ignored issues
show
introduced by
The private property $filtersSet is not used, and could be removed.
Loading history...
15
    private $filter = null;
0 ignored issues
show
introduced by
The private property $filter is not used, and could be removed.
Loading history...
16
    private $group = false;
17
    private $lastReturn = null;
18
19
    public function __construct()
20
    {
21
        return $this;
22
    }
23
24
    public static function create(): Router
25
    {
26
        self::getInstance()->check_config();
27
        self::getInstance()->import(ROUTER_CONFIG['path']);
28
        return self::getInstance();
29
    }
30
31
    public static function getInstance(): Router
32
    {
33
        self::$instance = (is_null(self::$instance)) ? new self() : self::$instance;
34
        return self::$instance;
35
    }
36
37
    public static function form(string $uri, string $controll): Router
38
    {
39
        return self::getInstance()->add($uri, $controll, 'form');
40
    }
41
42
    public static function get(string $uri, string $controll): Router
43
    {
44
        return self::getInstance()->add($uri, $controll, 'get');
45
    }
46
47
    public static function post(string $uri, string $controll): Router
48
    {
49
        return self::getInstance()->add($uri, $controll, 'post');
50
    }
51
52
    public static function ajax(string $uri, string $controll): Router
53
    {
54
        return self::getInstance()->add($uri, $controll, 'ajax');
55
    }
56
57
    public static function add(string $uri, string $controll, string $protocol): Router
58
    {
59
        return self::getInstance()->set($uri, $controll, $protocol);
60
    }
61
62
    public function set($url , $role , $protocol = null): Router
63
    {
64
		$url = (substr($url,0,1) !=='/' and strlen($url) > 0) ? "/{$url}" : $url;
65
66
    	foreach($this->routers as $key => $value){
67
    		if( md5($this->prefix . $value['url'] . $value['protocol'] ) === md5( $url . $protocol ) ){
68
                throw new Exception("There is already a route with the url {$url} and with the {$protocol} protocol configured.");
69
            }
70
    	}
71
72
		$route = [
73
			'url' => $this->prefix.$url,
74
			'role' => $role,
75
			'protocol' => $protocol,
76
			'filters' => null,
77
            'group' => self::getInstance()->group
78
		];
79
80
		$this->routers[] = $route;		
81
        
82
        return self::getInstance();
83
    }
84
85
    public static function group(string $prefix,$callback): Router
86
    {
87
        self::getInstance()->prefix = (substr($prefix,0,1) !== '/') ? "/{$prefix}" : $prefix;
88
        self::getInstance()->group = sha1(date('d/m/Y h:m:i'));
89
        $callback();
90
        self::getInstance()->group = null;
91
        self::getInstance()->prefix = null;
92
        self::getInstance()->lastReturn = true;
93
        return self::getInstance();
94
    }
95
96
    public static function name(string $name): Router
97
    {
98
99
        if(self::getInstance()->lastReturn){
100
            throw new Exception("There is no reason to call a {$name} route group.");
101
        }
102
103
        $currentRoute = end(self::getInstance()->routers);
104
105
        foreach(self::getInstance()->routers as $key => $value){
106
            if(array_key_exists($name, self::getInstance()->routers)){
107
                throw new Exception("There is already a route with the name {$name} configured.");
108
            }
109
        }
110
111
        $currentRoute['name'] = $name;
112
113
        self::getInstance()->routers[count(self::getInstance()->routers)-1] = $currentRoute;
114
115
        self::getInstance()->lastReturn = null;
116
117
        return self::getInstance();
118
    }
119
120
    private function byName(?string $route_name)
121
    {
122
        if(!is_null($route_name)){
123
            $currentProtocol = $this->getProtocol();
124
125
            $this->check_name($route_name);
126
    
127
            $route = $this->routers[$route_name];
128
    
129
            $this->check_protocol($route['protocol'], $currentProtocol);
130
    
131
            $this->check_filtering($route);
132
    
133
            $this->Controller($route['role']);
134
            throw true;
135
        }
136
        
137
    }
138
139
    public function dispatch(?string $route_name = null): bool
140
    {
141
        $this->byName($route_name);
142
143
		$currentProtocol = $this->getProtocol();
144
145
        foreach(array_reverse($this->routers) as $r => $route){
146
147
            $this->hasProtocol($route, $currentProtocol);
148
149
	        $route_loop = explode(
150
                '/',
151
                (substr($route['url'],strlen($route['url'])-1,1) === '/') 
152
                    ? substr($route['url'], 0, -1) 
153
                    : $route['url'] 
154
            );
155
156
            $route_request = explode(
157
                '/',
158
                (substr($_SERVER['REQUEST_URI'],strlen($_SERVER['REQUEST_URI'])-1,1) === '/') 
159
                ? substr($_SERVER['REQUEST_URI'], 0, -1) 
160
                : $_SERVER['REQUEST_URI'] 
161
            );
162
163
	        if($this->check_numparams($route_loop, $route_request)){
164
                continue;
165
            }
166
167
            foreach($route_loop as $rr => $param){
168
                //if( (substr($param,0,1) === '{') ){
169
                //    $data[ substr($param,1,strlen($param)-2) ] = $route_request[$rr];    
170
                //}
171
172
	            if($this->check_parameter($param, $route_request[$rr])){
173
                    continue 2;
174
                }
175
            }
176
            
177
            $this->check_filtering($route);
178
179
            $this->Controller($route['role']);
180
	        return true;
181
	    }
182
183
	    throw new Exception('Page not found.',404);
184
    }
185
186
    public static function filter($filters): Router
187
    {
188
        if(self::getInstance()->lastReturn !== null){
189
            $currentGroup = end(self::getInstance()->routers)['group'];
190
191
            foreach (self::getInstance()->routers as $key => $value) {
192
193
                if($value['group'] === $currentGroup){
194
                    $currentRoute = self::getInstance()->addFilter(self::getInstance()->routers[$key],$filters);
195
                    self::getInstance()->routers[$key] = $currentRoute;
196
                }
197
198
            }
199
            
200
            return self::getInstance();
201
        }
202
        
203
        self::getInstance()->routers[count(self::getInstance()->routers)-1] = self::getInstance()->addFilter(end(self::getInstance()->routers),$filters);
204
        return self::getInstance();
205
    }
206
207
    public static function addFilter(array $route, $filter): array
208
    {
209
        if(is_null($route['filters'])){
210
            $route['filters'] = $filter;
211
            return $route;
212
        }
213
214
        $filters = (is_array($filter)) ? $filter : [0 => $filter];
215
216
        if(is_array($route['filters'])){
217
            foreach ($route['filters'] as $key => $value) {
218
                $filters[] = $value;
219
            }
220
        }else{
221
            $filters[] = $route['filters'];
222
        }
223
224
        $route['filters'] = $filters;
225
        return $route;
226
    }
227
228
}
229