Passed
Branch master (eeb79a)
by Henri
02:29 queued 01:14
created

Router::post()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
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
        $currentProtocol = $this->getProtocol();
123
124
        $this->check_name($route_name);
125
126
        $route = $this->routers[$route_name];
127
128
        $this->check_protocol($route['protocol'], $currentProtocol);
129
130
        $this->check_filtering($route);
131
132
        $this->Controller($route['role']);
133
        return true;
134
    }
135
136
    public function dispatch(?string $route_name = null): bool
137
    {
138
        if(!is_null($route_name)){
139
            return $this->byName($route_name);
140
        }
141
142
		$currentProtocol = $this->getProtocol();
143
144
        foreach(array_reverse($this->routers) as $r => $route){
145
146
            $this->hasProtocol($route, $currentProtocol);
147
148
	        $route_loop = explode(
149
                '/',
150
                (substr($route['url'],strlen($route['url'])-1,1) === '/') 
151
                    ? substr($route['url'], 0, -1) 
152
                    : $route['url'] 
153
            );
154
155
            /* ONLY FOR DEBUG CONDITION */
156
            $route_request = $route_loop;
157
	        /*$route_request = explode(
158
                '/',
159
                (substr($_SERVER['REQUEST_URI'],strlen($_SERVER['REQUEST_URI'])-1,1) === '/') 
160
                ? substr($_SERVER['REQUEST_URI'], 0, -1) 
161
                : $_SERVER['REQUEST_URI'] 
162
            );*/
163
164
	        if(count($route_loop) !== count($route_request)){
165
                continue;
166
            }
167
168
	        for($rr = 0; $rr < count($route_loop); $rr++){
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
169
	            $param = (substr($route_loop[$rr],0,1)==='{');
170
171
	            if($param){
172
                    $param_name = substr($route_loop[$rr],1,strlen($route_loop[$rr])-2);
173
	                $data[$param_name] = $route_request[$rr];
174
	            }
175
176
	            if(!$param and $route_loop[$rr] !== $route_request[$rr]){
177
                    continue 2;
178
                }
179
            }
180
            
181
            $this->check_filtering($route);
182
183
            $this->Controller($route['role']);
184
	        return true;
185
	    }
186
187
	    throw new Exception('Page not found.',404);
188
    }
189
190
    public static function filter($filters): Router
191
    {
192
        if(self::getInstance()->lastReturn !== null){
193
            $currentGroup = end(self::getInstance()->routers)['group'];
194
195
            foreach (self::getInstance()->routers as $key => $value) {
196
197
                if($value['group'] === $currentGroup){
198
                    $currentRoute = self::getInstance()->addFilter(self::getInstance()->routers[$key],$filters);
199
                    self::getInstance()->routers[$key] = $currentRoute;
200
                }
201
202
            }
203
            
204
        }else{
205
            self::getInstance()->routers[count(self::getInstance()->routers)-1] = self::getInstance()->addFilter(end(self::getInstance()->routers),$filters);
206
        }
207
208
        return self::getInstance();
209
    }
210
211
    public static function addFilter(array $route, $filter): array
212
    {
213
        if(is_null($route['filters'])){
214
            $route['filters'] = $filter;
215
            return $route;
216
        }
217
218
        $filters = (is_array($filter)) ? $filter : [0 => $filter];
219
220
        if(is_array($route['filters'])){
221
            foreach ($route['filters'] as $key => $value) {
222
                $filters[] = $value;
223
            }
224
        }else{
225
            $filters[] = $route['filters'];
226
        }
227
228
        $route['filters'] = $filters;
229
        return $route;
230
    }
231
232
    public function Controller(string $controll): void
233
    {
234
        $data = $this->getData();
235
236
        foreach ($data['GET'] as $name => $value) {
237
            $controll = str_replace('{'.$name.'}',$value,$controll);
238
        }
239
240
        $d = explode(':',$controll);
241
242
        if(count($d) != 2){
243
            throw new Exception("Controller {$controll} badly set.");
244
        }
245
246
        if(!class_exists('Controllers\\' . ucfirst($d[0]))){
247
            throw new Exception("No controller {$d[0]} found.");
248
        }
249
250
        if(!method_exists('Controllers\\' . ucfirst($d[0]), $d[1])){
251
            throw new Exception("No method {$d[1]} found for {$d[0]}.");
252
        }
253
254
        $controller = 'Controllers\\' . ucfirst($d[0]);
255
        $controller = new $controller();
256
        $method = $d[1];
257
258
        if( ( $this->getProtocol() == 'form') ){
259
            $this->ControllerForm($controller, $method, $data['POST']);
260
        }else {
261
            $controller->$method($data);
262
        }
263
    }    
264
265
}
266