Completed
Push — master ( 7beb93...2f17d3 )
by Changwan
03:48
created

CompiledRoutes   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 10

Test Coverage

Coverage 97.22%

Importance

Changes 0
Metric Value
dl 0
loc 84
ccs 35
cts 36
cp 0.9722
rs 10
c 0
b 0
f 0
wmc 12
lcom 2
cbo 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
B compile() 0 30 5
A __construct() 0 6 1
A getPattern() 0 8 2
A dispatch() 0 16 4
1
<?php
2
namespace Wandu\Router;
3
4
use Closure;
5
use FastRoute\DataGenerator\GroupCountBased as GCBGenerator;
6
use FastRoute\Dispatcher as FastDispatcher;
7
use FastRoute\Dispatcher\GroupCountBased as GCBDispatcher;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Wandu\Router\Contracts\LoaderInterface;
10
use Wandu\Router\Contracts\ResponsifierInterface;
11
use Wandu\Router\Exception\MethodNotAllowedException;
12
use Wandu\Router\Exception\RouteNotFoundException;
13
use Wandu\Router\Path\Pattern;
14
15
class CompiledRoutes
16
{
17
    /**
18
     * @param \Closure $handler
19
     * @param \Wandu\Router\Configuration $config
20
     * @return \Wandu\Router\CompiledRoutes
21
     */
22 24
    public static function compile(Closure $handler, Configuration $config)
23
    {
24 24
        $resultRoutes = [];
25 24
        $resultNamedPath = [];
26
27 24
        $router = new Router;
28 24
        $router->middleware($config->getMiddleware(), $handler);
29
30 24
        $generator = new GCBGenerator();
31
        /**
32
         * @var array|string[] $methods
33
         * @var string $path
34
         * @var \Wandu\Router\Route $route
35
         * @var string $host
36
         */
37 24
        foreach ($router as list($methods, $path, $route, $host)) {
38 24
            $pathPattern = new Pattern($path);
39 24
            if ($routeName = $route->getName()) {
40 1
                $resultNamedPath[$routeName] = $pathPattern;
41
            }
42 24
            foreach ($pathPattern->parse() as $parsedPath) {
43 24
                foreach ($methods as $method) {
44 24
                    $handleId = uniqid('HANDLER');
45 24
                    $generator->addRoute($method, $parsedPath, $handleId);
46 24
                    $resultRoutes[$handleId] = $route;
47
                }
48
            }
49
        }
50 24
        return new static($resultRoutes, $resultNamedPath, $generator->getData());
51
    }
52
53
    /** @var \Wandu\Router\Route[] */
54
    protected $routes = [];
55
56
    /** @var \Wandu\Router\Route[] */
57
    protected $namedPattern;
58
59
    /** @var array */
60
    protected $compiledRoutes = [];
61
62
    /**
63
     * @param array $routes
64
     * @param array $namedPattern
65
     * @param array $compiledRoutes
66
     */
67 24
    public function __construct(array $routes, array $namedPattern, array $compiledRoutes)
68
    {
69 24
        $this->routes = $routes;
70 24
        $this->namedPattern = $namedPattern;
71 24
        $this->compiledRoutes = $compiledRoutes;
72 24
    }
73
    
74 1
    public function getPattern($name): Pattern
75
    {
76 1
        if (!isset($this->namedPattern[$name])) {
77 1
            throw new RouteNotFoundException("Route \"{$name}\" not found.");
78
        }
79 1
        return $this->namedPattern[$name];
80
81
    }
82 23
    public function dispatch(ServerRequestInterface $request, LoaderInterface $loader = null, ResponsifierInterface $responsifier = null)
83
    {
84 23
        $routeInfo = (new GCBDispatcher($this->compiledRoutes))
85 23
            ->dispatch($request->getMethod(), $request->getUri()->getPath());
86
        
87 23
        switch ($routeInfo[0]) {
88 23
            case FastDispatcher::NOT_FOUND:
89
                throw new RouteNotFoundException();
90 23
            case FastDispatcher::METHOD_NOT_ALLOWED:
91 8
                throw new MethodNotAllowedException();
92
        }
93 22
        foreach ($routeInfo[2] as $key => $value) {
94 4
            $request = $request->withAttribute($key, $value);
95
        }
96 22
        return $this->routes[$routeInfo[1]]->execute($request, $loader, $responsifier);
97
    }
98
}
99