Dispatcher   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 16
Bugs 2 Features 0
Metric Value
wmc 22
eloc 63
c 16
b 2
f 0
dl 0
loc 125
ccs 64
cts 64
cp 1
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A handle() 0 4 1
A requestWithRouteAttributes() 0 9 2
A ensureHandlerIsRoute() 0 7 2
A setMethodNotAllowedDecoratorMiddleware() 0 10 2
A dispatchRequest() 0 28 5
A setNotFoundDecoratorMiddleware() 0 10 2
B setFoundMiddleware() 0 35 8
1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\Route;
6
7
use FastRoute\Dispatcher as FastRoute;
8
use FastRoute\Dispatcher\GroupCountBased as GroupCountBasedDispatcher;
9
use League\Route\Http\Exception\{MethodNotAllowedException, NotFoundException};
10
use League\Route\Middleware\{MiddlewareAwareInterface, MiddlewareAwareTrait};
11
use League\Route\Strategy\{StrategyAwareInterface, StrategyAwareTrait, StrategyInterface};
12
use Psr\Http\Message\{ResponseInterface, ServerRequestInterface};
13
use Psr\Http\Server\RequestHandlerInterface;
14
use RuntimeException;
15
16
class Dispatcher extends GroupCountBasedDispatcher implements
17
    MiddlewareAwareInterface,
18
    RequestHandlerInterface,
19
    RouteConditionHandlerInterface,
20
    StrategyAwareInterface
21
{
22
    use MiddlewareAwareTrait;
23
    use RouteConditionHandlerTrait;
24
    use StrategyAwareTrait;
25
26 84
    public function dispatchRequest(ServerRequestInterface $request): ResponseInterface
27
    {
28 84
        $method = $request->getMethod();
29 84
        $uri    = $request->getUri()->getPath();
30 84
        $match  = $this->dispatch($method, $uri);
31
32 84
        switch ($match[0]) {
33 84
            case FastRoute::NOT_FOUND:
34 21
                $this->setNotFoundDecoratorMiddleware();
35 18
                break;
36 63
            case FastRoute::METHOD_NOT_ALLOWED:
37 9
                $allowed = (array) $match[1];
38 9
                $this->setMethodNotAllowedDecoratorMiddleware($allowed);
39 6
                break;
40 54
            case FastRoute::FOUND:
41 54
                $route = $this->ensureHandlerIsRoute($match[1], $method, $uri)->setVars($match[2]);
42
43 54
                if ($this->isExtraConditionMatch($route, $request)) {
44 51
                    $this->setFoundMiddleware($route);
45 48
                    $request = $this->requestWithRouteAttributes($request, $route);
46 48
                    break;
47
                }
48
49 3
                $this->setNotFoundDecoratorMiddleware();
50 3
                break;
51
        }
52
53 75
        return $this->handle($request);
54
    }
55
56 75
    public function handle(ServerRequestInterface $request): ResponseInterface
57
    {
58 75
        $middleware = $this->shiftMiddleware();
59 75
        return $middleware->process($request, $this);
60
    }
61
62 54
    protected function ensureHandlerIsRoute($matchingHandler, $httpMethod, $uri): Route
63
    {
64 54
        if ($matchingHandler instanceof Route) {
65 51
            return $matchingHandler;
66
        }
67
68 3
        return new Route($httpMethod, $uri, $matchingHandler);
69
    }
70
71 48
    protected function requestWithRouteAttributes(ServerRequestInterface $request, Route $route): ServerRequestInterface
72
    {
73 48
        $routerParams = $route->getVars();
74
75 48
        foreach ($routerParams as $key => $value) {
76 18
            $request = $request->withAttribute($key, $value);
77
        }
78
79 48
        return $request;
80
    }
81
82 51
    protected function setFoundMiddleware(Route $route): void
83
    {
84 51
        if ($route->getStrategy() === null) {
85 9
            $strategy = $this->getStrategy();
86
87 9
            if (!($strategy instanceof StrategyInterface)) {
88 3
                throw new RuntimeException('Cannot determine strategy to use for dispatch of found route');
89
            }
90
91 6
            $route->setStrategy($strategy);
92
        }
93
94 48
        $strategy  = $route->getStrategy();
95 48
        $container = $strategy instanceof ContainerAwareInterface ? $strategy->getContainer() : null;
96
97 48
        foreach ($this->getMiddlewareStack() as $key => $middleware) {
98 3
            $this->middleware[$key] = $this->resolveMiddleware($middleware, $container);
99
        }
100
101
        // wrap entire dispatch process in exception handler
102 48
        $this->prependMiddleware($strategy->getThrowableHandler());
103
104
        // add group and route specific middleware
105 48
        if ($group = $route->getParentGroup()) {
106 6
            foreach ($group->getMiddlewareStack() as $middleware) {
107 3
                $this->middleware($this->resolveMiddleware($middleware, $container));
108
            }
109
        }
110
111 48
        foreach ($route->getMiddlewareStack() as $middleware) {
112 3
            $this->middleware($this->resolveMiddleware($middleware, $container));
113
        }
114
115
        // add actual route to end of stack
116 48
        $this->middleware($route);
117 48
    }
118
119 9
    protected function setMethodNotAllowedDecoratorMiddleware(array $allowed): void
120
    {
121 9
        $strategy = $this->getStrategy();
122
123 9
        if (!($strategy instanceof StrategyInterface)) {
124 3
            throw new RuntimeException('Cannot determine strategy to use for dispatch of method not allowed route');
125
        }
126
127 6
        $middleware = $strategy->getMethodNotAllowedDecorator(new MethodNotAllowedException($allowed));
128 6
        $this->prependMiddleware($middleware);
129 6
    }
130
131 24
    protected function setNotFoundDecoratorMiddleware(): void
132
    {
133 24
        $strategy = $this->getStrategy();
134
135 24
        if (!($strategy instanceof StrategyInterface)) {
136 3
            throw new RuntimeException('Cannot determine strategy to use for dispatch of not found route');
137
        }
138
139 21
        $middleware = $strategy->getNotFoundDecorator(new NotFoundException());
140 21
        $this->prependMiddleware($middleware);
141 21
    }
142
}
143