Passed
Push — master ( 814b1f...e0eeef )
by Henri
01:17
created

Router::loadFromName()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 20
rs 9.9
1
<?php
2
3
namespace HnrAzevedo\Router;
4
5
use Exception;
6
7
class Router{
8
    use Helper, CheckTrait, CheckWhere, DefinitionsTrait, ExtraJobsTrait;
9
10
    private static $instance = null;
11
    private array $routers = [];
12
    private ?string $prefix = null;
13
    private ?string $group = null;
14
    private $lastReturn = null;
15
    private $beforeAll = null;
16
    private $afterAll = null;
17
    private array $afterExcepts = [];
18
    private array $beforeExcepts = [];
19
    private bool $instanced = false;
20
    private bool $loaded = false;
21
22
    public function __construct()
23
    {
24
        return $this;
25
    }
26
27
    public static function create(): Router
28
    {
29
        if(!self::getInstance()->instanced){
30
            self::getInstance()->instanced = true;
31
        }
32
        
33
        return self::getInstance();
34
    }
35
36
    public static function getInstance(): Router
37
    {
38
        self::$instance = (is_null(self::$instance)) ? new self() : self::$instance;
39
        return self::$instance;
40
    }
41
42
    public function set($url ,$walking , string $protocol): Router
43
    {
44
        $this->lastReturn = null;
45
        
46
		$url = (substr($url,0,1) !=='/' and strlen($url) > 0) ? "/{$url}" : $url;
47
48
    	foreach($this->routers as $key => $value){
49
    		if( md5($this->prefix . $value['url'] . $value['protocol'] ) === md5( $url . $protocol ) ){
50
                throw new Exception("There is already a route with the url {$url} and with the {$protocol} protocol configured.");
51
            }
52
        }
53
        
54
        $this->checkTypeRole($walking);
55
56
		$route = [
57
			'url' => $this->prefix.$url,
58
			'role' => $walking,
59
			'protocol' => $protocol,
60
            'filters' => null,
61
            'where' => null,
62
            'before' => null,
63
            'beforeAll' => $this->beforeAll,
64
            'after' => null,
65
            'afterAll' => $this->afterAll,
66
            'group' => self::getInstance()->group
67
		];
68
69
		$this->routers[] = $route;		
70
        
71
        return self::getInstance();
72
    }
73
74
    public static function group(string $prefix,$callback): Router
75
    {
76
        self::getInstance()->prefix = (substr($prefix,0,1) !== '/') ? "/{$prefix}" : $prefix;
77
        self::getInstance()->group = sha1(date('d/m/Y h:m:i'));
78
        $callback();
79
        self::getInstance()->group = null;
80
        self::getInstance()->prefix = null;
81
        self::getInstance()->lastReturn = true;
82
        return self::getInstance();
83
    }
84
85
    public static function where(): Router
86
    {
87
        if(self::getInstance()->lastReturn){
88
            throw new Exception("It is not possible to define parameter tests for groups of routes.");
89
        }
90
91
        self::getInstance()->callWhereAdd(func_get_args());
92
93
        return self::getInstance();
94
    }
95
96
    public static function name(string $name): Router
97
    {
98
        if(self::getInstance()->lastReturn){
99
            throw new Exception("There is no reason to call a {$name} route group.");
100
        }
101
102
        $currentRoute = end(self::getInstance()->routers);
103
104
        self::getInstance()->hasRouteName($name);
105
106
        if(in_array($name,self::getInstance()->beforeExcepts)){
107
            $currentRoute['beforeAll'] = null;
108
        }
109
110
        if(in_array($name,self::getInstance()->afterExcepts)){
111
            $currentRoute['afterAll'] = null;
112
        }
113
114
        unset(self::getInstance()->routers[count(self::getInstance()->routers)-1]);
115
        
116
        self::getInstance()->routers[$name] = $currentRoute;
117
118
        return self::getInstance();
119
    }
120
121
    private function loadFromName(?string $routName = null): bool
122
    {
123
        if(!is_null($routName)){
124
            $currentProtocol = $this->getProtocol();
125
126
            $this->checkName($routName);
127
    
128
            $route = $this->routers[$routName];
129
    
130
            if(!$this->checkProtocol($route['protocol'], $currentProtocol)){
131
                throw new Exception('Page not found.',404);
132
            }
133
134
            $this->currentRoute = $route;
135
            $this->currentRoute['name'] = $routName;
136
            $this->loaded = true;
137
138
            return true;
139
        }
140
        return false;
141
    }
142
143
    public static function load(?string $routeName = null): Router
144
    {
145
        $instance = self::create()->getInstance();
146
147
        if($instance->loadFromName($routeName)){
148
            return $instance;
149
        }
150
151
		return $instance->loadFromArrays();
152
    }
153
154
    public static function dispatch(?string $routeName = null): bool
155
    {
156
        $instance = self::create()->getInstance();
157
158
        if(!$instance->loaded){
159
            self::load($routeName);
160
        }
161
162
        $instance->checkFiltering($instance->currentRoute);
163
        $instance->toHiking($instance->currentRoute);
164
165
        return true;
166
    }
167
168
    public function filter($filters): Router
169
    {
170
        if($this->lastReturn !== null){
171
            $currentGroup = end($this->routers)['group'];
172
173
            foreach ($this->routers as $key => $value) {
174
175
                if($value['group'] === $currentGroup){
176
                    $currentRoute = $this->addFilter($this->routers[$key],$filters);
177
                    $this->routers[$key] = $currentRoute;
178
                }
179
180
            }
181
            
182
            return $this;
183
        }
184
        
185
        $this->routers[count($this->routers)-1] = $this->addFilter(end($this->routers),$filters);
186
        return $this;
187
    }
188
189
    public static function addFilter(array $route, $filter): array
190
    {
191
        if(is_null($route['filters'])){
192
            $route['filters'] = $filter;
193
            return $route;
194
        }
195
196
        $filters = (is_array($filter)) ? $filter : [0 => $filter];
197
198
        if(is_array($route['filters'])){
199
            foreach ($route['filters'] as $key => $value) {
200
                $filters[] = $value;
201
            }
202
        }else{
203
            $filters[] = $route['filters'];
204
        }
205
206
        $route['filters'] = $filters;
207
        return $route;
208
    }
209
210
}
211