Dispatcher   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 7

Test Coverage

Coverage 100%

Importance

Changes 7
Bugs 0 Features 4
Metric Value
wmc 6
c 7
b 0
f 4
lcom 0
cbo 7
dl 0
loc 80
ccs 28
cts 28
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A __invoke() 0 21 4
A processRouteInfo() 0 10 1
1
<?php
2
3
namespace Penny;
4
5
use Interop\Container\ContainerInterface;
6
use Exception;
7
use ReflectionClass;
8
use FastRoute\Dispatcher as BaseDispatcher;
9
use Penny\Exception\MethodNotAllowedException;
10
use Penny\Exception\RouteNotFoundException;
11
use Psr\Http\Message\RequestInterface;
12
use Penny\Route\RouteInfo;
13
14
class Dispatcher
15
{
16
    /**
17
     * Inner dispatcher.
18
     *
19
     * @var BaseDispatcher
20
     */
21
    private $router;
22
23
    /**
24
     * Service Container
25
     *
26
     * @var ContainerInterface
27
     */
28
    private $container;
29
30
    /**
31
     * Class constructor with required FastRoute dispatcher implementation.
32
     *
33
     * @param BaseDispatcher $router Inner router (based on Nikic FastRouter).
34
     * @param ContainerInterface $container Dependency Injection container.
35
     */
36 17
    public function __construct(BaseDispatcher $router, ContainerInterface $container)
37
    {
38 17
        $this->router = $router;
39 17
        $this->container = $container;
40 17
    }
41
42
    /**
43
     * Dispatching.
44
     *
45
     * @param RequestInterface $request Representation of an outgoing,
46
     *                                  client-side request.
47
     *
48
     * @throws RouteNotFoundException    If the route is not found.
49
     * @throws MethodNotAllowedException If the method is not allowed.
50
     * @throws Exception                 If no one case is matched.
51
     *
52
     * @return RouteInfo
53
     */
54 16
    public function __invoke(RequestInterface $request)
55
    {
56 16
        $router = $this->router;
57 16
        $uri = $request->getUri();
58
59 16
        $dispatch = $router->dispatch(
60 16
            $request->getMethod(),
61 16
            $uri->getPath()
62 16
        );
63
64 16
        switch ($dispatch[0]) {
65 16
            case BaseDispatcher::NOT_FOUND:
66 2
                throw new RouteNotFoundException('Route with path '.$uri->getPath().' not found.');
67 14
            case BaseDispatcher::METHOD_NOT_ALLOWED:
68 2
                throw new MethodNotAllowedException('Method '.$request->getMethod().' not allowed.');
69 12
            case BaseDispatcher::FOUND:
70 11
                return $this->processRouteInfo($dispatch);
71 1
            default:
72 1
                throw new Exception(null, 500);
73 1
        }
74
    }
75
76
    /**
77
     * Process RouteInfo instance
78
     *
79
     * @param array $dispatch
80
     *
81
     * @return RouteInfo
82
     */
83 11
    private function processRouteInfo(array $dispatch)
84
    {
85 11
        $controller = $this->container->get($dispatch[1][0]);
86 11
        $method = $dispatch[1][1];
87 11
        $params = $dispatch[2];
88 11
        $function = (new ReflectionClass($controller))->name;
89 11
        $eventName = "{$function}.{$method}"; // this improve ~1us
90
91 11
        return new RouteInfo($eventName, [$controller, $method], $params);
92
    }
93
}
94