Router   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 100
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 28
dl 0
loc 100
rs 10
c 2
b 0
f 0
wmc 9

6 Methods

Rating   Name   Duplication   Size   Complexity  
A match() 0 4 1
A setResolver() 0 4 1
A handleResult() 0 11 3
A getParams() 0 4 1
A process() 0 9 2
A __construct() 0 9 1
1
<?php
2
3
/**
4
 * Phoole (PHP7.2+)
5
 *
6
 * @category  Library
7
 * @package   Phoole\Route
8
 * @copyright Copyright (c) 2019 Hong Zhang
9
 */
10
declare(strict_types=1);
11
12
namespace Phoole\Route;
13
14
use Phoole\Route\Util\Result;
15
use Phoole\Route\Util\RouteAwareTrait;
16
use Psr\Http\Message\ResponseInterface;
17
use Psr\Http\Server\MiddlewareInterface;
18
use Phoole\Route\Parser\ParserInterface;
19
use Phoole\Route\Parser\FastRouteParser;
20
use Phoole\Route\Resolver\DefaultResolver;
21
use Psr\Http\Server\RequestHandlerInterface;
22
use Psr\Http\Message\ServerRequestInterface;
23
use Phoole\Route\Resolver\ResolverInterface;
24
25
/**
26
 * Router
27
 *
28
 * @package Phoole\Route
29
 */
30
class Router implements MiddlewareInterface
31
{
32
    use RouteAwareTrait;
33
    /**
34
     * context name used for storing parsed parameters
35
     */
36
    const URI_PARAMETERS = '__parsedParams__';
37
38
    /**
39
     * controller/action name resolver
40
     *
41
     * @var ResolverInterface
42
     */
43
    protected $resolver;
44
45
    /**
46
     * Load route definitions and set the parser
47
     *
48
     * @param  array             $routes    route definitions
49
     * @param  ResolverInterface $resolver  controller/action name resolver
50
     * @param  ParserInterface   $parser    routes parser/matcher
51
     */
52
    public function __construct(
53
        array $routes = [],
54
        ?ResolverInterface $resolver = NULL,
55
        ?ParserInterface $parser = NULL
56
    ) {
57
        $this
58
            ->loadRoutes($routes)
59
            ->setResolver($resolver ?? new DefaultResolver())
60
            ->setParser($parser ?? new FastRouteParser());
61
    }
62
63
    /**
64
     * Middleware compliant
65
     *
66
     * {@inheritDoc}
67
     */
68
    public function process(
69
        ServerRequestInterface $request,
70
        RequestHandlerInterface $handler
71
    ): ResponseInterface {
72
        $result = $this->match($request);
73
        if ($result->isMatched()) {
74
            return $this->handleResult($result);
75
        } else {
76
            return $handler->handle($request);
77
        }
78
    }
79
80
    /**
81
     * Match request with predefined routes, returns a Result object
82
     *
83
     * @param  ServerRequestInterface $request
84
     * @return Result
85
     */
86
    public function match(ServerRequestInterface $request): Result
87
    {
88
        $result = new Result($request);
89
        return $this->routeMatch($result);
90
    }
91
92
    /**
93
     * Utility function for getting parameter values stored in the request
94
     *
95
     * @param  ServerRequestInterface $request
96
     * @return array
97
     */
98
    public static function getParams(ServerRequestInterface $request): array
99
    {
100
        $params = $request->getAttribute(Router::URI_PARAMETERS) ?? [];
101
        return $params;
102
    }
103
104
    /**
105
     * @param  ResolverInterface $resolver
106
     * @return $this
107
     */
108
    protected function setResolver(ResolverInterface $resolver)
109
    {
110
        $this->resolver = $resolver;
111
        return $this;
112
    }
113
114
    /**
115
     * @param  Result $result
116
     * @return ResponseInterface
117
     * @throws \InvalidArgumentException    if resolver failure
118
     */
119
    protected function handleResult(Result $result): ResponseInterface
120
    {
121
        $request = $result->getRequest();
122
        $handler = $result->getHandler();
123
        if (is_callable($handler)) {
124
            return $handler($request);
125
        } elseif ($handler instanceof RequestHandlerInterface) {
126
            return $handler->handle($request);
127
        } else {
128
            $handler = $this->resolver->resolve($handler, self::getParams($request));
129
            return $handler($request);
130
        }
131
    }
132
}