PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.21
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.21
2.1.0 2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 All 42 releases
fluent-boards / vendor / wpfluent / framework / src / WPFluent / Http / Request / Request.php

Request.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.21, at vendor/wpfluent/framework/src/WPFluent/Http/Request/Request.php

670 lines 16.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\Framework\Http\Request;
4
5 use FluentBoards\Framework\Support\Arr;
6 use FluentBoards\Framework\Support\Helper;
7 use FluentBoards\Framework\Foundation\Application;
8 use FluentBoards\Framework\Validator\ValidationException;
9
10 class Request
11 {
12 use FileHandler, Cleaner, InputHelperMethodsTrait;
13
14 /**
15 * The application instance
16 * @var \FluentBoards\Framework\Foundation\Application
17 */
18 protected $app = null;
19
20 /**
21 * PHP header variables
22 * @var array
23 */
24 protected $headers = [];
25
26 /**
27 * PHP server variables
28 * @var array
29 */
30 protected $server = [];
31
32 /**
33 * PHP cookie variables
34 * @var array
35 */
36 protected $cookie = [];
37
38 /**
39 * The JSON payload of the request
40 * @var array
41 */
42 protected $json = [];
43
44 /**
45 * PHP $_GET Superglobal
46 * @var array
47 */
48 protected $get = [];
49
50
51 /**
52 * PHP $_POST Superglobal
53 * @var array
54 */
55 protected $post = [];
56
57 /**
58 * PHP $_FILES Superglobal
59 * @var array
60 */
61 protected $files = [];
62
63 /**
64 * PHP $_GET and $_POST Superglobals
65 * @var array
66 */
67 protected $request = [];
68
69 /**
70 * WP_REST_Request instance
71 * @var WP_REST_Request
72 */
73 protected $wpRestRequest = false;
74
75 /**
76 * Validated data after validation has been passed
77 * @var array
78 */
79 protected $validated = [];
80
81 /**
82 * Construct the request instance
83 * @param \FluentBoards\Framework\Foundation\Application $app
84 * @param array/$_GET $get
85 * @param array/$_POST $post
86 * @param array/$_FILES $files
87 */
88 public function __construct(Application $app, $get, $post, $files)
89 {
90 $this->app = $app;
91 $this->server = $_SERVER;
92 $this->cookie = $_COOKIE;
93 $this->files = $this->prepareFiles($files);
94
95 $this->request = array_merge(
96 $this->get = $this->clean($get),
97 $this->post = $this->clean($post)
98 );
99 }
100
101 /**
102 * Variable exists
103 * @param string $key
104 * @return bool
105 */
106 public function exists($key)
107 {
108 return Arr::has($this->inputs(), $key);
109 }
110
111 /**
112 * Variable exists and has truthy value
113 * @param string $key
114 * @return bool
115 */
116 public function has($key)
117 {
118 return $this->exists($key) && !empty(Arr::get($this->inputs(), $key));
119 }
120
121 /**
122 * Any variable exists and has truthy value
123 * @param string $key
124 * @return bool
125 */
126 public function hasAny($keys)
127 {
128 $keys = is_array($keys) ? $keys : func_get_args();
129
130 if ($data = $this->only($keys)) {
131 return (bool) count(array_filter($data));
132 }
133
134 return false;
135 }
136
137 /**
138 * Calls a callback if has value, otherwise
139 * calls another/second callback if given.
140 *
141 * @param string $key
142 * @param \Closure $has
143 * @param \Closure|null $hasnot
144 * @return mixed
145 */
146 public function whenHas($key, \Closure $has, \Closure $hasnot = null)
147 {
148 if ($this->has($key)) {
149 return $has($key, $this->get($key));
150 }
151
152 return ($hasnot ? $hasnot($key) : null);
153 }
154
155 /**
156 * Checks if a key is missing in the request.
157 *
158 * @param string $key
159 * @return bool
160 */
161 public function missing($key)
162 {
163 return !$this->has($key);
164 }
165
166 /**
167 * Calls the given callback if the provided key is missing.
168 *
169 * @param string $key
170 * @param \Closure $callback
171 * @return mixed
172 */
173 public function whenMissing($key, \Closure $callback)
174 {
175 if ($this->missing($key)) {
176 return $callback($key, $this);
177 }
178
179 return $this;
180 }
181
182 /**
183 * Set an item into the request inputs
184 * @param string $key
185 * @param mixed
186 */
187 public function set($key, $value)
188 {
189 Arr::set($this->request, $key, $value);
190
191 return $this;
192 }
193
194 /**
195 * Retrive all the items from the request inputs
196 * @return array
197 */
198 public function all()
199 {
200 return $this->get();
201 }
202
203 /**
204 * Retrieve an item from the request inputs
205 * @param string|null $key
206 * @param mixed $default
207 * @return mixed
208 */
209 public function get($key = null, $default = null)
210 {
211 return Helper::dataGet($this->inputs(), $key, $default);
212 }
213
214 /**
215 * Check the content-type for JSON
216 *
217 * @return boolean
218 */
219 public function isJson()
220 {
221 return $this->is_json_content_type();
222 }
223
224 /**
225 * Check if current request is a Rest request
226 *
227 * @return boolean
228 */
229 public function isRest()
230 {
231 $isRest = (defined('REST_REQUEST') && REST_REQUEST) || $this->query('rest_route');
232
233 return $isRest || (function() {
234 $currentUrl = wp_parse_url(add_query_arg([]));
235 $restUrl = wp_parse_url(trailingslashit(rest_url()));
236 return strpos($currentUrl['path'] ?? '/', $restUrl['path']);
237 })() !== false;
238 }
239
240 /**
241 * Retrieve an item from the json payload of the request
242 * @param string $key
243 * @param string $default
244 * @return mixed
245 */
246 public function json($key = null, $default = null)
247 {
248 if (!$this->isJson()) return;
249
250 if (!isset($this->json)) {
251 $json = $this->get_json_params() ?: $this->getContent();
252
253 $this->json = (array) json_decode($json, true);
254 }
255
256 if (is_null($key)) {
257 return $this->json;
258 }
259
260 return Helper::dataGet($this->json, $key, $default);
261 }
262
263 /**
264 * Retrieve an item from the PHP $_SERVER array
265 * @param string $key
266 * @param string $default
267 * @return mixed
268 */
269 public function server($key = null, $default = null)
270 {
271 return $key ? Arr::get($this->server, $key, $default) : $this->server;
272 }
273
274 /**
275 * Retrieve an item from the PHP headers
276 * @param string $key
277 * @param string $default
278 * @return mixed
279 */
280 public function header($key = null, $default = null)
281 {
282 if (!$this->headers) {
283 $this->headers = $this->setHeaders();
284 }
285
286 return $key ? Arr::get($this->headers, $key, $default) : $this->headers;
287 }
288
289 /**
290 * Retrieve an item from the cookie
291 * @param string $key
292 * @param mixed $default
293 * @return mixed
294 */
295 public function cookie($key = null, $default = null)
296 {
297 $cookie = $key ? Arr::get($this->cookie, $key, $default) : $this->cookie;
298
299 return json_decode(base64_decode($cookie, true));
300 }
301
302 /**
303 * Get the files from the request.
304 *
305 * @return array
306 */
307 public function files()
308 {
309 return $this->files;
310 }
311
312 /**
313 * Get an item from the PHP $_GET array
314 * @param string $key
315 * @param mixed $default
316 * @return mixed
317 */
318 public function query($key = null, $default = null)
319 {
320 return $key ? Arr::get($this->get, $key, $default) : $this->get;
321 }
322
323 /**
324 * Get an item from the PHP $_POST array
325 * @param string $key
326 * @param mixed $default
327 * @return mixed
328 */
329 public function post($key = null, $default = null)
330 {
331 return $key ? Arr::get($this->post, $key, $default) : $this->post;
332 }
333
334 /**
335 * Return the only items given in the args
336 * @param array $keys
337 * @return array
338 */
339 public function only($keys)
340 {
341 return Arr::only($this->inputs(), $keys);
342 }
343
344 /**
345 * Return a subset of the request inputs except the given args
346 * @param array $args
347 * @return array
348 */
349 public function except($args)
350 {
351 return Arr::except($this->inputs(), $args);
352 }
353
354 /**
355 * Merge array with the request inputs
356 * @param array $data
357 * @return self
358 */
359 public function merge(array $data = [])
360 {
361 $this->request = array_replace($this->inputs(), $data);
362
363 return $this;
364 }
365
366 /**
367 * Merge array with the request inputs
368 * @param array $data
369 * @return self
370 */
371 public function mergeMissing(array $data = [])
372 {
373 $all = $this->inputs();
374
375 $this->merge(Arr::mergeMissing($data, $all));
376
377 return $this;
378 }
379
380 /**
381 * Returns the request body content.
382 *
383 * @param bool $asResource If true, a resource will be returned
384 *
385 * @return string|resource
386 */
387 public function getContent()
388 {
389 if (null === $this->content || false === $this->content) {
390 $this->content = file_get_contents('php://input');
391 }
392
393 return $this->content;
394 }
395
396 public function mergeInputsFromRestRequest($wpRestRequest)
397 {
398 $this->request = array_merge(
399 $this->request, $wpRestRequest->get_params()
400 );
401
402 $this->post = array_merge(
403 $this->post, $wpRestRequest->get_body_params()
404 );
405
406 $this->get = array_merge(
407 $this->get, $wpRestRequest->get_query_params()
408 );
409
410 $this->wpRestRequest = true;
411 }
412
413 /**
414 * Retrieve an input item from the request.
415 *
416 * @param string|null $key
417 * @param mixed $default
418 * @return mixed
419 */
420 public function input($key = null, $default = null)
421 {
422 return Arr::get($this->inputs(), $key, $default);
423 }
424
425 /**
426 * Remove a key(s) from the $request array
427 * @param mixed $key
428 * @return self
429 */
430 public function forget($key)
431 {
432 Arr::forget($this->request, $key);
433
434 return $this;
435 }
436
437 /**
438 * Get all inputs
439 * @return array $this->request
440 */
441 protected function inputs()
442 {
443 if (!$this->wpRestRequest) {
444 if ($this->app->bound('wprestrequest')) {
445 $this->mergeInputsFromRestRequest($this->app->wprestrequest);
446 }
447 }
448
449 return $this->request;
450 }
451
452 /**
453 * Get user ip address
454 * @return string
455 */
456 public function getIp()
457 {
458 if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
459 $ip = $this->server('HTTP_CLIENT_IP');
460 } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
461 $ip = $this->server('HTTP_X_FORWARDED_FOR');
462 } else {
463 $ip = $this->server('REMOTE_ADDR');
464 }
465
466 return $ip;
467 }
468
469 /**
470 * Taken and modified from Symfony
471 */
472 public function setHeaders()
473 {
474 $headers = array();
475 $parameters = $this->server;
476 $contentHeaders = array('CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true);
477 foreach ($parameters as $key => $value) {
478 if (0 === strpos($key, 'HTTP_')) {
479 $headers[substr($key, 5)] = $value;
480 } // CONTENT_* are not prefixed with HTTP_
481 elseif (isset($contentHeaders[$key])) {
482 $headers[$key] = $value;
483 }
484 }
485
486 if (isset($parameters['PHP_AUTH_USER'])) {
487 $headers['PHP_AUTH_USER'] = $parameters['PHP_AUTH_USER'];
488 $headers['PHP_AUTH_PW'] = isset($parameters['PHP_AUTH_PW']) ? $parameters['PHP_AUTH_PW'] : '';
489 } else {
490 /*
491 * php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default
492 * For this workaround to work, add these lines to your .htaccess file:
493 * RewriteCond %{HTTP:Authorization} ^(.+)$
494 * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
495 *
496 * A sample .htaccess file:
497 * RewriteEngine On
498 * RewriteCond %{HTTP:Authorization} ^(.+)$
499 * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
500 * RewriteCond %{REQUEST_FILENAME} !-f
501 * RewriteRule ^(.*)$ app.php [QSA,L]
502 */
503
504 $authorizationHeader = null;
505 if (isset($parameters['HTTP_AUTHORIZATION'])) {
506 $authorizationHeader = $parameters['HTTP_AUTHORIZATION'];
507 } elseif (isset($parameters['REDIRECT_HTTP_AUTHORIZATION'])) {
508 $authorizationHeader = $parameters['REDIRECT_HTTP_AUTHORIZATION'];
509 }
510
511 if (null !== $authorizationHeader) {
512 if (0 === stripos($authorizationHeader, 'basic ')) {
513 // Decode AUTHORIZATION header into PHP_AUTH_USER and PHP_AUTH_PW when authorization header is basic
514 $exploded = explode(':', base64_decode(substr($authorizationHeader, 6)), 2);
515 if (count($exploded) == 2) {
516 list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded;
517 }
518 } elseif (empty($parameters['PHP_AUTH_DIGEST']) && (0 === stripos($authorizationHeader, 'digest '))) {
519 // In some circumstances PHP_AUTH_DIGEST needs to be set
520 $headers['PHP_AUTH_DIGEST'] = $authorizationHeader;
521 $parameters['PHP_AUTH_DIGEST'] = $authorizationHeader;
522 } elseif (0 === stripos($authorizationHeader, 'bearer ')) {
523 /*
524 * XXX: Since there is no PHP_AUTH_BEARER in PHP predefined variables,
525 * I'll just set $headers['AUTHORIZATION'] here.
526 * http://php.net/manual/en/reserved.variables.server.php
527 */
528 $headers['AUTHORIZATION'] = $authorizationHeader;
529 }
530 }
531 }
532
533 if (isset($headers['AUTHORIZATION'])) {
534 return $headers;
535 }
536
537 // PHP_AUTH_USER/PHP_AUTH_PW
538 if (isset($headers['PHP_AUTH_USER'])) {
539 $headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']);
540 } elseif (isset($headers['PHP_AUTH_DIGEST'])) {
541 $headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST'];
542 }
543
544 return $headers;
545 }
546
547 public function method()
548 {
549 return $_SERVER['REQUEST_METHOD'];
550 }
551
552 /**
553 * Get the URL (no query string) for the request.
554 *
555 * @return string
556 */
557 public function url()
558 {
559 return get_site_url() . rtrim(
560 preg_replace('/\?.*/', '', $_SERVER['REQUEST_URI']), '/'
561 );
562 }
563
564 /**
565 * Validate the request.
566 *
567 * @param string $key
568 * @return mixed
569 */
570 public function validate(array $rules, array $messages = [])
571 {
572 $instance = $this->app->make('validator');
573
574 $validator = $instance->make($data = $this->all(), $rules, $messages);
575
576 if ($validator->validate()->fails()) {
577 throw new ValidationException(
578 'Unprocessable Entity!', 422, null, $validator->errors()
579 );
580 }
581
582 $this->validated = $validator->validated();
583
584 return $data;
585 }
586
587 /**
588 * Get the valid data after validation has been passed.
589 *
590 * @return array
591 */
592 public function validated($data = [])
593 {
594 if ($data) {
595 return $this->validated = $data;
596 }
597
598 return (array) $this->validated;
599 }
600
601 /**
602 * Abort the request.
603 *
604 * @param integer $status
605 * @param string $message
606 * @return \WP_REST_Response
607 */
608 public function abort($status = 403, $message = null)
609 {
610 if (is_object($status)) {
611 if (method_exists($status, 'errors')) {
612 throw new ValidationException(
613 'Unprocessable Entity!', 422, null, $status->errors()
614 );
615 }
616 }
617
618 if (!$message && !is_numeric($status) && is_string($status)) {
619 $message = $status;
620 $status = 403;
621 }
622
623 $message = $message ?: 'Request has benn aborted.';
624
625 return new \WP_REST_Response(
626 is_array($message) ? $message : ['message' => (string) $message], $status
627 );
628 }
629
630 /**
631 * Get an input element from the request.
632 *
633 * @param string $key
634 * @return mixed
635 */
636 public function __get($key)
637 {
638 return $this->get($key);
639 }
640
641 /**
642 * Dynamyc method calls (specially for WP_rest_request)
643 * @param string $method
644 * @param array $params
645 * @return mixed
646 */
647 public function __call($method, $params)
648 {
649 if ($method == 'route') {
650
651 if ($params) {
652 return $this->app->route->{$params[0]};
653 }
654
655 return $this->app->route;
656 }
657
658 if ($this->app->bound('wprestrequest')) {
659
660 if (!method_exists($this->app->wprestrequest, $method)) {
661 $method = strtolower(
662 preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $method)
663 );
664 }
665
666 return call_user_func_array([$this->app->wprestrequest, $method], $params);
667 }
668 }
669 }
670