PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.94
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.94
2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 1.1.0 All 77 releases
fluent-community / vendor / wpfluent / framework / src / WPFluent / Http / Request / Request.php

Request.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 1.0.94, at vendor/wpfluent/framework/src/WPFluent/Http/Request/Request.php

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