Test Failed
Pull Request — master (#3)
by Бабичев
02:04
created

Router::loadingRoutes()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 0
cts 8
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 0
crap 6
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 3
    public function __construct($data, CacheItemPoolInterface $pool = null)
39
    {
40 3
        $this->pushConfig($data);
0 ignored issues
show
Bug introduced by
$data of type iterable is incompatible with the type array expected by parameter $config of Bavix\Router\Router::pushConfig(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

40
        $this->pushConfig(/** @scrutinizer ignore-type */ $data);
Loading history...
41
        $this->pool = $pool;
42
    }
43
44
    /**
45
     * @param array $config
46
     * @return Router
47
     */
48
    protected function pushConfig(array $config): self
49
    {
50
        $this->routes = null;
51
        $this->config = \array_merge(
52
            (array)$this->config,
53
            $config
54
        );
55
56
        return $this;
57
    }
58
59
    /**
60
     * @return Route
61
     *
62
     * @throws Exceptions\NotFound\Data
63
     * @throws Exceptions\NotFound\Path
64
     */
65
    public function getCurrentRoute(): Route
66
    {
67
        return $this->find(Server::sharedInstance()->path());
68
    }
69
70
    /**
71
     * @param string $path
72
     * @param string $host
73
     * @param string $protocol
74
     *
75
     * @return Route
76
     * @throws Exceptions\NotFound\Data
77
     * @throws Exceptions\NotFound\Path
78
     */
79
    public function getRoute(string $path, string $host = null, string $protocol = null): Route
80
    {
81
        return $this->find(Server::url($path, $host, $protocol));
82
    }
83
84
    /**
85
     * @return string
86
     */
87
    protected function hash(): string
88
    {
89
        return self::VERSION . \crc32(\json_encode($this->config));
90
    }
91
92
    /**
93
     * @return array
94
     * @throws
95
     */
96
    protected function loadingRoutes(): array
97
    {
98
        $loader = new Loader($this->config);
99
        $this->routes = $loader->simplify();
100
101
        if ($this->pool) {
102
            $item = $this->pool->getItem($this->hash());
103
            $item->set($this->routes);
104
            $this->pool->save($item);
105
        }
106
107
        return $this->routes;
108
    }
109
110
    /**
111
     * @return array
112
     * @throws
113
     */
114
    protected function bootRoutes(): array
115
    {
116
        if ($this->pool) {
117
            $item = $this->pool->getItem($this->hash());
118
            $data = $item->get();
119
            if ($data) {
120
                return $data;
121
            }
122
        }
123
124
        return $this->loadingRoutes();
125
    }
126
127
    /**
128
     * @return Route[]
129
     */
130
    public function routes(): array 
131
    {
132
        if (empty($this->routes)) {
133
            $this->routes = $this->bootRoutes();
134
        }
135
136
        return $this->routes;
137
    }
138
139
    /**
140
     * @param string $path
141
     *
142
     * @return Route
143
     *
144
     * @throws Exceptions\NotFound\Path
145
     */
146
    public function route(string $path): Route
147
    {
148
        $routes = $this->routes();
149
150
        if (empty($routes[$path])) {
151
            throw new Exceptions\NotFound\Path('Route `' . $path . '` not found');
152
        }
153
154
        return $routes[$path];
155
    }
156
157
    /**
158
     * @param string $subject
159
     * @return Route
160
     */
161
    protected function find(string $subject): Route
162
    {
163
        foreach ($this->routes() as $name => $patternRule) {
164
            $match = new Match($patternRule, $subject, Server::sharedInstance()->method());
165
            if ($match->isTest()) {
166
                return new Route($match);
167
            }
168
        }
169
170
        throw new Exceptions\NotFound\Page('Page `' . $subject . '` not found', 404);
171
    }
172
173
}
174