Completed
Push — master ( 27d2f2...3153a3 )
by Changwan
04:10
created

CompiledRoutes   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 10

Test Coverage

Coverage 97.5%

Importance

Changes 0
Metric Value
dl 0
loc 90
ccs 39
cts 40
cp 0.975
rs 10
c 0
b 0
f 0
wmc 14
lcom 2
cbo 10

4 Methods

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