|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Bluz Framework Component |
|
4
|
|
|
* |
|
5
|
|
|
* @copyright Bluz PHP Team |
|
6
|
|
|
* @link https://github.com/bluzphp/framework |
|
7
|
|
|
*/ |
|
8
|
|
|
|
|
9
|
|
|
/** |
|
10
|
|
|
* @namespace |
|
11
|
|
|
*/ |
|
12
|
|
|
namespace Bluz\Proxy; |
|
13
|
|
|
|
|
14
|
|
|
use Bluz\Common\Exception\ComponentException; |
|
15
|
|
|
use Bluz\Request\RequestFactory; |
|
16
|
|
|
use Psr\Http\Message\UriInterface; |
|
17
|
|
|
use Zend\Diactoros\ServerRequest as Instance; |
|
18
|
|
|
|
|
19
|
|
|
/** |
|
20
|
|
|
* Proxy to Request |
|
21
|
|
|
* |
|
22
|
|
|
* Example of usage |
|
23
|
|
|
* <code> |
|
24
|
|
|
* use Bluz\Proxy\Request; |
|
25
|
|
|
* |
|
26
|
|
|
* Request::getParam('foo'); |
|
27
|
|
|
* </code> |
|
28
|
|
|
* |
|
29
|
|
|
* @package Bluz\Proxy |
|
30
|
|
|
* @author Anton Shevchuk |
|
31
|
|
|
* |
|
32
|
|
|
* @todo Proxy class should be clean |
|
33
|
|
|
* |
|
34
|
|
|
* @method static Instance getInstance() |
|
35
|
|
|
* |
|
36
|
|
|
* @method static UriInterface getUri() |
|
37
|
|
|
* @see \Zend\Diactoros\RequestTrait::getUri() |
|
38
|
|
|
*/ |
|
39
|
|
|
class Request |
|
40
|
|
|
{ |
|
41
|
|
|
use ProxyTrait; |
|
42
|
|
|
|
|
43
|
|
|
/** |
|
44
|
|
|
* @const string HTTP methods |
|
45
|
|
|
*/ |
|
46
|
|
|
const METHOD_OPTIONS = 'OPTIONS'; |
|
47
|
|
|
const METHOD_GET = 'GET'; |
|
48
|
|
|
const METHOD_HEAD = 'HEAD'; |
|
49
|
|
|
const METHOD_PATCH = 'PATCH'; |
|
50
|
|
|
const METHOD_POST = 'POST'; |
|
51
|
|
|
const METHOD_PUT = 'PUT'; |
|
52
|
|
|
const METHOD_DELETE = 'DELETE'; |
|
53
|
|
|
const METHOD_TRACE = 'TRACE'; |
|
54
|
|
|
const METHOD_CONNECT = 'CONNECT'; |
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* @const string HTTP content types |
|
58
|
|
|
*/ |
|
59
|
|
|
const TYPE_ANY = '*/*'; |
|
60
|
|
|
const TYPE_HTML = 'text/html'; |
|
61
|
|
|
const TYPE_JSON = 'application/json'; |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* Init instance |
|
65
|
|
|
* |
|
66
|
|
|
* @throws ComponentException |
|
67
|
|
|
*/ |
|
68
|
|
|
protected static function initInstance() |
|
69
|
|
|
{ |
|
70
|
|
|
throw new ComponentException("Class `Proxy\\Request` required external initialization"); |
|
71
|
|
|
} |
|
72
|
|
|
|
|
73
|
|
|
/** |
|
74
|
|
|
* Retrieve a member of the $_GET super global |
|
75
|
|
|
* |
|
76
|
|
|
* If no $key is passed, returns the entire $_GET array. |
|
77
|
|
|
* |
|
78
|
|
|
* @param string $key |
|
79
|
|
|
* @param string $default Default value to use if key not found |
|
80
|
|
|
* @return string Returns null if key does not exist |
|
81
|
|
|
*/ |
|
82
|
45 |
|
public static function getQuery($key = null, $default = null) |
|
83
|
|
|
{ |
|
84
|
45 |
|
return RequestFactory::get($key, self::getInstance()->getQueryParams(), $default); |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
/** |
|
88
|
|
|
* Retrieve a member of the $_POST super global |
|
89
|
|
|
* |
|
90
|
|
|
* If no $key is passed, returns the entire $_POST array. |
|
91
|
|
|
* |
|
92
|
|
|
* @param string $key |
|
93
|
|
|
* @param string $default Default value to use if key not found |
|
94
|
|
|
* @return string Returns null if key does not exist |
|
95
|
|
|
*/ |
|
96
|
42 |
|
public static function getPost($key = null, $default = null) |
|
97
|
|
|
{ |
|
98
|
42 |
|
return RequestFactory::get($key, self::getInstance()->getParsedBody(), $default); |
|
|
|
|
|
|
99
|
|
|
} |
|
100
|
|
|
|
|
101
|
|
|
/** |
|
102
|
|
|
* Retrieve a member of the $_SERVER super global |
|
103
|
|
|
* |
|
104
|
|
|
* If no $key is passed, returns the entire $_SERVER array. |
|
105
|
|
|
* |
|
106
|
|
|
* @param string $key |
|
107
|
|
|
* @param string $default Default value to use if key not found |
|
108
|
|
|
* @return string Returns null if key does not exist |
|
109
|
|
|
*/ |
|
110
|
43 |
|
public static function getServer($key = null, $default = null) |
|
111
|
|
|
{ |
|
112
|
43 |
|
return RequestFactory::get($key, self::getInstance()->getServerParams(), $default); |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* Retrieve a member of the $_COOKIE super global |
|
117
|
|
|
* |
|
118
|
|
|
* If no $key is passed, returns the entire $_COOKIE array. |
|
119
|
|
|
* |
|
120
|
|
|
* @param string $key |
|
121
|
|
|
* @param string $default Default value to use if key not found |
|
122
|
|
|
* @return string Returns null if key does not exist |
|
123
|
|
|
*/ |
|
124
|
40 |
|
public static function getCookie($key = null, $default = null) |
|
125
|
|
|
{ |
|
126
|
40 |
|
return RequestFactory::get($key, self::getInstance()->getCookieParams(), $default); |
|
127
|
|
|
} |
|
128
|
|
|
/** |
|
129
|
|
|
* Retrieve a member of the $_ENV super global |
|
130
|
|
|
* |
|
131
|
|
|
* If no $key is passed, returns the entire $_ENV array. |
|
132
|
|
|
* |
|
133
|
|
|
* @param string $key |
|
134
|
|
|
* @param string $default Default value to use if key not found |
|
135
|
|
|
* @return string Returns null if key does not exist |
|
136
|
|
|
*/ |
|
137
|
|
|
public static function getEnv($key = null, $default = null) |
|
138
|
|
|
{ |
|
139
|
|
|
return RequestFactory::get($key, $_ENV, $default); |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
/** |
|
143
|
|
|
* Search for a header value |
|
144
|
|
|
* |
|
145
|
|
|
* @param string $header |
|
146
|
|
|
* @param mixed $default |
|
147
|
|
|
* @return string |
|
148
|
|
|
*/ |
|
149
|
2 |
|
public static function getHeader($header, $default = null) |
|
150
|
|
|
{ |
|
151
|
2 |
|
return RequestFactory::getHeader($header, self::getInstance()->getHeaders(), $default); |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
/** |
|
155
|
|
|
* Access values contained in the superglobals as public members |
|
156
|
|
|
* Order of precedence: 1. GET, 2. POST, 3. COOKIE, 4. SERVER, 5. ENV |
|
157
|
|
|
* |
|
158
|
|
|
* @param string $key |
|
159
|
|
|
* @param null $default |
|
160
|
|
|
* @return mixed |
|
161
|
|
|
* @link http://msdn.microsoft.com/en-us/library/system.web.httprequest.item.aspx |
|
162
|
|
|
*/ |
|
163
|
45 |
|
public static function getParam($key, $default = null) |
|
164
|
|
|
{ |
|
165
|
|
|
return |
|
166
|
45 |
|
self::getQuery($key) ?? |
|
167
|
41 |
|
self::getPost($key) ?? |
|
168
|
40 |
|
self::getCookie($key) ?? |
|
169
|
39 |
|
self::getServer($key) ?? |
|
170
|
45 |
|
$default; |
|
171
|
|
|
} |
|
172
|
|
|
|
|
173
|
|
|
/** |
|
174
|
|
|
* Get all params from GET and POST or PUT |
|
175
|
|
|
* |
|
176
|
|
|
* @return array |
|
177
|
|
|
*/ |
|
178
|
4 |
|
public static function getParams() |
|
179
|
|
|
{ |
|
180
|
4 |
|
$query = (array) self::getInstance()->getQueryParams(); |
|
181
|
4 |
|
$body = (array) self::getInstance()->getParsedBody(); |
|
182
|
|
|
|
|
183
|
4 |
|
return array_merge($body, $query); |
|
184
|
|
|
} |
|
185
|
|
|
|
|
186
|
|
|
/** |
|
187
|
|
|
* Get uploaded file |
|
188
|
|
|
* |
|
189
|
|
|
* @param string $name |
|
190
|
|
|
* @return \Zend\Diactoros\UploadedFile |
|
191
|
|
|
*/ |
|
192
|
|
|
public static function getFile($name) |
|
193
|
|
|
{ |
|
194
|
|
|
return RequestFactory::get($name, self::getInstance()->getUploadedFiles()); |
|
195
|
|
|
} |
|
196
|
|
|
|
|
197
|
|
|
/** |
|
198
|
|
|
* Get the client's IP address |
|
199
|
|
|
* |
|
200
|
|
|
* @param bool $checkProxy |
|
201
|
|
|
* @return string |
|
202
|
|
|
*/ |
|
203
|
|
|
public static function getClientIp($checkProxy = true) |
|
204
|
|
|
{ |
|
205
|
|
|
if ($checkProxy && self::getServer('HTTP_CLIENT_IP') != null) { |
|
206
|
|
|
$ip = self::getServer('HTTP_CLIENT_IP'); |
|
207
|
|
|
} else { |
|
208
|
|
|
if ($checkProxy && self::getServer('HTTP_X_FORWARDED_FOR') != null) { |
|
209
|
|
|
$ip = self::getServer('HTTP_X_FORWARDED_FOR'); |
|
210
|
|
|
} else { |
|
211
|
|
|
$ip = self::getServer('REMOTE_ADDR'); |
|
212
|
|
|
} |
|
213
|
|
|
} |
|
214
|
|
|
return $ip; |
|
215
|
|
|
} |
|
216
|
|
|
|
|
217
|
|
|
/** |
|
218
|
|
|
* Get module |
|
219
|
|
|
* |
|
220
|
|
|
* @return string |
|
221
|
|
|
*/ |
|
222
|
38 |
|
public static function getModule() |
|
223
|
|
|
{ |
|
224
|
38 |
|
return self::getParam('_module', Router::getDefaultModule()); |
|
225
|
|
|
} |
|
226
|
|
|
|
|
227
|
|
|
/** |
|
228
|
|
|
* Get controller |
|
229
|
|
|
* |
|
230
|
|
|
* @return string |
|
231
|
|
|
*/ |
|
232
|
38 |
|
public static function getController() |
|
233
|
|
|
{ |
|
234
|
38 |
|
return self::getParam('_controller', Router::getDefaultController()); |
|
235
|
|
|
} |
|
236
|
|
|
|
|
237
|
|
|
/** |
|
238
|
|
|
* Get method |
|
239
|
|
|
* |
|
240
|
|
|
* @return string |
|
241
|
|
|
*/ |
|
242
|
|
|
public static function getMethod() |
|
243
|
|
|
{ |
|
244
|
|
|
return self::getParam('_method', self::getInstance()->getMethod()); |
|
245
|
|
|
} |
|
246
|
|
|
|
|
247
|
|
|
/** |
|
248
|
|
|
* Get Accept MIME Type |
|
249
|
|
|
* |
|
250
|
|
|
* @todo: refactoring this method, accept types should be stored in static? variable |
|
251
|
|
|
* @param array $allowTypes |
|
252
|
|
|
* @return string |
|
253
|
|
|
*/ |
|
254
|
2 |
|
public static function getAccept($allowTypes = []) |
|
255
|
|
|
{ |
|
256
|
2 |
|
static $accept; |
|
257
|
|
|
|
|
258
|
2 |
|
if (!$accept) { |
|
259
|
|
|
// get header from request |
|
260
|
1 |
|
$header = self::getHeader('accept'); |
|
261
|
|
|
|
|
262
|
|
|
// make array if types |
|
263
|
1 |
|
$header = explode(',', $header); |
|
264
|
1 |
|
$header = array_map('trim', $header); |
|
265
|
|
|
|
|
266
|
|
|
// result store |
|
267
|
1 |
|
$types = []; |
|
268
|
|
|
|
|
269
|
1 |
|
foreach ($header as $a) { |
|
270
|
|
|
// the default quality is 1. |
|
271
|
1 |
|
$q = 1; |
|
272
|
|
|
// check if there is a different quality |
|
273
|
1 |
|
if (strpos($a, ';q=') or strpos($a, '; q=')) { |
|
274
|
|
|
// divide "mime/type;q=X" into two parts: "mime/type" i "X" |
|
275
|
|
|
$res = preg_split('/;([ ]?)q=/', $a); |
|
276
|
|
|
$a = $res[0]; |
|
277
|
|
|
$q = $res[1]; |
|
278
|
|
|
} |
|
279
|
|
|
// remove other extension |
|
280
|
1 |
|
if (strpos($a, ';')) { |
|
281
|
|
|
$a = substr($a, 0, strpos($a, ';')); |
|
282
|
|
|
} |
|
283
|
|
|
|
|
284
|
|
|
// mime-type $a is accepted with the quality $q |
|
285
|
|
|
// WARNING: $q == 0 means, that mime-type isn’t supported! |
|
286
|
1 |
|
$types[$a] = (float) $q; |
|
287
|
|
|
} |
|
288
|
1 |
|
arsort($types); |
|
289
|
1 |
|
$accept = $types; |
|
290
|
|
|
} |
|
291
|
|
|
|
|
292
|
|
|
// if no parameter was passed, just return parsed data |
|
293
|
2 |
|
if (empty($allowTypes)) { |
|
294
|
|
|
return $accept; |
|
295
|
|
|
} |
|
296
|
|
|
|
|
297
|
2 |
|
$mimeTypes = array_map('strtolower', $allowTypes); |
|
298
|
|
|
|
|
299
|
|
|
// let’s check our supported types: |
|
300
|
2 |
|
foreach ($accept as $mime => $q) { |
|
301
|
2 |
|
if ($q && in_array($mime, $mimeTypes)) { |
|
302
|
2 |
|
return $mime; |
|
303
|
|
|
} |
|
304
|
|
|
} |
|
305
|
|
|
// no mime-type found |
|
306
|
|
|
return null; |
|
307
|
|
|
} |
|
308
|
|
|
|
|
309
|
|
|
/** |
|
310
|
|
|
* Check CLI |
|
311
|
|
|
* |
|
312
|
|
|
* @return bool |
|
313
|
|
|
*/ |
|
314
|
|
|
public static function isCli() |
|
315
|
|
|
{ |
|
316
|
|
|
return (PHP_SAPI === 'cli'); |
|
317
|
|
|
} |
|
318
|
|
|
|
|
319
|
|
|
/** |
|
320
|
|
|
* Check HTTP |
|
321
|
|
|
* |
|
322
|
|
|
* @return bool |
|
323
|
|
|
*/ |
|
324
|
1 |
|
public static function isHttp() |
|
325
|
|
|
{ |
|
326
|
1 |
|
return (PHP_SAPI !== 'cli'); |
|
327
|
|
|
} |
|
328
|
|
|
|
|
329
|
|
|
/** |
|
330
|
|
|
* Is this a GET method request? |
|
331
|
|
|
* |
|
332
|
|
|
* @return bool |
|
333
|
|
|
*/ |
|
334
|
|
|
public static function isGet() |
|
335
|
|
|
{ |
|
336
|
|
|
return (self::getInstance()->getMethod() === self::METHOD_GET); |
|
337
|
|
|
} |
|
338
|
|
|
|
|
339
|
|
|
/** |
|
340
|
|
|
* Is this a POST method request? |
|
341
|
|
|
* |
|
342
|
|
|
* @return bool |
|
343
|
|
|
*/ |
|
344
|
|
|
public static function isPost() |
|
345
|
|
|
{ |
|
346
|
|
|
return (self::getInstance()->getMethod() === self::METHOD_POST); |
|
347
|
|
|
} |
|
348
|
|
|
|
|
349
|
|
|
/** |
|
350
|
|
|
* Is this a PUT method request? |
|
351
|
|
|
* |
|
352
|
|
|
* @return bool |
|
353
|
|
|
*/ |
|
354
|
|
|
public static function isPut() |
|
355
|
|
|
{ |
|
356
|
|
|
return (self::getInstance()->getMethod() === self::METHOD_PUT); |
|
357
|
|
|
} |
|
358
|
|
|
|
|
359
|
|
|
/** |
|
360
|
|
|
* Is this a DELETE method request? |
|
361
|
|
|
* |
|
362
|
|
|
* @return bool |
|
363
|
|
|
*/ |
|
364
|
|
|
public static function isDelete() |
|
365
|
|
|
{ |
|
366
|
|
|
return (self::getInstance()->getMethod() === self::METHOD_DELETE); |
|
367
|
|
|
} |
|
368
|
|
|
|
|
369
|
|
|
/** |
|
370
|
|
|
* Is the request a Javascript XMLHttpRequest? |
|
371
|
|
|
* |
|
372
|
|
|
* @return bool |
|
373
|
|
|
*/ |
|
374
|
2 |
|
public static function isXmlHttpRequest() |
|
375
|
|
|
{ |
|
376
|
2 |
|
return (self::getHeader('X-Requested-With') == 'XMLHttpRequest'); |
|
377
|
|
|
} |
|
378
|
|
|
} |
|
379
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.