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

737 lines 16.5 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 return $this->exists($key) && !empty(
136 Arr::get($this->inputs(), $key)
137 );
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 return $isJson;
254 }
255
256 /**
257 * Check if current request wants JSON response.
258 *
259 * @return boolean
260 */
261 public function wantsJson()
262 {
263 $wants = $this->header('accept');
264
265 if ($wants === '*/*') {
266 return $this->isJson();
267 }
268
269 return $wants === 'application/json';
270 }
271
272 /**
273 * Check if current request is a Rest request
274 *
275 * @return boolean
276 */
277 public function isRest()
278 {
279 $isRest = false;
280
281 if ($this->app->isUnitTesting()) {
282 return $isRest;
283 }
284
285 $url = $this->url();
286
287 $niddle = $this->app->config->get(
288 'app.rest_namespace'
289 ).'/__endpoints';
290
291 if (str_contains($url, $niddle)) {
292 return $isRest;
293 }
294
295 $isRest = defined('REST_REQUEST') && REST_REQUEST;
296
297 if (!$isRest) {
298 if (!get_option('permalink_structure')) {
299 $isRest = $this->query('rest_route', false);
300 } else {
301 $parsed = parse_url($url);
302 $path = isset($parsed['path']) ? $parsed['path'] : '';
303 $isRest = str_starts_with($path, '/wp-json');
304 }
305 }
306
307 return $isRest;
308 }
309
310 /**
311 * Determine if the request is initiated by WordPress.
312 *
313 * @return boolean
314 */
315 public function isInternal()
316 {
317 return $GLOBALS['wp_rest_server']->is_dispatching();
318 }
319
320 /**
321 * Retrieve an item from the json payload of the request.
322 *
323 * @param string $key
324 * @param string $default
325 * @return mixed
326 */
327 public function json($key = null, $default = null)
328 {
329 if (!$this->isJson()) return;
330
331 if (!isset($this->json)) {
332 $json = $this->get_json_params() ?: $this->getContent();
333
334 $this->json = (array) json_decode($json, true);
335 }
336
337 if (is_null($key)) {
338 return $this->json;
339 }
340
341 return Helper::dataGet($this->json, $key, $default);
342 }
343
344 /**
345 * Retrieve an item from the PHP $_SERVER array
346 * @param string $key
347 * @param string $default
348 * @return mixed
349 */
350 public function server($key = null, $default = null)
351 {
352 return $key ? Arr::get($this->server, $key, $default) : $this->server;
353 }
354
355 /**
356 * Retrieve an item from the cookie
357 * @param string $key
358 * @param mixed $default
359 * @return mixed
360 */
361 public function cookie($key = null, $default = null)
362 {
363 $cookie = $key ? Arr::get(
364 $this->cookie, $key, $default
365 ) : $this->cookie;
366
367 return json_decode(base64_decode($cookie, true));
368 }
369
370 /**
371 * Get an item from the PHP $_GET array
372 * @param string $key
373 * @param mixed $default
374 * @return mixed
375 */
376 public function query($key = null, $default = null)
377 {
378 return $key ? Arr::get($this->get, $key, $default) : $this->get;
379 }
380
381 /**
382 * Get an item from the PHP $_POST array
383 * @param string $key
384 * @param mixed $default
385 * @return mixed
386 */
387 public function post($key = null, $default = null)
388 {
389 return $key ? Arr::get($this->post, $key, $default) : $this->post;
390 }
391
392 /**
393 * Return the only items given in the args
394 * @param array $keys
395 * @return array
396 */
397 public function only($keys)
398 {
399 $keys = is_array($keys) ? $keys : func_get_args();
400
401 return Arr::only($this->inputs(), $keys);
402 }
403
404 /**
405 * Return a subset of the request inputs except the given keys
406 * @param array $keys
407 * @return array
408 */
409 public function except($keys)
410 {
411 $keys = is_array($keys) ? $keys : func_get_args();
412
413 return Arr::except($this->inputs(), $keys);
414 }
415
416 /**
417 * Merge array with the request inputs
418 * @param array $data
419 * @return self
420 */
421 public function merge(array $data = [])
422 {
423 $this->request = array_replace($this->inputs(), $data);
424
425 return $this;
426 }
427
428 /**
429 * Merge array with the request inputs
430 * @param array $data
431 * @return self
432 */
433 public function mergeMissing(array $data = [])
434 {
435 $all = $this->inputs();
436
437 $this->merge(Arr::mergeMissing($data, $all));
438
439 return $this;
440 }
441
442 /**
443 * Returns the request body content.
444 *
445 * @param bool $asResource If true, a resource will be returned
446 *
447 * @return string|resource
448 */
449 public function getContent()
450 {
451 if (null === $this->content || false === $this->content) {
452 $this->content = file_get_contents('php://input');
453 }
454
455 return $this->content;
456 }
457
458 /**
459 * Merges the input arrays from the WP_REST_Request.
460 *
461 * @param \WP_REST_Request $wpRestRequest
462 * @return void
463 */
464 public function mergeInputsFromRestRequest($wpRestRequest)
465 {
466 $this->request = array_merge(
467 $this->request, $wpRestRequest->get_params()
468 );
469
470 $this->post = array_merge(
471 $this->post, $wpRestRequest->get_body_params()
472 );
473
474 $this->get = array_merge(
475 $this->get, $wpRestRequest->get_query_params()
476 );
477
478 $this->mergerHeaders($wpRestRequest);
479
480 $this->wpRestRequest = true;
481 }
482
483 /**
484 * Merge the headers from the WP_REST_Request.
485 *
486 * @param WP_REST_Request $wpRestRequest
487 * @return void
488 */
489 protected function mergerHeaders($wpRestRequest)
490 {
491 $headers = [];
492
493 foreach ($wpRestRequest->get_headers() as $key => $header) {
494 $headers[strtoupper($key)] = reset($header);
495 }
496
497 $this->headers = array_merge($this->headers, $headers);
498
499 if (
500 !isset($this->headers['CONTENT_TYPE']) || (
501 isset($this->headers['CONTENT_TYPE']) &&
502 $this->headers['CONTENT_TYPE'] !== true
503 )) {
504 if ($this->isJson()) {
505 $this->headers['CONTENT_TYPE'] = 'application/json';
506 }
507 }
508 }
509
510 /**
511 * Retrieve an input item from the request.
512 *
513 * @param string|null $key
514 * @param mixed $default
515 * @return mixed
516 */
517 public function input($key = null, $default = null)
518 {
519 return Arr::get($this->inputs(), $key, $default);
520 }
521
522 /**
523 * Remove a key(s) from the $request array
524 * @param mixed $key
525 * @return self
526 */
527 public function forget($key)
528 {
529 Arr::forget($this->request, $key);
530
531 return $this;
532 }
533
534 /**
535 * Get all inputs
536 *
537 * @return array $this->request
538 */
539 protected function inputs()
540 {
541 if (!$this->wpRestRequest) {
542 if ($this->app->bound('wprestrequest')) {
543 $this->mergeInputsFromRestRequest($this->app->wprestrequest);
544 }
545 }
546
547 if ($this->safe === true) {
548 $this->safe = false;
549 return $this->validated;
550 }
551
552 return $this->request;
553 }
554
555 /**
556 * To get item(s) from validated inputs
557 *
558 * @return self
559 */
560 public function safe()
561 {
562 $this->safe = true;
563
564 return $this;
565 }
566
567 /**
568 * Get user ip address
569 * @return string
570 */
571 public function getIp()
572 {
573 if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
574 $ip = $this->server('HTTP_CLIENT_IP');
575 } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
576 $ip = $this->server('HTTP_X_FORWARDED_FOR');
577 } else {
578 $ip = $this->server('REMOTE_ADDR');
579 }
580
581 return $ip;
582 }
583
584 /**
585 * Get the request method.
586 *
587 * @return string
588 */
589 public function method()
590 {
591 return $_SERVER['REQUEST_METHOD'];
592 }
593
594 /**
595 * Get the URL (no query string) for the request.
596 *
597 * @return string
598 */
599 public function url()
600 {
601 return preg_replace('/\?.*/', '', $this->getFullUrl());
602 }
603
604 /**
605 * Get the full URL for the request.
606 *
607 * @return string
608 */
609 public function getFullUrl()
610 {
611 return get_site_url() . rtrim($_SERVER['REQUEST_URI'], '/');
612 }
613
614 /**
615 * Validate the request.
616 *
617 * @param string $key
618 * @return mixed
619 */
620 public function validate(array $rules, array $messages = [])
621 {
622 $instance = $this->app->make('validator');
623
624 $validator = $instance->make($data = $this->all(), $rules, $messages);
625
626 if ($validator->validate()->fails()) {
627 throw new ValidationException(
628 'Unprocessable Entity!', 422, null, $validator->errors()
629 );
630 }
631
632 $this->validated = $validator->validated();
633
634 return $data;
635 }
636
637 /**
638 * Get the valid data after validation has been passed.
639 *
640 * @return array
641 */
642 public function validated($data = [])
643 {
644 if ($data) {
645 return $this->validated = $data;
646 }
647
648 return (array) $this->validated;
649 }
650
651 /**
652 * Abort the request.
653 *
654 * @param integer $status
655 * @param string $message
656 * @return \WP_REST_Response
657 */
658 public function abort($status = 403, $message = null)
659 {
660 if (is_object($status)) {
661 if (method_exists($status, 'errors')) {
662 throw new ValidationException(
663 'Unprocessable Entity!', 422, null, $status->errors()
664 );
665 }
666 }
667
668 if (!$message && !is_numeric($status) && is_string($status)) {
669 $message = $status;
670 $status = 403;
671 }
672
673 $message = $message ?: 'Request has benn aborted.';
674
675 return new \WP_REST_Response(
676 is_array($message) ? $message : ['message' => (string) $message], $status
677 );
678 }
679
680 /**
681 * Get an input element from the request.
682 *
683 * @param string $key
684 * @return mixed
685 */
686 public function __get($key)
687 {
688 return $this->get($key);
689 }
690
691 /**
692 * Retrieves the currently logged in user.
693 *
694 * @return \FluentBoards\Framework\Http\Request\WPUserProxy
695 */
696 public function user()
697 {
698 return new WPUserProxy(
699 new \WP_User(get_current_user_id())
700 );
701 }
702
703 /**
704 * Dynamyc method calls (specially for WP_rest_request)
705 * @param string $method
706 * @param array $params
707 * @return mixed
708 */
709 public function __call($method, $params = [])
710 {
711 if (static::hasMacro($method)) {
712 return $this->macroCall($method, $params);
713 }
714
715 if ($method == 'route') {
716 if ($params) {
717 return $this->app->route->{$params[0]};
718 }
719 return $this->app->route;
720 }
721
722 if ($this->app->bound('wprestrequest')) {
723 if (!method_exists($this->app->wprestrequest, $method)) {
724 $method = strtolower(
725 preg_replace([
726 '/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'
727 ], '$1_$2', $method)
728 );
729 }
730
731 return call_user_func_array([
732 $this->app->wprestrequest, $method], $params
733 );
734 }
735 }
736 }
737