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

766 lines 17.4 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 Closure;
6 use FluentBoards\Framework\Support\Arr;
7 use FluentBoards\Framework\Support\Helper;
8 use FluentBoards\Framework\Support\MacroableTrait;
9 use FluentBoards\Framework\Foundation\Application;
10 use FluentBoards\Framework\Validator\ValidationException;
11
12 class Request
13 {
14 use InteractsWithCleaningTrait,
15 InteractsWithHeadersTrait,
16 InputHelperMethodsTrait,
17 InteractsWithFilesTrait,
18 MacroableTrait {
19 __call as macroCall;
20 }
21
22 /**
23 * The application instance
24 * @var \FluentBoards\Framework\Foundation\Application
25 */
26 protected $app = null;
27
28 /**
29 * PHP header variables
30 * @var array
31 */
32 protected $headers = [];
33
34 /**
35 * PHP server variables
36 * @var array
37 */
38 protected $server = [];
39
40 /**
41 * PHP cookie variables
42 * @var array
43 */
44 protected $cookie = [];
45
46 /**
47 * The JSON payload of the request
48 * @var array
49 */
50 protected $json = [];
51
52 /**
53 * PHP $_GET Superglobal
54 * @var array
55 */
56 protected $get = [];
57
58
59 /**
60 * PHP $_POST Superglobal
61 * @var array
62 */
63 protected $post = [];
64
65 /**
66 * PHP $_FILES Superglobal
67 * @var array
68 */
69 protected $files = [];
70
71 /**
72 * PHP $_GET and $_POST Superglobals
73 * @var array
74 */
75 protected $request = [];
76
77 /**
78 * WP_REST_Request instance
79 * @var WP_REST_Request
80 */
81 protected $wpRestRequest = false;
82
83 /**
84 * Validated data after validation has been passed
85 * @var array
86 */
87 protected $validated = [];
88
89 /**
90 * $safe Determines the input source when data retrieval methods get called.
91 * If true, the data will be returned from the $validated array.
92 * If false, the data will be returned from the $request array.
93 *
94 * @var boolean
95 */
96 protected $safe = false;
97
98 /**
99 * Construct the request instance
100 * @param \FluentBoards\Framework\Foundation\Application $app
101 * @param array/$_GET $get
102 * @param array/$_POST $post
103 * @param array/$_FILES $files
104 */
105 public function __construct(Application $app, $get, $post, $files)
106 {
107 $this->app = $app;
108 $this->server = $_SERVER;
109 $this->cookie = $_COOKIE;
110 $this->files = $this->prepareFiles($files);
111
112 $this->request = array_merge(
113 $this->get = $this->clean($get),
114 $this->post = $this->clean($post)
115 );
116 }
117
118 /**
119 * Variable exists
120 * @param string $key
121 * @return bool
122 */
123 public function exists($key)
124 {
125 return Arr::has($this->inputs(), $key);
126 }
127
128 /**
129 * Variable exists and has truthy value
130 * @param string $key
131 * @return bool
132 */
133 public function has($key)
134 {
135 $inputs = $this->inputs();
136
137 return isset($inputs[$key]) && !empty($inputs[$key]);
138 }
139
140 /**
141 * Any variable exists and has truthy value
142 * @param string $key
143 * @return bool
144 */
145 public function hasAny($keys)
146 {
147 $keys = is_array($keys) ? $keys : func_get_args();
148
149 if ($data = $this->only($keys)) {
150 return (bool) count(array_filter($data));
151 }
152
153 return false;
154 }
155
156 /**
157 * Calls a callback if has value, otherwise
158 * calls another/second callback if given.
159 *
160 * @param string $key
161 * @param \Closure $has
162 * @param \Closure|null $hasnot
163 * @return mixed
164 */
165 public function whenHas($key, Closure $has, ?Closure $hasnot = null)
166 {
167 if ($this->has($key)) {
168 return $has($key, $this->get($key));
169 }
170
171 return ($hasnot ? $hasnot($key) : null);
172 }
173
174 /**
175 * Checks if a key is missing in the request.
176 *
177 * @param string $key
178 * @return bool
179 */
180 public function missing($key)
181 {
182 return !$this->has($key);
183 }
184
185 /**
186 * Calls the given callback if the provided key is missing.
187 *
188 * @param string $key
189 * @param \Closure $callback
190 * @return mixed
191 */
192 public function whenMissing($key, Closure $callback)
193 {
194 if ($this->missing($key)) {
195 return $callback($key, $this);
196 }
197
198 return $this;
199 }
200
201 /**
202 * Set an item into the request inputs
203 * @param string $key
204 * @param mixed
205 */
206 public function set($key, $value)
207 {
208 Arr::set($this->request, $key, $value);
209
210 return $this;
211 }
212
213 /**
214 * Retrive all the items from the request inputs
215 * @return array
216 */
217 public function all()
218 {
219 return $this->get();
220 }
221
222 /**
223 * Retrieve an item from the request inputs
224 * @param string|null $key
225 * @param mixed $default
226 * @return mixed
227 */
228 public function get($key = null, $default = null)
229 {
230 return Helper::dataGet($this->inputs(), $key, $default);
231 }
232
233 /**
234 * Check the content-type for JSON
235 *
236 * @return boolean
237 */
238 public function isJson()
239 {
240 if (!($isJson = $this->is_json_content_type())) {
241 if (!$isJson) {
242 if ($body = $this->get_body()) {
243 json_decode($body);
244 if (json_last_error() === JSON_ERROR_NONE) {
245 $isJson = true;
246 }
247 } elseif ($this->isRest()) {
248 $isJson = true;
249 }
250 }
251 }
252
253 if (
254 !$isJson &&
255 isset($_SERVER['CONTENT_TYPE']) &&
256 strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false
257 ) {
258 $requestBody = file_get_contents('php://input');
259
260 if (!empty($requestBody)) {
261 $this->json = json_decode($requestBody, true);
262 $isJson = json_last_error() === JSON_ERROR_NONE;
263 }
264 }
265
266 return $isJson;
267 }
268
269 /**
270 * Check if current request wants JSON response.
271 *
272 * @return boolean
273 */
274 public function wantsJson()
275 {
276 $wants = $this->header('accept');
277
278 if ($wants === '*/*') {
279 return $this->isJson();
280 }
281
282 return $wants === 'application/json';
283 }
284
285 /**
286 * Check if current request is a Rest request
287 *
288 * @return boolean
289 */
290 public function isRest()
291 {
292 $isRest = false;
293
294 if ($this->app->isUnitTesting()) {
295 return $isRest;
296 }
297
298 $url = $this->url();
299
300 $niddle = $this->app->config->get(
301 'app.rest_namespace'
302 ).'/__endpoints';
303
304 if (str_contains($url, $niddle)) {
305 return $isRest;
306 }
307
308 $isRest = defined('REST_REQUEST') && REST_REQUEST;
309
310 if (!$isRest) {
311 if (!get_option('permalink_structure')) {
312 $isRest = $this->query('rest_route', false);
313 } else {
314 $parsed = parse_url($url);
315 $path = isset($parsed['path']) ? $parsed['path'] : '';
316 $isRest = str_starts_with($path, '/wp-json');
317 }
318 }
319
320 return $isRest;
321 }
322
323 /**
324 * Determine if the request is initiated by WordPress.
325 *
326 * @return boolean
327 */
328 public function isInternal()
329 {
330 return $GLOBALS['wp_rest_server']->is_dispatching();
331 }
332
333 /**
334 * Retrieve an item from the json payload of the request.
335 *
336 * @param string $key
337 * @param string $default
338 * @return mixed
339 */
340 public function json($key = null, $default = null)
341 {
342 if (!$this->isJson()) return;
343
344 if (!isset($this->json)) {
345 $json = $this->get_json_params() ?: $this->getContent();
346
347 $this->json = (array) json_decode($json, true);
348 }
349
350 if (is_null($key)) {
351 return $this->json;
352 }
353
354 return Helper::dataGet($this->json, $key, $default);
355 }
356
357 /**
358 * Retrieve an item from the PHP $_SERVER array
359 * @param string $key
360 * @param string $default
361 * @return mixed
362 */
363 public function server($key = null, $default = null)
364 {
365 return $key ? Arr::get($this->server, $key, $default) : $this->server;
366 }
367
368 /**
369 * Retrieve an item from the cookie
370 * @param string $key
371 * @param mixed $default
372 * @return mixed
373 */
374 public function cookie($key = null, $default = null)
375 {
376 $cookie = $key ? Arr::get(
377 $this->cookie, $key, $default
378 ) : $this->cookie;
379
380 return json_decode(base64_decode($cookie, true));
381 }
382
383 /**
384 * Get an item from the PHP $_GET array
385 * @param string $key
386 * @param mixed $default
387 * @return mixed
388 */
389 public function query($key = null, $default = null)
390 {
391 return $key ? Arr::get($this->get, $key, $default) : $this->get;
392 }
393
394 /**
395 * Get an item from the PHP $_POST array
396 * @param string $key
397 * @param mixed $default
398 * @return mixed
399 */
400 public function post($key = null, $default = null)
401 {
402 return $key ? Arr::get($this->post, $key, $default) : $this->post;
403 }
404
405 /**
406 * Return the only items given in the args
407 * @param array $keys
408 * @return array
409 */
410 public function only($keys)
411 {
412 $keys = is_array($keys) ? $keys : func_get_args();
413
414 return Arr::only($this->inputs(), $keys);
415 }
416
417 /**
418 * Return a subset of the request inputs except the given keys
419 * @param array $keys
420 * @return array
421 */
422 public function except($keys)
423 {
424 $keys = is_array($keys) ? $keys : func_get_args();
425
426 return Arr::except($this->inputs(), $keys);
427 }
428
429 /**
430 * Merge array with the request inputs
431 * @param array $data
432 * @return self
433 */
434 public function merge(array $data = [])
435 {
436 $this->request = array_replace($this->inputs(), $data);
437
438 return $this;
439 }
440
441 /**
442 * Merge array with the request inputs if the
443 * key(s) is missing from the request.
444 *
445 * @param array $data
446 * @return self
447 */
448 public function mergeIfMissing(array $data = [])
449 {
450 $all = $this->inputs();
451
452 $this->merge(Arr::mergeMissing($data, $all));
453
454 return $this;
455 }
456
457 /**
458 * Merge new input into the request's input, but only when
459 * that key is present in the request but value is missing.
460 *
461 * @param array $input
462 * @return $this
463 */
464 public function mergeMissing(array $input)
465 {
466 return $this->merge(Helper::collect($input)
467 ->filter(function($value, $key) {
468 return $this->missing($key);
469 })->toArray()
470 );
471 }
472
473 /**
474 * Returns the request body content.
475 *
476 * @param bool $asResource If true, a resource will be returned
477 *
478 * @return string|resource
479 */
480 public function getContent()
481 {
482 if (null === $this->content || false === $this->content) {
483 $this->content = file_get_contents('php://input');
484 }
485
486 return $this->content;
487 }
488
489 /**
490 * Merges the input arrays from the WP_REST_Request.
491 *
492 * @param \WP_REST_Request $wpRestRequest
493 * @return void
494 */
495 public function mergeInputsFromRestRequest($wpRestRequest)
496 {
497 $this->request = array_merge(
498 $this->request, $wpRestRequest->get_params()
499 );
500
501 $this->post = array_merge(
502 $this->post, $wpRestRequest->get_body_params()
503 );
504
505 $this->get = array_merge(
506 $this->get, $wpRestRequest->get_query_params()
507 );
508
509 $this->mergerHeaders($wpRestRequest);
510
511 $this->wpRestRequest = true;
512 }
513
514 /**
515 * Merge the headers from the WP_REST_Request.
516 *
517 * @param WP_REST_Request $wpRestRequest
518 * @return void
519 */
520 protected function mergerHeaders($wpRestRequest)
521 {
522 $headers = [];
523
524 foreach ($wpRestRequest->get_headers() as $key => $header) {
525 $headers[strtoupper($key)] = reset($header);
526 }
527
528 $this->headers = array_merge($this->headers, $headers);
529
530 if (
531 !isset($this->headers['CONTENT_TYPE']) || (
532 isset($this->headers['CONTENT_TYPE']) &&
533 $this->headers['CONTENT_TYPE'] !== true
534 )) {
535 if ($this->isJson()) {
536 $this->headers['CONTENT_TYPE'] = 'application/json';
537 }
538 }
539 }
540
541 /**
542 * Retrieve an input item from the request.
543 *
544 * @param string|null $key
545 * @param mixed $default
546 * @return mixed
547 */
548 public function input($key = null, $default = null)
549 {
550 return Arr::get($this->inputs(), $key, $default);
551 }
552
553 /**
554 * Remove a key(s) from the $request array
555 * @param mixed $key
556 * @return self
557 */
558 public function forget($key)
559 {
560 Arr::forget($this->request, $key);
561
562 return $this;
563 }
564
565 /**
566 * Get all inputs
567 *
568 * @return array $this->request
569 */
570 protected function inputs()
571 {
572 if (!$this->wpRestRequest) {
573 if ($this->app->bound('wprestrequest')) {
574 $this->mergeInputsFromRestRequest($this->app->wprestrequest);
575 }
576 }
577
578 if ($this->safe === true) {
579 $this->safe = false;
580 return $this->validated;
581 }
582
583 return $this->request;
584 }
585
586 /**
587 * To get item(s) from validated inputs
588 *
589 * @return self
590 */
591 public function safe()
592 {
593 $this->safe = true;
594
595 return $this;
596 }
597
598 /**
599 * Get user ip address
600 * @return string
601 */
602 public function getIp()
603 {
604 if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
605 $ip = $this->server('HTTP_CLIENT_IP');
606 } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
607 $ip = $this->server('HTTP_X_FORWARDED_FOR');
608 } else {
609 $ip = $this->server('REMOTE_ADDR');
610 }
611
612 return $ip;
613 }
614
615 /**
616 * Get the request method.
617 *
618 * @return string
619 */
620 public function method()
621 {
622 return $_SERVER['REQUEST_METHOD'];
623 }
624
625 /**
626 * Get the URL (no query string) for the request.
627 *
628 * @return string
629 */
630 public function url()
631 {
632 return preg_replace('/\?.*/', '', $this->getFullUrl());
633 }
634
635 /**
636 * Get the full URL for the request.
637 *
638 * @return string
639 */
640 public function getFullUrl()
641 {
642 return get_site_url() . rtrim($_SERVER['REQUEST_URI'], '/');
643 }
644
645 /**
646 * Validate the request.
647 *
648 * @param string $key
649 * @return mixed
650 */
651 public function validate(array $rules, array $messages = [])
652 {
653 $instance = $this->app->make('validator');
654
655 $validator = $instance->make($data = $this->all(), $rules, $messages);
656
657 if ($validator->validate()->fails()) {
658 throw new ValidationException(
659 'Unprocessable Entity!', 422, null, $validator->errors()
660 );
661 }
662
663 $this->validated = $validator->validated();
664
665 return $data;
666 }
667
668 /**
669 * Get the valid data after validation has been passed.
670 *
671 * @return array
672 */
673 public function validated($data = [])
674 {
675 if ($data) {
676 return $this->validated = $data;
677 }
678
679 return (array) $this->validated;
680 }
681
682 /**
683 * Abort the request.
684 *
685 * @param integer $status
686 * @param string $message
687 * @return \WP_REST_Response
688 */
689 public function abort($status = 403, $message = null)
690 {
691 if (is_object($status)) {
692 if (method_exists($status, 'errors')) {
693 throw new ValidationException(
694 'Unprocessable Entity!', 422, null, $status->errors()
695 );
696 }
697 }
698
699 if (!$message && !is_numeric($status) && is_string($status)) {
700 $message = $status;
701 $status = 403;
702 }
703
704 $message = $message ?: 'Request has benn aborted.';
705
706 return new \WP_REST_Response(
707 is_array($message) ? $message : ['message' => (string) $message], $status
708 );
709 }
710
711 /**
712 * Get an input element from the request.
713 *
714 * @param string $key
715 * @return mixed
716 */
717 public function __get($key)
718 {
719 return $this->get($key);
720 }
721
722 /**
723 * Retrieves the currently logged in user.
724 *
725 * @return \FluentBoards\Framework\Http\Request\WPUserProxy
726 */
727 public function user()
728 {
729 return $this->app->user();
730 }
731
732 /**
733 * Dynamyc method calls (specially for WP_rest_request)
734 * @param string $method
735 * @param array $params
736 * @return mixed
737 */
738 public function __call($method, $params = [])
739 {
740 if (static::hasMacro($method)) {
741 return $this->macroCall($method, $params);
742 }
743
744 if ($method == 'route') {
745 if ($params) {
746 return $this->app->route->{$params[0]};
747 }
748 return $this->app->route;
749 }
750
751 if ($this->app->bound('wprestrequest')) {
752 if (!method_exists($this->app->wprestrequest, $method)) {
753 $method = strtolower(
754 preg_replace([
755 '/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'
756 ], '$1_$2', $method)
757 );
758 }
759
760 return call_user_func_array([
761 $this->app->wprestrequest, $method], $params
762 );
763 }
764 }
765 }
766