Passed
Pull Request — master (#3)
by Бабичев
01:45
created

Router::bootRoutes()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 4.679

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 3
cts 7
cp 0.4286
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 0
crap 4.679
1
<?php
2
3
namespace Bavix\Router;
4
5
use Bavix\Router\Rules\PatternRule;
6
use Psr\Cache\CacheItemPoolInterface;
7
use Bavix\Exceptions;
8
9
class Router
10
{
11
12
    /**
13
     * Router version
14
     */
15
    public const VERSION = '2.0.0';
16
17
    /**
18
     * @var PatternRule[]
19
     */
20
    protected $routes;
21
22
    /**
23
     * @var iterable
24
     */
25
    protected $config;
26
27
    /**
28
     * @var CacheItemPoolInterface
29
     */
30
    protected $pool;
31
32
    /**
33
     * Router constructor.
34
     *
35
     * @param iterable $data
36
     * @param CacheItemPoolInterface   $pool
37
     */
38 5
    public function __construct($data, CacheItemPoolInterface $pool = null)
39
    {
40 5
        $this->config = $data;
41 5
        $this->pool = $pool;
42 5
    }
43
44
    /**
45
     * @return Route
46
     *
47
     * @throws Exceptions\NotFound\Data
48
     * @throws Exceptions\NotFound\Path
49
     */
50
    public function getCurrentRoute(): Route
51
    {
52
        return $this->find(Server::sharedInstance()->path());
53
    }
54
55
    /**
56
     * @param string $path
57
     * @param string $host
58
     * @param string $protocol
59
     *
60
     * @return Route
61
     * @throws Exceptions\NotFound\Data
62
     * @throws Exceptions\NotFound\Path
63
     */
64 3
    public function getRoute(string $path, string $host = null, string $protocol = null): Route
65
    {
66 3
        return $this->find(Server::url($path, $host, $protocol));
67
    }
68
69
    /**
70
     * @return string
71
     */
72
    protected function hash(): string
73
    {
74
        return self::VERSION . \crc32(\json_encode($this->config));
75
    }
76
77
    /**
78
     * @return array
79
     * @throws
80
     */
81 5
    protected function loadingRoutes(): array
82
    {
83 5
        $loader = new Loader($this->config);
84 5
        $this->routes = $loader->simplify();
85
86 3
        if ($this->pool) {
87
            $item = $this->pool->getItem($this->hash());
88
            $item->set($this->routes);
89
            $this->pool->save($item);
90
        }
91
92 3
        return $this->routes;
93
    }
94
95
    /**
96
     * @return array
97
     * @throws
98
     */
99 5
    protected function bootRoutes(): array
100
    {
101 5
        if ($this->pool) {
102
            $item = $this->pool->getItem($this->hash());
103
            $data = $item->get();
104
            if ($data) {
105
                return $data;
106
            }
107
        }
108
109 5
        return $this->loadingRoutes();
110
    }
111
112
    /**
113
     * @return Route[]
114
     */
115 5
    public function routes(): array 
116
    {
117 5
        if (empty($this->routes)) {
118 5
            $this->routes = $this->bootRoutes();
119
        }
120
121 3
        return $this->routes;
122
    }
123
124
    /**
125
     * @param string $path
126
     *
127
     * @return Route
128
     *
129
     * @throws Exceptions\NotFound\Path
130
     */
131
    public function route(string $path): Route
132
    {
133
        $routes = $this->routes();
134
135
        if (empty($routes[$path])) {
136
            throw new Exceptions\NotFound\Path('Route `' . $path . '` not found');
137
        }
138
139
        return $routes[$path];
140
    }
141
142
    /**
143
     * @param string $subject
144
     * @return Route
145
     */
146 3
    protected function find(string $subject): Route
147
    {
148 3
        foreach ($this->routes() as $name => $patternRule) {
149 3
            $match = new Match($patternRule, $subject, Server::sharedInstance()->method());
150 3
            if ($match->isTest()) {
151 3
                return new Route($match);
152
            }
153
        }
154
155 1
        throw new Exceptions\NotFound\Page('Page `' . $subject . '` not found', 404);
156
    }
157
158
}
159