Passed
Branch master (d2b7b8)
by Henri
01:19
created

Router::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 2
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, CheckWhere, DefinitionsTrait;
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 function set($url ,$walking , string $protocol): Router
40
    {
41
		$url = (substr($url,0,1) !=='/' and strlen($url) > 0) ? "/{$url}" : $url;
42
43
    	foreach($this->routers as $key => $value){
44
    		if( md5($this->prefix . $value['url'] . $value['protocol'] ) === md5( $url . $protocol ) ){
45
                throw new Exception("There is already a route with the url {$url} and with the {$protocol} protocol configured.");
46
            }
47
        }
48
        
49
        $this->checkTypeRole($walking);
50
51
		$route = [
52
			'url' => $this->prefix.$url,
53
			'role' => $walking,
54
			'protocol' => $protocol,
55
            'filters' => null,
56
            'where' => null,
57
            'group' => self::getInstance()->group
58
		];
59
60
		$this->routers[] = $route;		
61
        
62
        return self::getInstance();
63
    }
64
65
    public static function group(string $prefix,$callback): Router
66
    {
67
        self::getInstance()->prefix = (substr($prefix,0,1) !== '/') ? "/{$prefix}" : $prefix;
68
        self::getInstance()->group = sha1(date('d/m/Y h:m:i'));
69
        $callback();
70
        self::getInstance()->group = null;
71
        self::getInstance()->prefix = null;
72
        self::getInstance()->lastReturn = true;
73
        return self::getInstance();
74
    }
75
76
    public static function where(): Router
77
    {
78
        if(self::getInstance()->lastReturn){
79
            throw new Exception("It is not possible to define parameter tests for groups of routes.");
80
        }
81
82
        self::getInstance()->callWhereAdd(func_get_args());
83
84
        return self::getInstance();
85
    }
86
87
    public static function name(string $name): Router
88
    {
89
        if(self::getInstance()->lastReturn){
90
            throw new Exception("There is no reason to call a {$name} route group.");
91
        }
92
93
        $currentRoute = end(self::getInstance()->routers);
94
95
        foreach(self::getInstance()->routers as $key => $value){
96
            if(array_key_exists($name, self::getInstance()->routers)){
97
                throw new Exception("There is already a route with the name {$name} configured.");
98
            }
99
        }
100
101
        $currentRoute['name'] = $name;
102
103
        self::getInstance()->routers[count(self::getInstance()->routers)-1] = $currentRoute;
104
105
        self::getInstance()->lastReturn = null;
106
107
        return self::getInstance();
108
    }
109
110
    private function byName(?string $routName)
111
    {
112
        if(!is_null($routName)){
113
            $currentProtocol = $this->getProtocol();
114
115
            $this->checkName($routName);
116
    
117
            $route = $this->routers[$routName];
118
    
119
            if(!$this->checkProtocol($route['protocol'], $currentProtocol)){
120
                throw new Exception('Page not found.',404);
121
            }
122
    
123
            $this->checkFiltering($route);
124
    
125
            $this->toHiking($route['role']);
126
            throw true;
127
        }
128
    }
129
130
    public static function dispatch(?string $routeName = null): bool
131
    {
132
        $instance = self::create();
133
134
        $instance->getInstance()->byName($routeName);
135
136
		$currentProtocol = $instance->getInstance()->getProtocol();
137
138
        foreach(array_reverse($instance->getInstance()->routers) as $r => $route){
139
140
            $instance->getInstance()->currentRoute = $route;
141
142
            if(!$instance->getInstance()->checkProtocol($route['protocol'], $currentProtocol)){
143
                continue;
144
            }
145
146
            $instance->getInstance()->hasProtocol($route, $currentProtocol);
147
148
            $routeLoop = $instance->getInstance()->explodeRoute( (substr($route['url'],strlen($route['url'])-1,1) === '/') , $route['url']);
149
            
150
            $_SERVER['REQUEST_URI'] = (array_key_exists('REQUEST_URI', $_SERVER)) ? $_SERVER['REQUEST_URI'] : '';
151
152
            $routeRequest = $instance->getInstance()->explodeRoute((substr($_SERVER['REQUEST_URI'],strlen($_SERVER['REQUEST_URI'])-1,1) === '/') , $_SERVER['REQUEST_URI']);
153
154
            if(!$instance->getInstance()->checkToHiking($route, $routeRequest, $routeLoop)){
155
                continue;
156
            }
157
158
            $instance->getInstance()->checkFiltering($route);
159
160
            $instance->getInstance()->toHiking($route['role']);
161
            return true;
162
            
163
        }
164
        
165
        $instance->getInstance()->currentRoute = null;
166
167
	    throw new Exception('Page not found.',404);
168
    }
169
170
    public static function filter($filters): Router
171
    {
172
        if(self::getInstance()->lastReturn !== null){
173
            $currentGroup = end(self::getInstance()->routers)['group'];
174
175
            foreach (self::getInstance()->routers as $key => $value) {
176
177
                if($value['group'] === $currentGroup){
178
                    $currentRoute = self::getInstance()->addFilter(self::getInstance()->routers[$key],$filters);
179
                    self::getInstance()->routers[$key] = $currentRoute;
180
                }
181
182
            }
183
184
            self::getInstance()->lastReturn = null;
185
            
186
            return self::getInstance();
187
        }
188
        
189
        self::getInstance()->routers[count(self::getInstance()->routers)-1] = self::getInstance()->addFilter(end(self::getInstance()->routers),$filters);
190
        return self::getInstance();
191
    }
192
193
    public static function addFilter(array $route, $filter): array
194
    {
195
        if(is_null($route['filters'])){
196
            $route['filters'] = $filter;
197
            return $route;
198
        }
199
200
        $filters = (is_array($filter)) ? $filter : [0 => $filter];
201
202
        if(is_array($route['filters'])){
203
            foreach ($route['filters'] as $key => $value) {
204
                $filters[] = $value;
205
            }
206
        }else{
207
            $filters[] = $route['filters'];
208
        }
209
210
        $route['filters'] = $filters;
211
        return $route;
212
    }
213
214
}
215