Passed
Branch master (1ac090)
by Hong
02:12
created

RouteAwareTrait   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 27
c 1
b 0
f 0
dl 0
loc 120
rs 10
wmc 13

7 Methods

Rating   Name   Duplication   Size   Complexity  
A setParser() 0 4 1
A addPost() 0 3 1
A extractPrefix() 0 6 2
A addGet() 0 3 1
A addRoute() 0 9 2
A groupMatch() 0 10 4
A loadRoutes() 0 10 2
1
<?php
2
3
/**
4
 * Phoole (PHP7.2+)
5
 *
6
 * @category  Library
7
 * @package   Phoole\Route
8
 * @copyright Copyright (c) 2019 Hong Zhang
9
 */
10
declare(strict_types=1);
11
12
namespace Phoole\Route\Util;
13
14
use Phoole\Route\Util\Result;
15
use Phoole\Route\Parser\ParserInterface;
16
17
/**
18
 * RouteAwareTrait
19
 *
20
 * @package Phoole\Route
21
 */
22
trait RouteAwareTrait
23
{
24
    /**
25
     * @var ParserInterface
26
     */
27
    protected $parser;
28
29
    /**
30
     * @var RouteGroup[]
31
     */
32
    protected $groups = [];
33
34
    /**
35
     * Add one route
36
     *
37
     * @param  Route $route
38
     * @return $this
39
     */
40
    public function addRoute(Route $route)
41
    {
42
        // group routes base on the URI prefix
43
        $prefix = $this->extractPrefix($route->getPattern());
44
        if (!isset($this->groups[$prefix])) {
45
            $this->groups[$prefix] = new RouteGroup($this->parser);
46
        }
47
        $this->groups[$prefix]->addRoute($route);
48
        return $this;
49
    }
50
51
    /**
52
     * Add a GET route
53
     *
54
     * @param  string $pattern
55
     * @param  mixed $handler
56
     * @param  array $defaults  default parameters if any
57
     * @return $this
58
     */
59
    public function addGet(string $pattern, $handler, array $defaults = [])
60
    {
61
        return $this->addRoute(new Route('GET', $pattern, $handler, $defaults));
62
    }
63
64
    /**
65
     * Add a POST route
66
     *
67
     * @param  string $pattern
68
     * @param  mixed $handler
69
     * @param  array $defaults  default parameters if any
70
     * @return $this
71
     */
72
    public function addPost(string $pattern, $handler, array $defaults = [])
73
    {
74
        return $this->addRoute(new Route('POST', $pattern, $handler, $defaults));
75
    }
76
77
    /**
78
     * Load routes from config array
79
     *
80
     * ```php
81
     * $routes = [
82
     *     ['GET', '/user/{uid}', function() {}, ['uid' => 12]],
83
     *     ...
84
     * ];
85
     * ```
86
     *
87
     * @param  array $routes
88
     * @return $this
89
     */
90
    protected function loadRoutes(array $routes)
91
    {
92
        foreach ($routes as $definition) {
93
            $method = $definition[0];
94
            $pattern = $definition[1];
95
            $handler = $definition[2];
96
            $defaults = $definition[3] ?? [];
97
            $this->addRoute(new Route($method, $pattern, $handler, $defaults));
98
        }
99
        return $this;
100
    }
101
102
    /**
103
     * @param  ParserInterface $parser
104
     * @return $this
105
     */
106
    protected function setParser(ParserInterface $parser)
107
    {
108
        $this->parser = $parser;
109
        return $this;
110
    }
111
112
    /**
113
     * Extract the URI prefix, '/usr/' from '/user/uid/1'
114
     *
115
     * @param  string $uri  URI or pattern
116
     * @return string
117
     */
118
    protected function extractPrefix(string $uri): string
119
    {
120
        if (preg_match('~^(/[^/\[\]\{\}]+)~', $uri, $matched)) {
121
            return $matched[1];
122
        }
123
        return '/';
124
    }
125
126
    /**
127
     * Match a http request with all RouteGroup[s]
128
     *
129
     * @param  Result $result;
130
     * @return Result
131
     */
132
    protected function groupMatch(Result $result): Result
133
    {
134
        $uri = $result->getRequest()->getUri()->getPath();
135
        foreach ($this->groups as $prefix => $group) {
136
            // check prefix, then do matching
137
            if ($prefix === $this->extractPrefix($uri) && $group->match($result)) {
138
                return $result;
139
            }
140
        }
141
        return $result;
142
    }
143
}
144