Passed
Push — master ( d7d8c0...c26592 )
by Mads
03:35
created

Router::singleRequest()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 31
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 16
nc 4
nop 5
dl 0
loc 31
ccs 0
cts 17
cp 0
crap 12
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace Napp\Core\Api\Router;
4
5
use Illuminate\Foundation\Application;
6
use Illuminate\Http\Request;
7
use Illuminate\Routing\Router as LaravelRouter;
8
9
class Router
10
{
11
    private $app;
12
13
    private $router;
14
15
    private $request;
16
17
    private $disableMiddleware = false;
18
19
    /**
20
     * @param \Illuminate\Foundation\Application $app
21
     * @param \Illuminate\Http\Request $request,
22
     * @param \Illuminate\Routing\Router $router
23
     */
24
    public function __construct(Application $app, Request $request, LaravelRouter $router)
25
    {
26
        $this->app = $app;
27
        $this->request = $request;
28
        $this->router = $router;
29
    }
30
31
    /**
32
     * @param  string $uri
33
     * @param  array  $data
34
     * @param  array  $headers
35
     * @param  string $content
36
     * @return \Illuminate\Http\Response
37
     */
38
    public function get()
39
    {
40
        return $this->quickCall('GET', func_get_args());
41
    }
42
43
    /**
44
     * @param  string $uri
45
     * @param  array  $data
46
     * @param  array  $headers
47
     * @param  string $content
48
     * @return \Illuminate\Http\Response
49
     */
50
    public function post()
51
    {
52
        return $this->quickCall('POST', func_get_args());
53
    }
54
55
    /**
56
     * @param  string $uri
57
     * @param  array  $data
58
     * @param  array  $headers
59
     * @param  string $content
60
     * @return \Illuminate\Http\Response
61
     */
62
    public function put()
63
    {
64
        return $this->quickCall('PUT', func_get_args());
65
    }
66
67
    /**
68
     * @param  string $uri
69
     * @param  array  $data
70
     * @param  array  $headers
71
     * @param  string $content
72
     * @return \Illuminate\Http\Response
73
     */
74
    public function delete()
75
    {
76
        return $this->quickCall('DELETE', func_get_args());
77
    }
78
79
    /**
80
     * @param  array $requests An array of requests
81
     * @return array
82
     */
83
    public function batchRequest(array $requests)
84
    {
85
        foreach ($requests as $i => $request) {
86
            $requests[$i] = call_user_func_array([$this, 'singleRequest'], $request);
87
        }
88
89
        return $requests;
90
    }
91
92
    /**
93
     * @param  string $method
94
     * @param  array  $args
95
     * @return \Illuminate\Http\Response
96
     */
97
    public function quickCall($method, array $args)
98
    {
99
        array_unshift($args, $method);
100
        return call_user_func_array([$this, "singleRequest"], $args);
101
    }
102
103
    /**
104
     * @param  string $method
105
     * @param  string $uri
106
     * @param  array  $data
107
     * @param  array  $headers
108
     * @param  string $content
109
     * @return \Illuminate\Http\Response
110
     */
111
    public function singleRequest($method, $uri, array $data = [], array $headers = [], $content = null)
112
    {
113
        // Save the current request so we can reset the router back to it
114
        // after we've completed our internal request.
115
        $currentRequest = $this->request->instance()->duplicate();
116
117
        $headers = $this->overrideHeaders($currentRequest->server->getHeaders(), $headers);
118
119
        if ($this->disableMiddleware) {
120
            $this->app->instance('middleware.disable', true);
121
        }
122
123
        $response = $this->request($method, $uri, $data, $headers, $content);
124
125
        if ($this->disableMiddleware) {
126
            $this->app->instance('middleware.disable', false);
127
        }
128
129
        // Once the request has completed we reset the currentRequest of the router
130
        // to match the original request.
131
        $this->request->instance()->initialize(
132
            $currentRequest->query->all(),
133
            $currentRequest->request->all(),
134
            $currentRequest->attributes->all(),
135
            $currentRequest->cookies->all(),
136
            $currentRequest->files->all(),
137
            $currentRequest->server->all(),
138
            $currentRequest->getContent()
139
        );
140
141
        return $response;
142
    }
143
144
    private function overrideHeaders(array $default, array $headers)
145
    {
146
        $headers = $this->transformHeadersToUppercaseUnderscoreType($headers);
147
        return array_merge($default, $headers);
148
    }
149
150
    public function enableMiddleware()
151
    {
152
        $this->disableMiddleware = false;
153
    }
154
155
    public function disableMiddleware()
156
    {
157
        $this->disableMiddleware = true;
158
    }
159
160
    /**
161
     * @param  string $method
162
     * @param  string $uri
163
     * @param  array  $data
164
     * @param  array  $headers
165
     * @param  string $content
166
     * @return \Illuminate\Http\Response
167
     */
168
    private function request($method, $uri, array $data = [], array $headers = [], $content = null)
169
    {
170
        // Create a new request object for the internal request
171
        $request = $this->createRequest($method, $uri, $data, $headers, $content);
172
173
        // Handle the request in the kernel and prepare a response
174
        $response = $this->router->prepareResponse($request, $this->app->handle($request));
175
176
        return $response;
177
    }
178
179
    /**
180
     * @param  string $method
181
     * @param  string $uri
182
     * @param  array  $data
183
     * @param  array  $headers
184
     * @param  string $content
185
     * @return \Illuminate\Http\Request
186
     */
187
    private function createRequest($method, $uri, array $data = [], array $headers = [], $content = null)
188
    {
189
        $server = $this->transformHeadersToServerVariables($headers);
190
191
        return $this->request->create($uri, $method, $data, [], [], $server, $content);
192
    }
193
194
    private function transformHeadersToUppercaseUnderscoreType($headers)
195
    {
196
        $transformed = [];
197
198
        foreach ($headers as $headerType => $headerValue) {
199
            $headerType = strtoupper(str_replace('-', '_', $headerType));
200
201
            $transformed[$headerType] = $headerValue;
202
        }
203
204
        return $transformed;
205
    }
206
207
    /**
208
     * https://github.com/symfony/symfony/issues/5074
209
     *
210
     * @param  array $headers
211
     * @return array
212
     */
213
    private function transformHeadersToServerVariables($headers)
214
    {
215
        $server = [];
216
217
        foreach ($headers as $headerType => $headerValue) {
218
            $headerType = 'HTTP_' . $headerType;
219
220
            $server[$headerType] = $headerValue;
221
        }
222
223
        return $server;
224
    }
225
}
226