Passed
Push — master ( d3e071...5eb5e7 )
by Nícollas
01:38
created

RouteManager::setName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace MinasRouter\Router;
4
5
use MinasRouter\Http\Request;
6
use MinasRouter\Traits\RouteManagerUtils;
7
use MinasRouter\Router\Middlewares\MiddlewareCollection;
8
9
class RouteManager
10
{
11
    use RouteManagerUtils;
12
13
    /** @var string */
14
    protected $separator;
15
16
    /** @var string */
17
    protected $name;
18
19
    /** @var string */
20
    private $defaultName;
21
22
    /** @var string */
23
    private $defaultNamespace;
24
25
    /** @var object */
26
    protected $group;
27
28
    /** @var string */
29
    protected $route;
30
31
    /** @var string */
32
    protected $originalRoute;
33
34
    /** @var string */
35
    protected $fullUrl;
36
37
    /** @var string */
38
    protected $defaultRegex = "[^/]+";
39
40
    /** @var object */
41
    protected $middleware;
42
43
    /** @var string|\Closure */
44
    protected $action;
45
46
    /** @var string|null */
47
    protected $handler;
48
49
    /** @var array */
50
    protected $where = [];
51
52
    /** @var object */
53
    protected $request;
54
55
    public function __construct($fullUrl, $uri, $callback, String $separator, ?RouteGroups $group = null)
56
    {
57
        $this->fullUrl = $fullUrl;
58
        $this->route = $uri;
59
        $this->originalRoute = $uri;
60
        $this->separator = $separator;
61
        $this->group = $group;
62
63
        $this->request = new Request(
64
            $this->fullUrl,
65
            $this->route,
66
            $this->foundParameters(true)
67
        );
68
69
        $this->compileGroupData();
70
        $this->compileAction($callback);
71
    }
72
73
    /**
74
     * Method responsible for returning
75
     * the current group.
76
     * 
77
     * @return null|\MinasRouter\Router\RouteGroups
78
     */
79
    public function getGroup()
80
    {
81
        return $this->group;
82
    }
83
84
    /**
85
     * Method responsible for defining the
86
     * settings of the group the is part of.
87
     * 
88
     * @return null
89
     */
90
    private function compileGroupData()
91
    {
92
        if(!is_a($this->group, RouteGroups::class)) return null;
93
94
        $this->defaultName = $this->name = $this->group->name;
95
        $this->defaultNamespace = $this->group->namespace;
96
97
        if(is_a($this->group->middlewares, MiddlewareCollection::class)) {
98
            $this->middleware = $this->group->middlewares;
99
        }
100
101
        return null;
102
    }
103
104
    /**
105
     * Method responsible for returning the filtered route.
106
     * 
107
     * @return string
108
     */
109
    public function getRoute(): String
110
    {
111
        return $this->filteredRoute();
112
    }
113
114
    /**
115
     * Method responsible for filtering the route,
116
     * inserting regular expressions in place of dynamic parameters.
117
     * 
118
     * @return string
119
     */
120
    protected function filteredRoute(): String
121
    {
122
        $parameters = $this->foundParameters();
123
124
        foreach ($parameters as $parameter) {
125
            $realRegex = $this->getWhere($parameter[1]) ?? $this->defaultRegex;
126
127
            if (preg_match("/\?/", $parameter[0])) {
128
                $this->route = str_replace("/{$parameter[0]}", "(\/)?({$realRegex})?", $this->route);
129
                continue;
130
            }
131
132
            $this->route = str_replace("{$parameter[0]}", "({$realRegex})", $this->route);
133
        }
134
135
        return $this->route . '(\/)?';
136
    }
137
138
    /**
139
     * Method responsible for returning the regular
140
     * expression of a dynamic parameter.
141
     * 
142
     * @param string $param
143
     * 
144
     * @return null|string
145
     */
146
    protected function getWhere(String $param): ?String
147
    {
148
        if (!isset($this->where[$param])) return null;
149
150
        return $this->where[$param];
151
    }
152
153
    /**
154
     * Return the where of router.
155
     * 
156
     * @return void
157
     */
158
    protected function setWhereData(String $key, String $value)
159
    {
160
        $this->where[$key] = $value;
161
    }
162
163
    /**
164
     * Method responsible for returning all dynamic parameters.
165
     * 
166
     * @return array
167
     */
168
    protected function foundParameters($wordOnly = false, $originalRoute = false): array
169
    {
170
        $route = $originalRoute ? $this->originalRoute : $this->route;
171
172
        preg_match_all("~\{\s*([a-zA-Z_][a-zA-Z0-9_-]*)\??\}~x", $route, $params, PREG_SET_ORDER);
173
174
        if ($wordOnly) {
175
            $params = array_map(function ($param) {
176
                return $param[1];
177
            }, $params);
178
        }
179
180
        return $params;
181
    }
182
183
    /**
184
     * Method responsible for returning the parameters
185
     * for the route action.
186
     * 
187
     * @return array
188
     */
189
    public function closureReturn(): array
190
    {
191
        $getParams = $this->request()->getParams();
192
        $dinamycParameters = array_fill_keys($this->foundParameters(true, true), null);
193
194
        $params = array_values(
195
            array_merge($dinamycParameters, $getParams)
196
        );
197
198
        return [
199
            ...$params,
200
            $this->request()
201
        ];
202
    }
203
204
    /**
205
     * Method responsible for separating and defining the class and method,
206
     * or the anonymous function of the route.
207
     * 
208
     * @param string
209
     * 
210
     * @return null
211
     */
212
    private function compileAction($callback)
213
    {
214
        $handler = '';
215
        $action = '';
216
217
        if ($callback instanceof \Closure) {
218
            $this->action = $callback;
219
            return null;
220
        }
221
222
        if (is_string($callback)) {
223
            [$handler, $action] = explode($this->separator, $callback);
224
        }
225
226
        if (is_array($callback)) {
227
            $handler = $callback[0];
228
            $action = $callback[1];
229
        }
230
231
        $this->handler = $this->resolveHandler($handler);
232
        $this->action = $action;
233
234
        return null;
235
    }
236
    
237
    /**
238
     * Method responsible for returning the correct controller,
239
     * including the namespace of a group.
240
     * 
241
     * @param string $handler
242
     * 
243
     * @return string
244
     */
245
    private function resolveHandler(String $handler)
246
    {
247
        if(!$this->defaultNamespace) {
248
            return $handler;
249
        }
250
251
        $namespace = $this->parseDefaultString($this->defaultNamespace);
252
        
253
        return $namespace . $this->parseDefaultString($handler);
254
    }
255
256
    /**
257
     * Method responsible for applying the default
258
     * rule in the controller string.
259
     * 
260
     * @param string $handler
261
     * 
262
     * @return string
263
     */
264
    private function parseDefaultString(String $handler)
265
    {
266
        if (!preg_match("/^\\\/", $handler, $match)) {
267
            $handler = "\\{$handler}";
268
        }
269
270
        if (preg_match("/\/$/", $handler, $match)) {
271
            $handler = rtrim($handler, "/");
272
        }
273
274
        return $handler;
275
    }
276
277
    /**
278
     * Get the route name.
279
     * 
280
     * @return null|string
281
     */
282
    public function getName(): ?String
283
    {
284
        return $this->name;
285
    }
286
287
    /**
288
     * Set the route name.
289
     * 
290
     * @return void
291
     */
292
    protected function setName(String $value)
293
    {
294
        $this->name = $value;
295
    }
296
297
    /**
298
     * Get the route default name.
299
     * 
300
     * @return void
301
     */
302
    protected function getDefaultName()
303
    {
304
        return $this->defaultName;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->defaultName returns the type string which is incompatible with the documented return type void.
Loading history...
305
    }
306
307
    /**
308
     * Get the route action.
309
     * 
310
     * @return mixed|\Closure|string
311
     */
312
    public function getAction()
313
    {
314
        return $this->action;
315
    }
316
317
    /**
318
     * Get the route action and handler.
319
     * 
320
     * @return array
321
     */
322
    public function getCompleteAction()
323
    {
324
        return [
325
            $this->getHandler(),
326
            $this->getAction()
327
        ];
328
    }
329
330
    /**
331
     * Get the route handler.
332
     * 
333
     * @return mixed|\Closure|string
334
     */
335
    public function getHandler()
336
    {
337
        return $this->handler;
338
    }
339
340
    /**
341
     * Get the request route.
342
     * 
343
     * @return \MinasRouter\Http\Request
344
     */
345
    public function request(): Request
346
    {
347
        return $this->request;
348
    }
349
350
    /**
351
     * Get the middleware route.
352
     * 
353
     * @return null|\MinasRouter\Router\Middlewares\MiddlewareCollection
354
     */
355
    public function getMiddleware()
356
    {
357
        return $this->middleware;
358
    }
359
360
    /**
361
     * Method responsible for defining the middlewares of the route.
362
     * 
363
     * @param string|array $middleware
364
     * 
365
     * @return \MinasRouter\Router\RouteManager
366
     */
367
    public function middleware($middleware): RouteManager
368
    {
369
        if(is_a($this->middleware, MiddlewareCollection::class)) {
370
            $middleware = $this->middleware->storeMiddleware($middleware);
371
        }
372
373
        $this->middleware = new MiddlewareCollection($middleware);
374
375
        return $this;
376
    }
377
}
378