1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Almendra\Http\Psr\Messages; |
4
|
|
|
|
5
|
|
|
use Psr\Http\Message\RequestInterface; |
6
|
|
|
use Psr\Http\Message\UriInterface; |
7
|
|
|
use Almendra\Http\Psr\Messages\Environment; |
8
|
|
|
|
9
|
|
|
use Almendra\Http\Server; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Represents an incomming request. |
13
|
|
|
* Server specific methods are left to ServerRequest. |
14
|
|
|
* |
15
|
|
|
* @package Almendra\Http |
16
|
|
|
* @author author <email> |
17
|
|
|
*/ |
18
|
|
|
class Request extends Message implements RequestInterface |
19
|
|
|
{ |
20
|
|
|
protected $_target; |
21
|
|
|
protected $_method; |
22
|
|
|
protected $_Uri; |
23
|
|
|
protected $_params = []; |
24
|
|
|
|
25
|
|
|
protected $_contentType; |
26
|
|
|
|
27
|
|
|
protected $_scriptName; |
28
|
|
|
protected $_queryString; |
29
|
|
|
protected $_serverName; |
30
|
|
|
protected $_serverPort; |
31
|
|
|
protected $_host; |
32
|
|
|
protected $_accept; |
33
|
|
|
protected $_acceptLanguage; |
34
|
|
|
protected $_acceptCharset; |
35
|
|
|
protected $_userAgent; |
36
|
|
|
protected $_remoteAddr; |
37
|
|
|
protected $_time; |
38
|
|
|
protected $_timeFloat; |
39
|
|
|
|
40
|
|
|
protected $_fields = []; |
41
|
|
|
|
42
|
|
|
|
43
|
|
|
public function __construct(UriInterface $uri = null) |
44
|
|
|
{ |
45
|
|
|
if (isset($uri) && $uri !== null) { |
46
|
|
|
$this -> setUri($uri); |
47
|
|
|
} |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
public function createFromEnvironment(Environment $environment) |
51
|
|
|
{ |
52
|
|
|
$params = $environment::init([]); |
53
|
|
|
|
54
|
|
|
// repart values among the properties |
55
|
|
|
foreach ($params as $param => $value) { |
56
|
|
|
// $this -> _params[$param] = $value; // @tmp for debugging |
|
|
|
|
57
|
|
|
$this -> assign($param, $value); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
$this -> fillFields($this -> getMethod()); |
61
|
|
|
|
62
|
|
|
return $this; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* Assign the environmental values to the proper members |
67
|
|
|
* |
68
|
|
|
* @param string $key Environmental value key |
69
|
|
|
* @param string $value Environmental value value |
70
|
|
|
* @return boolean false if failure |
71
|
|
|
*/ |
72
|
|
|
public function assign($key, $value) |
73
|
|
|
{ |
74
|
|
|
switch ($key) { |
75
|
|
|
case 'SCRIPT_NAME': |
76
|
|
|
$this -> _scriptName = $value; |
77
|
|
|
break; |
78
|
|
|
|
79
|
|
|
case 'REQUEST_METHOD': |
80
|
|
|
$this -> setMethod($value); |
81
|
|
|
break; |
82
|
|
|
|
83
|
|
|
case 'REQUEST_URI': |
84
|
|
|
$this -> setUri(new Uri($value)); |
85
|
|
|
break; |
86
|
|
|
|
87
|
|
|
case 'SERVER_PROTOCOL': |
88
|
|
|
$this -> _protocolVersion = $value; |
89
|
|
|
break; |
90
|
|
|
|
91
|
|
|
case 'SCRIPT_NAME': |
92
|
|
|
$this -> _scriptName = $value; |
93
|
|
|
break; |
94
|
|
|
|
95
|
|
|
case 'QUERY_STRING': |
96
|
|
|
$this -> _queryString = $value; |
97
|
|
|
break; |
98
|
|
|
|
99
|
|
|
case 'SERVER_NAME': |
100
|
|
|
$this -> _serverName = $value; |
101
|
|
|
break; |
102
|
|
|
|
103
|
|
|
case 'SERVER_PORT': |
104
|
|
|
$this -> _serverPort = $value; |
105
|
|
|
break; |
106
|
|
|
|
107
|
|
|
case 'HTTP_HOST': |
108
|
|
|
$this -> _host = $value; |
109
|
|
|
break; |
110
|
|
|
|
111
|
|
|
case 'HTTP_ACCEPT': |
112
|
|
|
$this -> _accept = $value; |
113
|
|
|
break; |
114
|
|
|
|
115
|
|
|
case 'HTTP_ACCEPT_LANGUAGE': |
116
|
|
|
$this -> _acceptLanguage = $value; |
117
|
|
|
break; |
118
|
|
|
|
119
|
|
|
case 'HTTP_ACCEPT_CHARSET': |
120
|
|
|
$this -> _acceptCharset = $value; |
121
|
|
|
break; |
122
|
|
|
|
123
|
|
|
case 'HTTP_USER_AGENT': |
124
|
|
|
$this -> _userAgent = $value; |
125
|
|
|
break; |
126
|
|
|
|
127
|
|
|
case 'REMOTE_ADDR': |
128
|
|
|
$this -> _remoteAddr = $value; |
129
|
|
|
break; |
130
|
|
|
|
131
|
|
|
case 'REQUEST_TIME': |
132
|
|
|
$this -> _time = $value; |
133
|
|
|
break; |
134
|
|
|
|
135
|
|
|
case 'REQUEST_TIME_FLOAT': |
136
|
|
|
$this -> _timeFloat = $value; |
137
|
|
|
break; |
138
|
|
|
|
139
|
|
|
case 'CONTENT_TYPE': |
140
|
|
|
$this -> _contentType = $value; |
141
|
|
|
break; |
142
|
|
|
|
143
|
|
|
default: |
144
|
|
|
return false; |
145
|
|
|
break; |
|
|
|
|
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
return true; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Retrieves the message's request target. |
153
|
|
|
* |
154
|
|
|
* Retrieves the message's request-target either as it will appear (for |
155
|
|
|
* clients), as it appeared at request (for servers), or as it was |
156
|
|
|
* specified for the instance (see withRequestTarget()). |
157
|
|
|
* |
158
|
|
|
* In most cases, this will be the origin-form of the composed URI, |
159
|
|
|
* unless a value was provided to the concrete implementation (see |
160
|
|
|
* withRequestTarget() below). |
161
|
|
|
* |
162
|
|
|
* If no URI is available, and no request-target has been specifically |
163
|
|
|
* provided, this method MUST return the string "/". |
164
|
|
|
* |
165
|
|
|
* @return string |
166
|
|
|
*/ |
167
|
|
|
public function getRequestTarget() |
168
|
|
|
{ |
169
|
|
|
// retrieve the target |
170
|
|
|
$target = ('' != $this -> getUri() -> getPath()) ? |
171
|
|
|
$this -> getUri() -> getPath() : |
172
|
|
|
'/'; |
173
|
|
|
|
174
|
|
|
// attach the query parameters |
175
|
|
|
$params = $this -> getUri() -> getQuery(); |
176
|
|
|
if ('' != $params) { |
177
|
|
|
$target .= '?' . $params; |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
return $target; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* Return an instance with the specific request-target. |
185
|
|
|
* |
186
|
|
|
* If the request needs a non-origin-form request-target — e.g., for |
187
|
|
|
* specifying an absolute-form, authority-form, or asterisk-form — |
188
|
|
|
* this method may be used to create an instance with the specified |
189
|
|
|
* request-target, verbatim. |
190
|
|
|
* |
191
|
|
|
* This method MUST be implemented in such a way as to retain the |
192
|
|
|
* immutability of the message, and MUST return an instance that has the |
193
|
|
|
* changed request target. |
194
|
|
|
* |
195
|
|
|
* @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various |
196
|
|
|
* request-target forms allowed in request messages) |
197
|
|
|
* @param mixed $requestTarget |
|
|
|
|
198
|
|
|
* @return static |
199
|
|
|
*/ |
200
|
|
|
public function withRequestTarget($target) |
201
|
|
|
{ |
202
|
|
|
$clone = clone $this; |
203
|
|
|
$clone -> setRequestTarget($target); |
204
|
|
|
|
205
|
|
|
return $clone; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Sets the request-target. |
210
|
|
|
* |
211
|
|
|
* @param string $target |
212
|
|
|
* @return void |
213
|
|
|
*/ |
214
|
|
|
public function setRequestTarget($target) |
215
|
|
|
{ |
216
|
|
|
$this -> _target = $target; |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
/** |
220
|
|
|
* Retrieves the HTTP method of the request. |
221
|
|
|
* |
222
|
|
|
* @return string Returns the request method. |
223
|
|
|
*/ |
224
|
|
|
public function getMethod() |
225
|
|
|
{ |
226
|
|
|
return $this -> _method; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* Overrides the request method. |
231
|
|
|
* |
232
|
|
|
* @param string $method The HTTP method |
233
|
|
|
* @return void |
234
|
|
|
*/ |
235
|
|
|
public function setMethod($method) |
236
|
|
|
{ |
237
|
|
|
$this -> _method = $method; |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
/** |
241
|
|
|
* Return an instance with the provided HTTP method. |
242
|
|
|
* |
243
|
|
|
* While HTTP method names are typically all uppercase characters, HTTP |
244
|
|
|
* method names are case-sensitive and thus implementations SHOULD NOT |
245
|
|
|
* modify the given string. |
246
|
|
|
* |
247
|
|
|
* This method MUST be implemented in such a way as to retain the |
248
|
|
|
* immutability of the message, and MUST return an instance that has the |
249
|
|
|
* changed request method. |
250
|
|
|
* |
251
|
|
|
* @param string $method Case-sensitive method. |
252
|
|
|
* @return static |
253
|
|
|
* @throws \InvalidArgumentException for invalid HTTP methods. |
254
|
|
|
*/ |
255
|
|
|
public function withMethod($method) |
256
|
|
|
{ |
257
|
|
|
$clone = clone $this; |
258
|
|
|
$clone -> setMethod($method); |
259
|
|
|
|
260
|
|
|
return $clone; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** |
264
|
|
|
* Retrieves the URI instance. |
265
|
|
|
* |
266
|
|
|
* This method MUST return a UriInterface instance. |
267
|
|
|
* |
268
|
|
|
* @link http://tools.ietf.org/html/rfc3986#section-4.3 |
269
|
|
|
* @return UriInterface Returns a UriInterface instance |
270
|
|
|
* representing the URI of the request. |
271
|
|
|
*/ |
272
|
|
|
public function getUri() |
273
|
|
|
{ |
274
|
|
|
return $this -> _Uri; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Sets the request URI. |
279
|
|
|
* |
280
|
|
|
* @param UriInterface $uri The URI |
281
|
|
|
* @return void |
282
|
|
|
*/ |
283
|
|
|
public function setUri(UriInterface $uri) |
284
|
|
|
{ |
285
|
|
|
$this -> _Uri = $uri; |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
/** |
289
|
|
|
* Returns an instance with the provided URI. |
290
|
|
|
* |
291
|
|
|
* This method MUST update the Host header of the returned request by |
292
|
|
|
* default if the URI contains a host component. If the URI does not |
293
|
|
|
* contain a host component, any pre-existing Host header MUST be carried |
294
|
|
|
* over to the returned request. |
295
|
|
|
* |
296
|
|
|
* You can opt-in to preserving the original state of the Host header by |
297
|
|
|
* setting `$preserveHost` to `true`. When `$preserveHost` is set to |
298
|
|
|
* `true`, this method interacts with the Host header in the following ways: |
299
|
|
|
* |
300
|
|
|
* - If the Host header is missing or empty, and the new URI contains |
301
|
|
|
* a host component, this method MUST update the Host header in the returned |
302
|
|
|
* request. |
303
|
|
|
* - If the Host header is missing or empty, and the new URI does not contain a |
304
|
|
|
* host component, this method MUST NOT update the Host header in the returned |
305
|
|
|
* request. |
306
|
|
|
* - If a Host header is present and non-empty, this method MUST NOT update |
307
|
|
|
* the Host header in the returned request. |
308
|
|
|
* |
309
|
|
|
* This method MUST be implemented in such a way as to retain the |
310
|
|
|
* immutability of the message, and MUST return an instance that has the |
311
|
|
|
* new UriInterface instance. |
312
|
|
|
* |
313
|
|
|
* @link http://tools.ietf.org/html/rfc3986#section-4.3 |
314
|
|
|
* @param UriInterface $uri New request URI to use. |
315
|
|
|
* @param bool $preserveHost Preserve the original state of the Host header. |
316
|
|
|
* @return static |
317
|
|
|
*/ |
318
|
|
|
public function withUri(UriInterface $uri, $preserveHost = false) |
319
|
|
|
{ |
320
|
|
|
$clone = clone $this; |
321
|
|
|
$clone -> setUri($uri); |
322
|
|
|
|
323
|
|
|
return $clone; |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
/** |
327
|
|
|
* Returns all the request fields. |
328
|
|
|
* |
329
|
|
|
* @return mixed |
330
|
|
|
*/ |
331
|
|
|
public function all() |
332
|
|
|
{ |
333
|
|
|
return $this -> _fields; |
334
|
|
|
} |
335
|
|
|
|
336
|
|
|
/** |
337
|
|
|
* Returns the request field by name corresponding the to GET method. |
338
|
|
|
* Null if none exists. |
339
|
|
|
* |
340
|
|
|
* @param string $name The field's name |
341
|
|
|
* @return mixed |
342
|
|
|
*/ |
343
|
|
View Code Duplication |
public function get($name) |
|
|
|
|
344
|
|
|
{ |
345
|
|
|
if (isset($this -> _fields['get'][$name])) { |
346
|
|
|
return $this -> _fields['get'][$name]; |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
return null; |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
/** |
353
|
|
|
* Returns the request field by name corresponding the to POST method. |
354
|
|
|
* Null if none exists. |
355
|
|
|
* |
356
|
|
|
* @param string $name The field's name |
357
|
|
|
* @return mixed |
358
|
|
|
*/ |
359
|
|
View Code Duplication |
public function post($name) |
|
|
|
|
360
|
|
|
{ |
361
|
|
|
if (isset($this -> _fields['post'][$name])) { |
362
|
|
|
return $this -> _fields['post'][$name]; |
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
return null; |
366
|
|
|
} |
367
|
|
|
|
368
|
|
|
/** |
369
|
|
|
* Returns the request field by name corresponding the to PUT method. |
370
|
|
|
* Null if none exists. |
371
|
|
|
* |
372
|
|
|
* @param string $name The field's name |
373
|
|
|
* @return mixed |
374
|
|
|
*/ |
375
|
|
View Code Duplication |
public function put($name) |
|
|
|
|
376
|
|
|
{ |
377
|
|
|
if (isset($this -> _fields['put'][$name])) { |
378
|
|
|
return $this -> _fields['put'][$name]; |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
return null; |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
/** |
385
|
|
|
* Returns the request field by name corresponding the to DELETE method. |
386
|
|
|
* Null if none exists. |
387
|
|
|
* |
388
|
|
|
* @param string $name The field's name |
389
|
|
|
* @return mixed |
390
|
|
|
*/ |
391
|
|
View Code Duplication |
public function delete($name) |
|
|
|
|
392
|
|
|
{ |
393
|
|
|
if (isset($this -> _fields['delete'][$name])) { |
394
|
|
|
return $this -> _fields['delete'][$name]; |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
return null; |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
/** |
401
|
|
|
* Returns the request file field by name usually found thourgh the $_SERVER super-global. |
402
|
|
|
* Null if none exists. |
403
|
|
|
* |
404
|
|
|
* @param string $name The field's name |
405
|
|
|
* @return mixed |
406
|
|
|
*/ |
407
|
|
View Code Duplication |
public function files($name) |
|
|
|
|
408
|
|
|
{ |
409
|
|
|
if (isset($this -> _fields['files'][$name])) { |
410
|
|
|
return $this -> _fields['files'][$name]; |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
return null; |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
|
417
|
|
|
protected function fillFields($method) |
418
|
|
|
{ |
419
|
|
|
$server = new Server; |
420
|
|
|
$fields = []; |
421
|
|
|
|
422
|
|
|
$fields['files'] = $server -> files() -> all(); |
423
|
|
|
switch ($method) { |
424
|
|
|
case 'GET': |
425
|
|
|
$fields['get'] = $server -> get() -> all(); |
|
|
|
|
426
|
|
|
break; |
427
|
|
|
|
428
|
|
|
case 'POST': |
429
|
|
|
$fields['post'] = $server -> post() -> all(); |
|
|
|
|
430
|
|
|
break; |
431
|
|
|
|
432
|
|
|
default: |
433
|
|
|
throw new \InvalidMethodException("No valid method provided."); |
434
|
|
|
break; |
|
|
|
|
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
$this -> _fields = $fields; |
438
|
|
|
} |
439
|
|
|
} |
440
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.