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

CompiledRoutes::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 6
ccs 5
cts 5
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
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