Completed
Push — master ( cc3500...7c787d )
by Taosikai
14:10
created

Route.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * slince routing library
4
 * @author Tao <[email protected]>
5
 */
6
namespace Slince\Routing;
7
8
class Route
9
{
10
    /**
11
     * head
12
     * @var string
13
     */
14
    const HEAD = 'HEAD';
15
16
    /**
17
     * get
18
     * @var string
19
     */
20
    const GET = 'GET';
21
22
    /**
23
     * post
24
     * @var string
25
     */
26
    const POST = 'POST';
27
28
    /**
29
     * put
30
     * @var string
31
     */
32
    const PUT = 'PUT';
33
34
    /**
35
     * patch
36
     * @var string
37
     */
38
    const PATCH = 'PATCH';
39
40
    /**
41
     * delete
42
     * @var string
43
     */
44
    const DELETE = 'DELETE';
45
46
    /**
47
     * purge
48
     * @var string
49
     */
50
    const PURGE = 'PURGE';
51
52
    /**
53
     * options
54
     * @var string
55
     */
56
    const OPTIONS = 'OPTIONS';
57
58
    /**
59
     * trace
60
     * @var string
61
     */
62
    const TRACE = 'TRACE';
63
64
    /**
65
     * connect
66
     * @var string
67
     */
68
    const CONNECT = 'CONNECT';
69
70
    /**
71
     * The route name
72
     * @var string
73
     */
74
    protected $name;
75
76
    /**
77
     * Path
78
     * @var string
79
     */
80
    protected $path;
81
82
    /**
83
     * Action
84
     * @var mixed
85
     */
86
    protected $action;
87
88
    /**
89
     * Schemes
90
     * @var array
91
     */
92
    protected $schemes = [];
93
94
    /**
95
     * Host
96
     * @var string
97
     */
98
    protected $host;
99
100
    /**
101
     * Methods
102
     * @var array
103
     */
104
    protected $methods = [];
105
106
    /**
107
     * Requirements
108
     * @var array
109
     */
110
    protected $requirements = [];
111
112
    /**
113
     * Defaults
114
     * @var array
115
     */
116
    protected $defaults= [];
117
118
    /**
119
     * Parameters
120
     * @var array
121
     */
122
    protected $parameters = [];
123
124
    /**
125
     * The computed parameters
126
     * @var array
127
     */
128
    protected $computedParameters = [];
129
130
    /**
131
     * whether the route has been compiled
132
     * @var bool
133
     */
134
    protected $isCompiled = false;
135
136
    /**
137
     * the host regex
138
     * @var string
139
     */
140
    protected $hostRegex;
141
142
    /**
143
     * the path regex
144
     * @var string
145
     */
146
    protected $pathRegex;
147
148
    /**
149
     * Array of host variables
150
     * @var array
151
     */
152
    protected $hostVariables = [];
153
154
    /**
155
     * Array of path variables
156
     * @var array
157
     */
158
    protected $pathVariables = [];
159
160
    /**
161
     * Array of variables
162
     * @var array
163
     */
164
    protected $variables = [];
165
166
    public function __construct($path, $action) {
167
        $this->setPath($path);
168
        $this->setAction($action);
169
    }
170
171
    /**
172
     * Sets route name
173
     * @param string $name
174
     * @return Route;
0 ignored issues
show
The doc-type Route; could not be parsed: Expected "|" or "end of type", but got ";" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
175
     */
176
    public function setName($name)
177
    {
178
        $this->name = $name;
179
        return $this;
180
    }
181
182
    /**
183
     * @return string
184
     */
185
    public function getName()
186
    {
187
        return $this->name;
188
    }
189
190
    /**
191
     * Sets the route path
192
     * @param string $path
193
     * @return Route
194
     */
195
    public function setPath($path)
196
    {
197
        $this->path = '/' . trim($path, '/');
198
        return $this;
199
    }
200
201
    /**
202
     * Gets the route path
203
     * @return string path
204
     */
205
    public function getPath()
206
    {
207
        return $this->path;
208
    }
209
210
    /**
211
     * Gets the path regex
212
     * @return string
213
     */
214
    public function getPathRegex()
215
    {
216
        return $this->pathRegex;
217
    }
218
219
    /**
220
     * Sets the action for the route
221
     * @param mixed $action
222
     * @return Route
223
     */
224
    public function setAction($action)
225
    {
226
        $this->action = $action;
227
        return $this;
228
    }
229
230
    /**
231
     * Gets the action
232
     * @return mixed
233
     */
234
    public function getAction()
235
    {
236
        return $this->action;
237
    }
238
239
    /**
240
     * Sets the route schemes
241
     * @param array $schemes
242
     * @return Route
243
     */
244
    public function setSchemes(array $schemes)
245
    {
246
        $this->schemes = array_map('strtolower', $schemes);
247
        return $this;
248
    }
249
250
    /**
251
     * Checks whether the route has the scheme
252
     * @param string $scheme
253
     * @return bool
254
     */
255
    public function hasScheme($scheme)
256
    {
257
        return in_array(strtolower($scheme), $this->schemes);
258
    }
259
260
    /**
261
     * Gets all schemes
262
     * @return array
263
     */
264
    public function getSchemes()
265
    {
266
        return $this->schemes;
267
    }
268
269
    /**
270
     * Sets the route request methods
271
     * @param array $methods
272
     * @return Route
273
     */
274
    public function setMethods(array $methods)
275
    {
276
        $this->methods = array_map('strtoupper', $methods);
277
        return $this;
278
    }
279
280
    /**
281
     * Checks whether the route has the request method
282
     * @param string $method
283
     * @return bool
284
     */
285
    public function hasMethod($method)
286
    {
287
        return in_array(strtoupper($method), $this->methods);
288
    }
289
290
    /**
291
     * Gets all request methods that the route supports
292
     * @return array
293
     */
294
    public function getMethods()
295
    {
296
        return $this->methods;
297
    }
298
299
    /**
300
     * Set the route host
301
     * @param string $host
302
     * @return Route
303
     */
304
    public function setHost($host)
305
    {
306
        $this->host = $host;
307
        return $this;
308
    }
309
310
    /**
311
     * Gets the host
312
     * @return string
313
     */
314
    public function getHost()
315
    {
316
        return $this->host;
317
    }
318
319
    /**
320
     * Gets the route host regex
321
     * @return string
322
     */
323
    public function getHostRegex()
324
    {
325
        return $this->hostRegex;
326
    }
327
328
    /**
329
     * Sets the requirements of the route
330
     * @param array $requirements
331
     * @return Route
332
     */
333
    public function setRequirements(array $requirements)
334
    {
335
        $this->requirements = $requirements;
336
        return $this;
337
    }
338
339
    /**
340
     * Sets a requirement by specified name and value
341
     * @param string $name
342
     * @param string $requirement
343
     * @return Route
344
     */
345
    public function setRequirement($name, $requirement)
346
    {
347
        $this->requirements[$name] = $requirement;
348
        return $this;
349
    }
350
351
    /**
352
     * Add the requirements of the route (not replace)
353
     * @param array $requirements
354
     * @return Route
355
     */
356
    public function addRequirements(array $requirements)
357
    {
358
        $this->requirements += $requirements;
359
        return $this;
360
    }
361
362
    /**
363
     * Gets all requirements
364
     * @return array
365
     */
366
    public function getRequirements()
367
    {
368
        return $this->requirements;
369
    }
370
371
    /**
372
     * Checks whether the route has the requirement
373
     * @param string $name
374
     * @return bool
375
     */
376
    public function hasRequirement($name)
377
    {
378
        return isset($this->requirements[$name]);
379
    }
380
381
    /**
382
     * Gets a requirement by its name
383
     * @param string $name
384
     * @param string $default
385
     * @return string|null
386
     */
387
    public function getRequirement($name, $default = null)
388
    {
389
        return isset($this->requirements[$name]) ? $this->requirements[$name] : $default;
390
    }
391
392
    /**
393
     *  Gets the defaults
394
     */
395
    public function getDefaults()
396
    {
397
        return $this->defaults;
398
    }
399
400
    /**
401
     * Sets a default item
402
     * @param string $name
403
     * @param string $value
404
     * @return Route
405
     */
406
    public function setDefault($name, $value)
407
    {
408
        $this->defaults[$name] = $value;
409
        return $this;
410
    }
411
412
    /**
413
     * Sets the defaults
414
     * @param array $defaults
415
     * @return Route
416
     */
417
    public function setDefaults(array $defaults)
418
    {
419
        $this->defaults = $defaults;
420
        return $this;
421
    }
422
423
    /**
424
     * Add the defaults of the route (not replace)
425
     * @param array $defaults
426
     * @return Route
427
     */
428
    public function addDefaults(array $defaults)
429
    {
430
        $this->defaults += $defaults;
431
        return $this;
432
    }
433
434
    /**
435
     * Gets the default option value by its name
436
     * @param string $name
437
     * @return mixed|null
438
     */
439
    public function getDefault($name)
440
    {
441
        return isset($this->defaults[$name]) ? $this->defaults[$name] : null;
442
    }
443
444
    /**
445
     * Checks whether the route has the default option
446
     * @param string $name
447
     * @return bool
448
     */
449
    public function hasDefault($name)
450
    {
451
        return array_key_exists($name, $this->defaults);
452
    }
453
454
    /**
455
     * Sets the route parameters
456
     * @param string $name
457
     * @param mixed $parameter
458
     * @return Route
459
     */
460
    public function setParameter($name, $parameter)
461
    {
462
        $this->parameters[$name] = $parameter;
463
        return $this;
464
    }
465
466
    /**
467
     * Gets the route parameters
468
     * @param string $name
469
     * @return mixed
470
     */
471
    public function getParameter($name)
472
    {
473
        return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
474
    }
475
476
    /**
477
     * Checks whether the parameter exists
478
     * @param string $name
479
     * @return mixed
480
     */
481
    public function hasParameter($name)
482
    {
483
        return isset($this->parameters[$name]);
484
    }
485
486
    /**
487
     * Sets all parameters
488
     * @param array $parameters
489
     * @return Route
490
     */
491
    public function setParameters(array $parameters)
492
    {
493
        $this->parameters = $parameters;
494
        return $this;
495
    }
496
497
    /**
498
     * Add the parameters of the route (not replace)
499
     * @param array $parameters
500
     * @return Route
501
     */
502
    public function addParameters(array $parameters)
503
    {
504
        $this->parameters += $parameters;
505
        return $this;
506
    }
507
508
    /**
509
     * Gets all parameters
510
     * @return array
511
     */
512
    public function getParameters()
513
    {
514
        return $this->parameters;
515
    }
516
517
    /**
518
     * @param array $computedParameters
519
     */
520
    public function setComputedParameters($computedParameters)
521
    {
522
        $this->computedParameters = $computedParameters;
523
    }
524
525
    /**
526
     * @return array
527
     */
528
    public function getComputedParameters()
529
    {
530
        return $this->computedParameters;
531
    }
532
533
    /**
534
     * {@inheritdoc}
535
     */
536
    public function isCompiled()
537
    {
538
        return $this->isCompiled;
539
    }
540
541
    /**
542
     * Complies the route
543
     * @param boolean $reCompile
544
     * @return Route
545
     */
546
    public function compile($reCompile = false)
547
    {
548
        if (!$this->isCompiled || $reCompile) {
549
            if ($this->getHost()) {
550
                $this->hostRegex = $this->parsePattern($this->getHost(), true);
551
            }
552
            $this->pathRegex = $this->parsePattern($this->getPath(), false);
553
            $this->variables = array_merge($this->hostVariables, $this->pathVariables);
554
            $this->isCompiled = true;
555
        }
556
        return $this;
557
    }
558
559
    /**
560
     * Gets all variables that been compiled
561
     * @return array
562
     */
563
    public function getVariables()
564
    {
565
        return $this->variables;
566
    }
567
568
    /**
569
     * Parses the path to regex
570
     * @param string $path
571
     * @param boolean $isHost
572
     * @return string
573
     */
574
    protected function parsePattern($path, $isHost)
575
    {
576
        $variables = [];
577
        $regex = preg_replace_callback('#[/\.]?\{([a-zA-Z0-9_,]*)\}#i', function ($matches) use(&$variables){
578
            $variables[] = $matches[1];
579
            $subRegex = "(?P<{$matches[1]}>" . (isset($this->requirements[$matches[1]]) ? $this->requirements[$matches[1]] : '[^/\.]+') . ')';
580
            $regex = str_replace('\{' . $matches[1] . '\}', $subRegex, preg_quote($matches[0], '#'));
581
            if ($this->hasDefault($matches[1])) {
582
                $regex = "(?:{$regex})?";
583
            }
584
            return $regex;
585
        }, $path);
586
        $regex = "#^{$regex}$#";
587
        if ($isHost) {
588
            $regex .= 'i';
589
            $this->hostVariables = $variables;
590
        } else {
591
            $this->pathVariables = $variables;
592
        }
593
        return $regex;
594
    }
595
}