Completed
Push — master ( e98977...d8077f )
by Gianluca
02:11
created

Dispatcher::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4286
cc 1
eloc 3
nc 1
nop 2
crap 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 32
    public function __construct(BaseDispatcher $router, ContainerInterface $container)
37
    {
38 32
        $this->router = $router;
39 32
        $this->container = $container;
40 32
    }
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 30
    public function __invoke(RequestInterface $request)
55
    {
56 30
        $router = $this->router;
57 30
        $uri = $request->getUri();
58
59 30
        $dispatch = $router->dispatch(
60 30
            $request->getMethod(),
61 30
            $uri->getPath()
62 15
        );
63
64 30
        switch ($dispatch[0]) {
65 30
            case BaseDispatcher::NOT_FOUND:
66 4
                throw new RouteNotFoundException();
67 26
            case BaseDispatcher::METHOD_NOT_ALLOWED:
68 4
                throw new MethodNotAllowedException();
69 22
            case BaseDispatcher::FOUND:
70 20
                return $this->processRouteInfo($dispatch);
71 1
            default:
72 2
                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 20
    private function processRouteInfo(array $dispatch)
84
    {
85 20
        $controller = $this->container->get($dispatch[1][0]);
86 20
        $method = $dispatch[1][1];
87 20
        $params = $dispatch[2];
88 20
        $function = strtolower((new ReflectionClass($controller))->getShortName());
89 20
        $eventName = "{$function}.{$method}"; // this improve ~1us
90
91 20
        return new RouteInfo($eventName, [$controller, $method], $params);
92
    }
93
}
94