Passed
Push — master ( 7ec6a9...6497a7 )
by Mikael
27s
created

Request::getCurrentUrl()   D

Complexity

Conditions 8
Paths 128

Size

Total Lines 25
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 8

Importance

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