PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.31
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.31
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.31, at vendor/wpfluent/framework/src/WPFluent/Http/Request/Request.php

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