Completed
Push — master ( fa7c53...535778 )
by Matze
04:38
created

AppKernel::setMiddlewares()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace BrainExe\Core\Application;
4
5
use BrainExe\Annotations\Annotations\Inject;
6
use BrainExe\Annotations\Annotations\Service;
7
use BrainExe\Core\Middleware\MiddlewareInterface;
8
use Exception;
9
use Symfony\Component\HttpFoundation\JsonResponse;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\HttpFoundation\Response;
12
use Symfony\Component\HttpKernel\HttpKernelInterface;
13
14
/**
15
 * @Service(public=true)
16
 */
17
class AppKernel implements HttpKernelInterface
18
{
19
20
    /**
21
     * @var SerializedRouteCollection
22
     */
23
    private $routes;
24
25
    /**
26
     * @var ControllerResolver
27
     */
28
    private $resolver;
29
30
    /**
31
     * @var MiddlewareInterface[]
32
     */
33
    private $middlewares;
34
35
    /**
36
     * @var UrlMatcher
37
     */
38
    private $urlMatcher;
39
40
    /**
41
     * @Inject({
42
     *     "@ControllerResolver",
43
     *     "@Core.RouteCollection",
44
     *     "@UrlMatcher",
45
     *     null
46 3
     * })
47
     * @param ControllerResolver $resolver
48
     * @param SerializedRouteCollection $routes
49
     * @param UrlMatcher $urlMatcher
50
     * @param MiddlewareInterface[] $middlewares
51 3
     */
52 3
    public function __construct(
53 3
        ControllerResolver $resolver,
54 3
        SerializedRouteCollection $routes,
55
        UrlMatcher $urlMatcher,
56
        array $middlewares
57
    ) {
58
        $this->resolver    = $resolver;
59 3
        $this->routes      = $routes;
60
        $this->urlMatcher  = $urlMatcher;
61 3
        $this->middlewares = $middlewares;
62 3
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67 3
    public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
68
    {
69 3
        $response = null;
70
71
        try {
72 3
            $response = $this->handleRequest($request);
73 1
        } catch (Exception $exception) {
74 1
            $response = $this->applyExceptionMiddleware($request, $exception);
75
        }
76
77 3
        $response = $this->prepareResponse($response);
78
79 3
        $this->applyResponseMiddleware($request, $response);
80
81 3
        return $response;
82
    }
83
84
    /**
85
     * @param Request $request
86
     * @return Response|mixed
87
     */
88 3
    private function handleRequest(Request $request)
89
    {
90 3
        // match route and set attributes in request object
91
        $attributes = $this->urlMatcher->match($request);
92 2
        $request->attributes->replace($attributes);
93
94 2
        $routeName = $attributes['_route'];
95 2
        $route     = $this->routes->get($routeName);
96
97 2
        foreach ($this->middlewares as $middleware) {
98 2
            $response = $middleware->processRequest($request, $route);
99 2
            if ($response) {
100
                // e.g. RedirectResponse or rendered error page
101 2
                return $response;
102
            }
103
        }
104
105
        /** @var callable $callable */
106 1
        $callable  = $this->resolver->getController($request);
107 1
        $arguments = $this->resolver->getArguments($request, $callable);
108
109 1
        return $callable(...$arguments);
110
    }
111
112
    /**
113
     * @param Response|mixed $response
114
     * @return Response
115
     */
116 3
    private function prepareResponse($response)
117
    {
118 3
        if (!$response instanceof Response) {
119 1
            return new JsonResponse($response);
120
        }
121
122 2
        return $response;
123
    }
124
125
    /**
126
     * @param Request $request
127
     * @param Response $response
128
     */
129 3
    protected function applyResponseMiddleware(Request $request, Response $response)
130
    {
131 3
        $middlewareIdx = count($this->middlewares) - 1;
132 3
        for ($i = $middlewareIdx; $i >= 0; $i--) {
133 3
            $middleware = $this->middlewares[$i];
134 3
            $middleware->processResponse($request, $response);
135
        }
136 3
    }
137
138
    /**
139
     * @param Request $request
140
     * @param Exception $exception
141
     * @return Response|null
142
     */
143 1
    protected function applyExceptionMiddleware(Request $request, Exception $exception)
144
    {
145 1
        foreach ($this->middlewares as $middleware) {
146 1
            $response = $middleware->processException($request, $exception);
147 1
            if ($response !== null) {
148 1
                return $response;
149
            }
150
        }
151
152
        return null;
153
    }
154
}
155