1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace JetFire\Routing; |
4
|
|
|
|
5
|
|
|
use ReflectionMethod; |
6
|
|
|
|
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Class Middleware |
10
|
|
|
* @package JetFire\Routing |
11
|
|
|
*/ |
12
|
|
|
class Middleware implements MiddlewareInterface |
13
|
|
|
{ |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* @var Router |
17
|
|
|
*/ |
18
|
|
|
private $router; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* @var array |
22
|
|
|
*/ |
23
|
|
|
private $callbacks = [ |
24
|
|
|
'globalMiddleware', |
25
|
|
|
'blockMiddleware', |
26
|
|
|
'classMiddleware', |
27
|
|
|
'routeMiddleware', |
28
|
|
|
]; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var array |
32
|
|
|
*/ |
33
|
|
|
private $middleware = []; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @param Router $router |
37
|
|
|
*/ |
38
|
|
|
public function __construct(Router $router) |
39
|
|
|
{ |
40
|
|
|
$this->router = $router; |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* @return array |
45
|
|
|
*/ |
46
|
|
|
public function getMiddleware() |
47
|
|
|
{ |
48
|
|
|
return $this->middleware; |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @param $middleware |
53
|
|
|
* @return mixed|void |
54
|
|
|
*/ |
55
|
|
|
public function setBeforeCallback($middleware) |
56
|
|
|
{ |
57
|
|
|
$this->setMiddleware('before', $middleware); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* @param $middleware |
62
|
|
|
* @return mixed|void |
63
|
|
|
*/ |
64
|
|
|
public function setAfterCallback($middleware) |
65
|
|
|
{ |
66
|
|
|
$this->setMiddleware('after', $middleware); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @param $action |
71
|
|
|
* @param $middleware |
72
|
|
|
*/ |
73
|
|
|
private function setMiddleware($action, $middleware) |
74
|
|
|
{ |
75
|
|
|
if (is_string($middleware)) { |
76
|
|
|
$middleware = rtrim($middleware, '/'); |
77
|
|
|
} |
78
|
|
|
if (is_array($middleware)) { |
79
|
|
|
$this->middleware[$action] = $middleware; |
80
|
|
|
} elseif (is_file($middleware) && is_array($mid = include $middleware)) { |
81
|
|
|
$this->middleware[$action] = $mid; |
82
|
|
|
} else { |
83
|
|
|
throw new \InvalidArgumentException('Accepted argument for setMiddleware are array and array file'); |
84
|
|
|
} |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @return Router |
89
|
|
|
*/ |
90
|
|
|
public function getCallbacks() |
91
|
|
|
{ |
92
|
|
|
return $this->callbacks; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* @description global middleware |
97
|
|
|
* @param $action |
98
|
|
|
* @return bool|mixed |
99
|
|
|
*/ |
100
|
|
|
public function globalMiddleware($action) |
101
|
|
|
{ |
102
|
|
|
if (isset($this->middleware[$action]['global_middleware'])) { |
103
|
|
|
foreach ($this->middleware[$action]['global_middleware'] as $class) { |
104
|
|
|
if (class_exists($class)) return $this->callHandler($class); |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
return true; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* @description block middleware |
112
|
|
|
* @param $action |
113
|
|
|
* @return bool|mixed |
114
|
|
|
*/ |
115
|
|
View Code Duplication |
public function blockMiddleware($action) |
|
|
|
|
116
|
|
|
{ |
117
|
|
|
if (isset($this->middleware[$action]['block_middleware'])) { |
118
|
|
|
if (isset($this->middleware[$action]['block_middleware'][$this->router->route->getTarget('block')])) { |
119
|
|
|
$blocks = $this->middleware[$action]['block_middleware'][$this->router->route->getTarget('block')]; |
120
|
|
|
if (is_array($blocks)) { |
121
|
|
|
foreach ($blocks as $block) { |
122
|
|
|
if (class_exists($block)) { |
123
|
|
|
if ($this->callHandler($block) === false) return false; |
124
|
|
|
} |
125
|
|
|
} |
126
|
|
|
} elseif (is_string($blocks) && class_exists($blocks)) { |
127
|
|
|
return $this->callHandler($blocks); |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
return true; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* @description controller middleware |
136
|
|
|
* @param $action |
137
|
|
|
* @return bool|mixed |
138
|
|
|
*/ |
139
|
|
View Code Duplication |
public function classMiddleware($action) |
|
|
|
|
140
|
|
|
{ |
141
|
|
|
if (isset($this->middleware[$action]['class_middleware'])) { |
142
|
|
|
$ctrl = str_replace('\\', '/', $this->router->route->getTarget('controller')); |
143
|
|
|
if (isset($this->middleware[$action]['class_middleware'][$ctrl]) && class_exists($this->router->route->getTarget('controller'))) { |
144
|
|
|
$classes = $this->middleware[$action]['class_middleware'][$ctrl]; |
145
|
|
|
if (is_array($classes)) { |
146
|
|
|
foreach ($classes as $class) { |
147
|
|
|
if ($this->callHandler($class) === false) return false; |
148
|
|
|
} |
149
|
|
|
} elseif (is_string($classes)) { |
150
|
|
|
return $this->callHandler($classes); |
151
|
|
|
} |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
return true; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* @description route middleware |
159
|
|
|
* @param $action |
160
|
|
|
* @return bool|mixed |
161
|
|
|
*/ |
162
|
|
|
public function routeMiddleware($action) |
163
|
|
|
{ |
164
|
|
|
if (isset($this->middleware[$action]['route_middleware'])) { |
165
|
|
|
if (isset($this->router->route->getPath()['middleware']) && class_exists($this->middleware[$action]['route_middleware'][$this->router->route->getPath()['middleware']])) { |
166
|
|
|
$classes = $this->middleware[$action]['route_middleware'][$this->router->route->getPath()['middleware']]; |
167
|
|
|
if (is_array($classes)) { |
168
|
|
|
foreach ($classes as $class) { |
169
|
|
|
if ($this->callHandler($class) === false) return false; |
170
|
|
|
} |
171
|
|
|
} elseif (is_string($classes)) { |
172
|
|
|
return $this->callHandler($classes); |
173
|
|
|
} |
174
|
|
|
} |
175
|
|
|
} |
176
|
|
|
return true; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @param $class |
181
|
|
|
* @return mixed |
182
|
|
|
*/ |
183
|
|
|
private function callHandler($class) |
184
|
|
|
{ |
185
|
|
|
$class = explode('@', $class); |
186
|
|
|
$method = isset($class[1]) ? $class[1] : 'handle'; |
187
|
|
|
$instance = call_user_func($this->router->getConfig()['di'], $class[0]); |
188
|
|
|
if (method_exists($instance, $method)) { |
189
|
|
|
$reflectionMethod = new ReflectionMethod($instance, $method); |
190
|
|
|
$dependencies = []; |
191
|
|
|
foreach ($reflectionMethod->getParameters() as $arg) { |
192
|
|
|
if (!is_null($arg->getClass())) { |
193
|
|
|
$dependencies[] = $this->getClass($arg->getClass()->name); |
194
|
|
|
} |
195
|
|
|
} |
196
|
|
|
$dependencies = array_merge($dependencies, [$this->router->route]); |
197
|
|
|
return $reflectionMethod->invokeArgs($instance, $dependencies); |
198
|
|
|
} |
199
|
|
|
return true; |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* @param $class |
204
|
|
|
* @return Route|RouteCollection|Router|mixed |
205
|
|
|
*/ |
206
|
|
|
private function getClass($class) |
207
|
|
|
{ |
208
|
|
|
switch ($class) { |
209
|
|
|
case Route::class: |
210
|
|
|
return $this->router->route; |
211
|
|
|
case Router::class: |
212
|
|
|
return $this->router; |
213
|
|
|
case RouteCollection::class: |
214
|
|
|
return $this->router->collection; |
215
|
|
|
case Response::class: |
216
|
|
|
return $this->router->response; |
217
|
|
|
default: |
218
|
|
|
return call_user_func_array($this->router->getConfig()['di'], [$class]); |
219
|
|
|
} |
220
|
|
|
} |
221
|
|
|
} |
222
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.