Passed
Push — master ( ca348b...1f6505 )
by Marcio
03:43
created

Request   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 246
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 2
Metric Value
wmc 23
eloc 51
c 5
b 0
f 2
dl 0
loc 246
rs 10

16 Methods

Rating   Name   Duplication   Size   Complexity  
A setPostData() 0 3 1
A setBaseUrl() 0 3 1
A setAbsoluteUrl() 0 3 1
A getRawServerValue() 0 3 1
A getQueryParameters() 0 10 2
A getBaseUrl() 0 3 1
A getUrl() 0 3 1
A setUrl() 0 3 1
A __toString() 0 17 4
A getMethod() 0 3 1
A getAbsoluteUrl() 0 10 2
A setMethod() 0 3 1
A __construct() 0 6 1
A getPath() 0 22 3
A setRawServerData() 0 3 1
A getPostData() 0 3 1
1
<?php
2
/**
3
 *
4
 * KNUT7 K7F (https://marciozebedeu.com/)
5
 * KNUT7 K7F (tm) : Rapid Development Framework (https://marciozebedeu.com/)
6
 *
7
 * Licensed under The MIT License
8
 * For full copyright and license information, please see the LICENSE.txt
9
 * Redistributions of files must retain the above copyright notice.
10
 *
11
 * @link      https://github.com/knut7/framework/ for the canonical source repository
12
 * @copyright (c) 2015.  KNUT7  Software Technologies AO Inc. (https://marciozebedeu.com/)
13
 * @license   https://marciozebedeu.com/license/new-bsd New BSD License
14
 * @author    Marcio Zebedeu - [email protected]
15
 * @version   1.0.15
16
 *
17
 *
18
 */
19
20
namespace Ballybran\Core\Http;
21
22
class Request extends Message
23
{
24
    /**
25
     * HTTP Method.
26
     *
27
     * @var string
28
     */
29
    protected $method;
30
31
    /**
32
     * Request Url.
33
     *
34
     * @var string
35
     */
36
    protected $url;
37
38
    /**
39
     * Creates the request object.
40
     *
41
     * @param resource|callable|string $body
42
     */
43
    public function __construct(string $method, string $url, array $headers = [], $body = null)
44
    {
45
        $this->setMethod($method);
46
        $this->setUrl($url);
47
        $this->setHeaders($headers);
48
        $this->setBody($body);
49
    }
50
51
    /**
52
     * Returns the current HTTP method.
53
     */
54
    public function getMethod(): string
55
    {
56
        return $this->method;
57
    }
58
59
    /**
60
     * Sets the HTTP method.
61
     */
62
    public function setMethod(string $method)
63
    {
64
        $this->method = $method;
65
    }
66
67
    /**
68
     * Returns the request url.
69
     */
70
    public function getUrl(): string
71
    {
72
        return $this->url;
73
    }
74
75
    /**
76
     * Sets the request url.
77
     */
78
    public function setUrl(string $url)
79
    {
80
        $this->url = $url;
81
    }
82
83
    /**
84
     * Returns the list of query parameters.
85
     *
86
     * This is equivalent to PHP's $_GET superglobal.
87
     */
88
    public function getQueryParameters(): array
89
    {
90
        $url = $this->getUrl();
91
        if (false === ($index = strpos($url, '?'))) {
92
            return [];
93
        }
94
95
        parse_str(substr($url, $index + 1), $queryParams);
96
97
        return $queryParams;
98
    }
99
100
    protected $absoluteUrl;
101
102
    /**
103
     * Sets the absolute url.
104
     */
105
    public function setAbsoluteUrl(string $url)
106
    {
107
        $this->absoluteUrl = $url;
108
    }
109
110
    /**
111
     * Returns the absolute url.
112
     */
113
    public function getAbsoluteUrl(): string
114
    {
115
        if (!$this->absoluteUrl) {
116
            // Guessing we're a http endpoint.
117
            $this->absoluteUrl = 'http://'.
118
                ($this->getHeader('Host') ?? 'localhost').
119
                $this->getUrl();
120
        }
121
122
        return $this->absoluteUrl;
123
    }
124
125
    /**
126
     * Base url.
127
     *
128
     * @var string
129
     */
130
    protected $baseUrl = '/';
131
132
    /**
133
     * Sets a base url.
134
     *
135
     * This url is used for relative path calculations.
136
     */
137
    public function setBaseUrl(string $url)
138
    {
139
        $this->baseUrl = $url;
140
    }
141
142
    /**
143
     * Returns the current base url.
144
     */
145
    public function getBaseUrl(): string
146
    {
147
        return $this->baseUrl;
148
    }
149
150
    /**
151
     * Returns the relative path.
152
     *
153
     * This is being calculated using the base url. This path will not start
154
     * with a slash, so it will always return something like
155
     * 'example/path.html'.
156
     *
157
     * If the full path is equal to the base url, this method will return an
158
     * empty string.
159
     *
160
     * This method will also urldecode the path, and if the url was incoded as
161
     * ISO-8859-1, it will convert it to UTF-8.
162
     *
163
     * If the path is outside of the base url, a LogicException will be thrown.
164
     */
165
    public function getPath(): string
166
    {
167
        // Removing duplicated slashes.
168
        $uri = str_replace('//', '/', $this->getUrl());
169
170
        $uri = $uri;
171
        $baseUri = $this->getBaseUrl();
172
173
        if (0 === strpos($uri, $baseUri)) {
174
            // We're not interested in the query part (everything after the ?).
175
            list($uri) = explode('?', $uri);
176
177
            return trim(substr($uri, strlen($baseUri)), '/');
178
        }
179
180
        if ($uri.'/' === $baseUri) {
181
            return '';
182
        }
183
        // A special case, if the baseUri was accessed without a trailing
184
        // slash, we'll accept it as well.
185
186
        throw new \LogicException('Requested uri ('.$this->getUrl().') is out of base uri ('.$this->getBaseUrl().')');
187
    }
188
189
    /**
190
     * Equivalent of PHP's $_POST.
191
     *
192
     * @var array
193
     */
194
    protected $postData = [];
195
196
    /**
197
     * Sets the post data.
198
     *
199
     * This is equivalent to PHP's $_POST superglobal.
200
     *
201
     * This would not have been needed, if POST data was accessible as
202
     * php://input, but unfortunately we need to special case it.
203
     */
204
    public function setPostData(array $postData)
205
    {
206
        $this->postData = $postData;
207
    }
208
209
    /**
210
     * Returns the POST data.
211
     *
212
     * This is equivalent to PHP's $_POST superglobal.
213
     */
214
    public function getPostData(): array
215
    {
216
        return $this->postData;
217
    }
218
219
    /**
220
     * An array containing the raw _SERVER array.
221
     *
222
     * @var array
223
     */
224
    protected $rawServerData;
225
226
    /**
227
     * Returns an item from the _SERVER array.
228
     *
229
     * If the value does not exist in the array, null is returned.
230
     *
231
     * @return string|null
232
     */
233
    public function getRawServerValue(string $valueName)
234
    {
235
        return $this->rawServerData[$valueName] ?? null;
236
    }
237
238
    /**
239
     * Sets the _SERVER array.
240
     */
241
    public function setRawServerData(array $data)
242
    {
243
        $this->rawServerData = $data;
244
    }
245
246
    /**
247
     * Serializes the request object as a string.
248
     *
249
     * This is useful for debugging purposes.
250
     */
251
    public function __toString(): string
252
    {
253
        $out = $this->getMethod().' '.$this->getUrl().' HTTP/'.$this->getHttpVersion()."\r\n";
254
255
        foreach ($this->getHeaders() as $key => $value) {
256
            foreach ($value as $v) {
257
                if ('Authorization' === $key) {
258
                    list($v) = explode(' ', $v, 2);
259
                    $v .= ' REDACTED';
260
                }
261
                $out .= $key.': '.$v."\r\n";
262
            }
263
        }
264
        $out .= "\r\n";
265
        $out .= $this->getBodyAsString();
266
267
        return $out;
268
    }
269
}