Completed
Pull Request — master (#7037)
by Damian
09:19
created

HTTPApplication::addMiddleware()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Control;
4
5
use SilverStripe\Core\Application;
6
use SilverStripe\Control\HTTPMiddleware;
7
use SilverStripe\Core\Kernel;
8
9
/**
10
 * Invokes the HTTP application within an ErrorControlChain
11
 */
12
class HTTPApplication implements Application
13
{
14
    /**
15
     * @var HTTPMiddleware[]
16
     */
17
    protected $middlewares = [];
18
19
    /**
20
     * @var Kernel
21
     */
22
    protected $kernel;
23
24
    public function __construct(Kernel $kernel)
25
    {
26
        $this->kernel = $kernel;
27
    }
28
29
    /**
30
     * @return HTTPMiddleware[]
31
     */
32
    public function getMiddlewares()
33
    {
34
        return $this->middlewares;
35
    }
36
37
    /**
38
     * @param HTTPMiddleware[] $middlewares
39
     * @return $this
40
     */
41
    public function setMiddlewares($middlewares)
42
    {
43
        $this->middlewares = $middlewares;
44
        return $this;
45
    }
46
47
    /**
48
     * @param HTTPMiddleware $middleware
49
     * @return $this
50
     */
51
    public function addMiddleware(HTTPMiddleware $middleware)
52
    {
53
        $this->middlewares[] = $middleware;
54
        return $this;
55
    }
56
57
    /**
58
     * Call middleware
59
     *
60
     * @param HTTPRequest $request
61
     * @param callable $last Last config to call
62
     * @return HTTPResponse
63
     */
64
    protected function callMiddleware(HTTPRequest $request, $last)
65
    {
66
        // Reverse middlewares
67
        $next = $last;
68
        /** @var HTTPMiddleware $middleware */
69
        foreach (array_reverse($this->getMiddlewares()) as $middleware) {
70
            $next = function ($request) use ($middleware, $next) {
71
                return $middleware->process($request, $next);
72
            };
73
        }
74
        return call_user_func($next, $request);
75
    }
76
77
    /**
78
     * Get the kernel for this application
79
     *
80
     * @return Kernel
81
     */
82
    public function getKernel()
83
    {
84
        return $this->kernel;
85
    }
86
87
    /**
88
     * Handle the given HTTP request
89
     *
90
     * @param HTTPRequest $request
91
     * @return HTTPResponse
92
     */
93
    public function handle(HTTPRequest $request)
94
    {
95
        $flush = $request->getVar('flush') || strpos($request->getURL(), 'dev/build') === 0;
96
97
        // Ensure boot is invoked
98
        return $this->execute($request, function (HTTPRequest $request) {
99
            // Start session and execute
100
            $request->getSession()->init();
101
            return Director::direct($request);
102
        }, $flush);
103
    }
104
105
    /**
106
     * Safely boot the application and execute the given main action
107
     *
108
     * @param HTTPRequest $request
109
     * @param callable $callback
110
     * @param bool $flush
111
     * @return HTTPResponse
112
     */
113
    public function execute(HTTPRequest $request, callable $callback, $flush = false)
114
    {
115
        try {
116
            return $this->callMiddleware($request, function ($request) use ($callback, $flush) {
117
                // Pre-request boot
118
                $this->getKernel()->boot($flush);
119
                return call_user_func($callback, $request);
120
            });
121
        } catch (HTTPResponse_Exception $ex) {
122
            return $ex->getResponse();
123
        } finally {
124
            $this->getKernel()->shutdown();
125
        }
126
    }
127
}
128