Completed
Push — master ( 90174b...a197f9 )
by Changwan
03:50
created

CompiledRoutes::getPattern()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 8
ccs 4
cts 4
cp 1
crap 2
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
        $routeMap = [];
25 24
        $router = new Router;
26 24
        $router->middleware($config->getMiddleware(), $handler);
27
28
        /** @var \FastRoute\DataGenerator\GroupCountBased[] $generators */
29 24
        $generators = [];
30
        /**
31
         * @var array|string[] $methods
32
         * @var string $path
33
         * @var \Wandu\Router\Route $route
34
         */
35 24
        foreach ($router as list($methods, $path, $route)) {
36 24
            $pathPattern = new Pattern($path);
37
38 24
            $handleId = uniqid('HANDLER');
39 24
            $routeMap[$handleId] = $route;
40
41 24
            foreach ($pathPattern->parse() as $parsedPath) {
42 24
                foreach ($methods as $method) {
43 24
                    foreach ($route->getDomains() as $domain) {
0 ignored issues
show
Bug introduced by
The expression $route->getDomains() of type string is not traversable.
Loading history...
44 24
                        if (!isset($generators[$domain])) {
45 24
                            $generators[$domain] = new GCBGenerator();
46
                        }
47 24
                        $generators[$domain]->addRoute($method, $parsedPath, $handleId);
48
                    }
49
                }
50
            }
51
        }
52
53 24
        $compiledRoutes = array_map(function (GCBGenerator $generator) {
54 24
            return $generator->getData();
55 24
        }, $generators);
56 24
        return new static($compiledRoutes, $routeMap);
57
    }
58
59
    /** @var \Wandu\Router\Route[] */
60
    protected $routeMap = [];
61
62
    /** @var array */
63
    protected $compiledRoutes = [];
64
65
    /**
66
     * @param array $compiledRoutes
67
     * @param array $routeMap
68
     */
69 24
    public function __construct(array $compiledRoutes, array $routeMap)
70
    {
71 24
        $this->routeMap = $routeMap;
72 24
        $this->compiledRoutes = $compiledRoutes;
73 24
    }
74
    
75 24
    public function dispatch(ServerRequestInterface $request, LoaderInterface $loader = null, ResponsifierInterface $responsifier = null)
76
    {
77 24
        $host = $request->getHeaderLine('host');
78 24
        $compiledRoutes = array_key_exists($host, $this->compiledRoutes)
79 1
            ? $this->compiledRoutes[$host]
80 24
            : $this->compiledRoutes['@'];
81
        
82 24
        $routeInfo = (new GCBDispatcher($compiledRoutes))
83 24
            ->dispatch($request->getMethod(), '/' . trim($request->getUri()->getPath(), '/'));
84
        
85 24
        switch ($routeInfo[0]) {
86 24
            case FastDispatcher::NOT_FOUND:
87 1
                throw new RouteNotFoundException();
88 24
            case FastDispatcher::METHOD_NOT_ALLOWED:
89 9
                throw new MethodNotAllowedException();
90
        }
91 23
        $route = $this->routeMap[$routeInfo[1]];
92 23
        foreach ($routeInfo[2] as $key => $value) {
93 5
            $request = $request->withAttribute($key, $value);
94
        }
95
        
96 23
        return $route->execute($request, $loader, $responsifier);
97
    }
98
}
99