Passed
Push — master ( 6a1ee3...4881ab )
by Mikael
01:30
created

Request::setBody()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Anax\Request;
4
5
/**
6
 * Storing information from the request and calculating related essentials.
7
 *
8
 */
9
class Request
10
{
11
    /**
12
     * @var string $requestUri Request URI from $_SERVER.
13
     * @var string $scriptName Scriptname from $_SERVER, actual scriptname part.
14
     * @var string $path       Scriptname from $_SERVER, path-part.
15
     */
16
    private $requestUri;
17
    private $scriptName;
18
    private $path;
19
20
21
22
    /**
23
     * @var string $route      The route.
24
     * @var array  $routeParts The route as an array.
25
     */
26
    private $route;
27
    private $routeParts;
28
29
30
31
    /**
32
     * @var string $currentUrl Current url.
33
     * @var string $siteUrl    Url to this site, http://dbwebb.se.
34
     * @var string $baseUrl    Url to root dir,
35
     *                         siteUrl . /some/installation/directory/.
36
     */
37
    private $currentUrl;
38
    private $siteUrl;
39
    private $baseUrl;
40
41
42
43
    /**
44
     * @var string $server Mapped to $_SERVER.
45
     * @var string $get    Mapped to $_GET.
46
     * @var string $post   Mapped to $_POST.
47
     * @var string $body   Mapped to request body, defaults to php://input.
48
     */
49
    private $server;
50
    private $get;
51
    private $post;
52
    private $body;
53
54
55
56
    /**
57
     * Constructor.
58
     */
59 27
    public function __construct()
60
    {
61 27
        $this->setGlobals();
62 27
    }
63
64
65
66
    /**
67
     * Read info from the globals.
68
     *
69
     * @param array $globals use to initiate globals with values.
70
     *
71
     * @return void
72
     */
73 27
    public function setGlobals($globals = [])
74
    {
75 27
        $this->server = isset($globals["server"])
76 27
            ? array_merge($_SERVER, $globals["server"])
77 27
            : $_SERVER;
78
79 27
        $this->get = isset($globals["get"])
80 27
            ? array_merge($_GET, $globals["get"])
81
            : $_GET;
82
83 27
        $this->post = isset($globals["post"])
84 27
            ? array_merge($_POST, $globals["post"])
85
            : $_POST;
86 27
    }
87
88
89
90
    /**
91
     * Init the request class by reading information from the request.
92
     *
93
     * @return $this
94
     */
95 10
    public function init()
96
    {
97 10
        $this->requestUri = rawurldecode($this->getServer("REQUEST_URI"));
98 10
        $scriptName = rawurldecode($this->getServer("SCRIPT_NAME"));
99 10
        $this->path = rtrim(dirname($scriptName), "/");
100 10
        $this->scriptName = basename($scriptName);
101
102
        // The route and its parts
103 10
        $this->extractRoute();
104
105
        // Prepare to create siteUrl and baseUrl by using currentUrl
106 10
        $this->currentUrl = $this->getCurrentUrl();
107 10
        $parts = parse_url($this->currentUrl);
108 10
        $this->siteUrl = "{$parts["scheme"]}://{$parts["host"]}"
109 10
            . (isset($parts["port"])
110 10
                ? ":{$parts["port"]}"
111 10
                : "");
112 10
        $this->baseUrl = $this->siteUrl . $this->path;
113
114 10
        return $this;
115
    }
116
117
118
119
    /**
120
     * Get site url.
121
     *
122
     * @return string
123
     */
124 4
    public function getSiteUrl()
125
    {
126 4
        return $this->siteUrl;
127
    }
128
129
130
131
    /**
132
     * Get base url.
133
     *
134
     * @return string
135
     */
136 4
    public function getBaseUrl()
137
    {
138 4
        return $this->baseUrl;
139
    }
140
141
142
143
    /**
144
     * Get script name.
145
     *
146
     * @return string
147
     */
148
    public function getScriptName()
149
    {
150
        return $this->scriptName;
151
    }
152
153
154
155
    /**
156
     * Get route parts.
157
     *
158
     * @return array with route in its parts
159
     */
160
    public function getRouteParts()
161
    {
162
        return $this->routeParts;
163
    }
164
165
166
167
    /**
168
     * Get the route.
169
     *
170
     * @return string as the current extracted route
171
     */
172 6
    public function getRoute()
173
    {
174 6
        return $this->route;
175
    }
176
177
178
179
    /**
180
     * Get the request method.
181
     *
182
     * @return string as the request method
183
     */
184 5
    public function getMethod()
185
    {
186 5
        return $this->getServer("REQUEST_METHOD");
187
    }
188
189
190
191
    /**
192
     * Extract the part containing the route.
193
     *
194
     * @return string as the current extracted route
195
     */
196 10
    public function extractRoute()
197
    {
198 10
        $requestUri = $this->requestUri;
199 10
        $scriptPath = $this->path;
200 10
        $scriptFile = $this->scriptName;
201
202
        // Compare REQUEST_URI and SCRIPT_NAME as long they match,
203
        // leave the rest as current request.
204 10
        $i = 0;
205 10
        $len = min(strlen($requestUri), strlen($scriptPath));
206
        while ($i < $len
207 10
               && $requestUri[$i] == $scriptPath[$i]
208 10
        ) {
209 10
            $i++;
210 10
        }
211 10
        $route = trim(substr($requestUri, $i), "/");
212
213
        // Does the request start with script-name - remove it.
214 10
        $len1 = strlen($route);
215 10
        $len2 = strlen($scriptFile);
216
217
        if ($len2 <= $len1
218 10
            && substr_compare($scriptFile, $route, 0, $len2, true) === 0
219 10
        ) {
220 10
            $route = substr($route, $len2 + 1);
221 10
        }
222
223
        // Remove the ?-part from the query when analysing controller/metod/arg1/arg2
224 10
        $queryPos = strpos($route, "?");
225 10
        if ($queryPos !== false) {
226
            $route = substr($route, 0, $queryPos);
227
        }
228
229 10
        $route = ($route === false) ? "" : $route;
230
231 10
        $this->route = $route;
232 10
        $this->routeParts = explode("/", trim($route, "/"));
233
234 10
        return $this->route;
235
    }
236
237
238
239
    /**
240
     * Get the current url.
241
     *
242
     * @param boolean $queryString attach query string, default is true.
243
     *
244
     * @return string as current url.
245
     */
246 25
    public function getCurrentUrl($queryString = true)
247
    {
248 25
        $port  = $this->getServer("SERVER_PORT");
249 25
        $https = $this->getServer("HTTPS") == "on" ? true : false;
250
251
        $scheme = $https
252 25
            ? "https"
253 25
            : $this->getServer("REQUEST_SCHEME", "http");
254
255 25
        $server = $this->getServer("SERVER_NAME")
256 25
            ?: $this->getServer("HTTP_HOST");
257
258 25
        $port  = ($port === "80")
259 25
            ? ""
260 25
            : (($port == 443 && $https)
261 10
                ? ""
262 25
                : ":" . $port);
263
264 25
        $uri = rawurldecode($this->getServer("REQUEST_URI"));
265
        $uri = $queryString
266 25
            ? rtrim($uri, "/")
267 25
            : rtrim(strtok($uri, "?"), "/");
268
269 25
        $url  = htmlspecialchars($scheme) . "://";
270 25
        $url .= htmlspecialchars($server)
271 25
            . $port . htmlspecialchars(rawurldecode($uri));
272
273 25
        return $url;
274
    }
275
276
277
278
    /**
279
     * Get a value from the _SERVER array and use default if it is not set.
280
     *
281
     * @param string $key     to check if it exists in the $_SERVER variable
282
     * @param string $default value to return as default
283
     *
284
     * @return mixed
285
     */
286 26
    public function getServer($key, $default = null)
287
    {
288 26
        return isset($this->server[$key]) ? $this->server[$key] : $default;
289
    }
290
291
292
293
    /**
294
     * Set variable in the server array.
295
     *
296
     * @param mixed  $key   the key an the , or an key-value array
297
     * @param string $value the value of the key
298
     *
299
     * @return self
300
     */
301 19 View Code Duplication
    public function setServer($key, $value = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
302
    {
303 19
        if (is_array($key)) {
304
            $this->server = array_merge($this->server, $key);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge($this->server, $key) of type array is incompatible with the declared type string of property $server.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
305
        } else {
306 19
            $this->server[$key] = $value;
307
        }
308 19
        return $this;
309
    }
310
311
312
313
    /**
314
     * Get a value from the _GET array and use default if it is not set.
315
     *
316
     * @param string $key     to check if it exists in the $_GET variable
317
     * @param string $default value to return as default
318
     *
319
     * @return mixed
320
     */
321 1
    public function getGet($key, $default = null)
322
    {
323 1
        return isset($this->get[$key]) ? $this->get[$key] : $default;
324
    }
325
326
327
328
    /**
329
     * Set variable in the get array.
330
     *
331
     * @param mixed  $key   the key an the , or an key-value array
332
     * @param string $value the value of the key
333
     *
334
     * @return self
335
     */
336 1 View Code Duplication
    public function setGet($key, $value = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
337
    {
338 1
        if (is_array($key)) {
339
            $this->get = array_merge($this->get, $key);
340
        } else {
341 1
            $this->get[$key] = $value;
342
        }
343 1
        return $this;
344
    }
345
346
347
348
    /**
349
     * Get a value from the _POST array and use default if it is not set.
350
     *
351
     * @param string $key     to check if it exists in the $_POST variable
352
     * @param string $default value to return as default
353
     *
354
     * @return mixed
355
     */
356
    public function getPost($key = null, $default = null)
357
    {
358
        if ($key) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $key of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
359
            return isset($this->post[$key]) ? $this->post[$key] : $default;
360
        }
361
362
        return $this->post;
363
    }
364
365
366
367
    /**
368
     * Set the request body (useful for unit testing).
369
     *
370
     * @return self
371
     */
372
    public function setBody($body)
373
    {
374
        $this->body = $body;
375
    }
376
377
378
379
    /**
380
     * Get the request body.
381
     *
382
     * @return mixed
383
     */
384
    public function getBody()
385
    {
386
        return isset($this->body)
387
            ? $this->body
388
            : file_get_contents("php://input");
389
    }
390
}
391