Completed
Push — master ( 7dba56...6875ae )
by Oscar
10:21
created

AuraRouter::__invoke()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 34
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
c 4
b 0
f 1
dl 0
loc 34
rs 8.439
cc 6
eloc 19
nc 6
nop 3
1
<?php
2
3
namespace Psr7Middlewares\Middleware;
4
5
use Psr7Middlewares\Utils;
6
use Psr7Middlewares\Middleware;
7
use Aura\Router\RouterContainer;
8
use Aura\Router\Route;
9
use Psr\Http\Message\ServerRequestInterface;
10
use Psr\Http\Message\ResponseInterface;
11
use RuntimeException;
12
13
class AuraRouter
14
{
15
    use Utils\CallableTrait;
16
17
    const KEY = 'AURA_ROUTE';
18
19
    /**
20
     * @var RouterContainer|null The router container
21
     */
22
    private $router;
23
24
    /**
25
     * Returns the route instance.
26
     *
27
     * @param ServerRequestInterface $request
28
     *
29
     * @return Route|null
30
     */
31
    public static function getRoute(ServerRequestInterface $request)
32
    {
33
        return Middleware::getAttribute($request, self::KEY);
34
    }
35
36
    /**
37
     * Constructor.Set the RouterContainer instance.
38
     *
39
     * @param RouterContainer $router
40
     */
41
    public function __construct(RouterContainer $router = null)
42
    {
43
        if ($router !== null) {
44
            $this->router($router);
45
        }
46
    }
47
48
    /**
49
     * Extra arguments passed to the controller.
50
     *
51
     * @param RouterContainer $router
52
     *
53
     * @return self
54
     */
55
    public function router(RouterContainer $router)
56
    {
57
        $this->router = $router;
58
59
        return $this;
60
    }
61
62
    /**
63
     * Execute the middleware.
64
     *
65
     * @param ServerRequestInterface $request
66
     * @param ResponseInterface      $response
67
     * @param callable               $next
68
     *
69
     * @return ResponseInterface
70
     */
71
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
72
    {
73
        if (empty($this->router)) {
74
            throw new RuntimeException('No RouterContainer instance has been provided');
75
        }
76
77
        $matcher = $this->router->getMatcher();
78
        $route = $matcher->match($request);
79
80
        if (!$route) {
81
            $failedRoute = $matcher->getFailedRoute();
82
83
            switch ($failedRoute->failedRule) {
84
                case 'Aura\Router\Rule\Allows':
85
                    return $response->withStatus(405); // 405 METHOD NOT ALLOWED
86
87
                case 'Aura\Router\Rule\Accepts':
88
                    return $response->withStatus(406); // 406 NOT ACCEPTABLE
89
90
                default:
91
                    return $response->withStatus(404); // 404 NOT FOUND
92
            }
93
        }
94
95
        $request = Middleware::setAttribute($request, self::KEY, $route);
96
97
        foreach ($route->attributes as $name => $value) {
98
            $request = $request->withAttribute($name, $value);
99
        }
100
101
        $response = $this->executeCallable($route->handler, $request, $response);
102
103
        return $next($request, $response);
104
    }
105
}
106