PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / 1.5.22
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution v1.5.22
2.4.0 2.3.0 2.2.5 2.2.0 2.1.2 2.1.1 trunk 1.10.0 1.10.01 1.10.02 1.5.0 1.5.01 1.5.02 1.5.1 1.5.10 1.5.20 1.5.21 1.5.22 1.5.23 1.5.24 1.5.25 1.6.0 1.7.0 1.7.1 1.7.2 All 33 releases
fluent-booking / vendor / wpfluent / framework / src / WPFluent / Http / Request / Request.php

Request.php in Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution 1.5.22, at vendor/wpfluent/framework/src/WPFluent/Http/Request/Request.php

701 lines 17.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBooking\Framework\Http\Request;
4
5 use FluentBooking\Framework\Support\Arr;
6 use FluentBooking\Framework\Support\Helper;
7 use FluentBooking\Framework\Foundation\Application;
8 use FluentBooking\Framework\Validator\ValidationException;
9
10 class Request
11 {
12 use FileHandler, Cleaner, InputHelperMethodsTrait;
13
14 /**
15 * The application instance
16 * @var \FluentBooking\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 \FluentBooking\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 = (defined('REST_REQUEST') && REST_REQUEST) || $this->query('rest_route');
241
242 return $isRest || (function() {
243 $currentUrl = wp_parse_url(add_query_arg([]));
244 $restUrl = wp_parse_url(trailingslashit(rest_url()));
245 return strpos($currentUrl['path'] ?? '/', $restUrl['path']);
246 })() !== false;
247 }
248
249 /**
250 * Retrieve an item from the json payload of the request
251 * @param string $key
252 * @param string $default
253 * @return mixed
254 */
255 public function json($key = null, $default = null)
256 {
257 if (!$this->isJson()) return;
258
259 if (!isset($this->json)) {
260 $json = $this->get_json_params() ?: $this->getContent();
261
262 $this->json = (array) json_decode($json, true);
263 }
264
265 if (is_null($key)) {
266 return $this->json;
267 }
268
269 return Helper::dataGet($this->json, $key, $default);
270 }
271
272 /**
273 * Retrieve an item from the PHP $_SERVER array
274 * @param string $key
275 * @param string $default
276 * @return mixed
277 */
278 public function server($key = null, $default = null)
279 {
280 return $key ? Arr::get($this->server, $key, $default) : $this->server;
281 }
282
283 /**
284 * Retrieve an item from the PHP headers
285 * @param string $key
286 * @param string $default
287 * @return mixed
288 */
289 public function header($key = null, $default = null)
290 {
291 if (!$this->headers) {
292 $this->headers = $this->setHeaders();
293 }
294
295 return $key ? Arr::get($this->headers, $key, $default) : $this->headers;
296 }
297
298 /**
299 * Retrieve an item from the cookie
300 * @param string $key
301 * @param mixed $default
302 * @return mixed
303 */
304 public function cookie($key = null, $default = null)
305 {
306 $cookie = $key ? Arr::get($this->cookie, $key, $default) : $this->cookie;
307
308 return json_decode(base64_decode($cookie, true));
309 }
310
311 /**
312 * Get the files from the request.
313 *
314 * @return array
315 */
316 public function files()
317 {
318 return $this->files;
319 }
320
321 /**
322 * Get an item from the PHP $_GET array
323 * @param string $key
324 * @param mixed $default
325 * @return mixed
326 */
327 public function query($key = null, $default = null)
328 {
329 return $key ? Arr::get($this->get, $key, $default) : $this->get;
330 }
331
332 /**
333 * Get an item from the PHP $_POST array
334 * @param string $key
335 * @param mixed $default
336 * @return mixed
337 */
338 public function post($key = null, $default = null)
339 {
340 return $key ? Arr::get($this->post, $key, $default) : $this->post;
341 }
342
343 /**
344 * Return the only items given in the args
345 * @param array $keys
346 * @return array
347 */
348 public function only($keys)
349 {
350 $keys = is_array($keys) ? $keys : func_get_args();
351
352 return Arr::only($this->inputs(), $keys);
353 }
354
355 /**
356 * Return a subset of the request inputs except the given keys
357 * @param array $keys
358 * @return array
359 */
360 public function except($keys)
361 {
362 $keys = is_array($keys) ? $keys : func_get_args();
363
364 return Arr::except($this->inputs(), $keys);
365 }
366
367 /**
368 * Merge array with the request inputs
369 * @param array $data
370 * @return self
371 */
372 public function merge(array $data = [])
373 {
374 $this->request = array_replace($this->inputs(), $data);
375
376 return $this;
377 }
378
379 /**
380 * Merge array with the request inputs
381 * @param array $data
382 * @return self
383 */
384 public function mergeMissing(array $data = [])
385 {
386 $all = $this->inputs();
387
388 $this->merge(Arr::mergeMissing($data, $all));
389
390 return $this;
391 }
392
393 /**
394 * Returns the request body content.
395 *
396 * @param bool $asResource If true, a resource will be returned
397 *
398 * @return string|resource
399 */
400 public function getContent()
401 {
402 if (null === $this->content || false === $this->content) {
403 $this->content = file_get_contents('php://input');
404 }
405
406 return $this->content;
407 }
408
409 public function mergeInputsFromRestRequest($wpRestRequest)
410 {
411 $this->request = array_merge(
412 $this->request, $wpRestRequest->get_params()
413 );
414
415 $this->post = array_merge(
416 $this->post, $wpRestRequest->get_body_params()
417 );
418
419 $this->get = array_merge(
420 $this->get, $wpRestRequest->get_query_params()
421 );
422
423 $this->wpRestRequest = true;
424 }
425
426 /**
427 * Retrieve an input item from the request.
428 *
429 * @param string|null $key
430 * @param mixed $default
431 * @return mixed
432 */
433 public function input($key = null, $default = null)
434 {
435 return Arr::get($this->inputs(), $key, $default);
436 }
437
438 /**
439 * Remove a key(s) from the $request array
440 * @param mixed $key
441 * @return self
442 */
443 public function forget($key)
444 {
445 Arr::forget($this->request, $key);
446
447 return $this;
448 }
449
450 /**
451 * Get all inputs
452 *
453 * @return array $this->request
454 */
455 protected function inputs()
456 {
457 if (!$this->wpRestRequest) {
458 if ($this->app->bound('wprestrequest')) {
459 $this->mergeInputsFromRestRequest($this->app->wprestrequest);
460 }
461 }
462
463 if ($this->safe === true) {
464 $this->safe = false;
465 return $this->validated;
466 }
467
468 return $this->request;
469 }
470
471 /**
472 * To get item(s) from validated inputs
473 *
474 * @return self
475 */
476 public function safe()
477 {
478 $this->safe = true;
479
480 return $this;
481 }
482
483 /**
484 * Get user ip address
485 * @return string
486 */
487 public function getIp()
488 {
489 if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
490 $ip = $this->server('HTTP_CLIENT_IP');
491 } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
492 $ip = $this->server('HTTP_X_FORWARDED_FOR');
493 } else {
494 $ip = $this->server('REMOTE_ADDR');
495 }
496
497 return $ip;
498 }
499
500 /**
501 * Taken and modified from Symfony
502 */
503 public function setHeaders()
504 {
505 $headers = array();
506 $parameters = $this->server;
507 $contentHeaders = array('CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true);
508 foreach ($parameters as $key => $value) {
509 if (0 === strpos($key, 'HTTP_')) {
510 $headers[substr($key, 5)] = $value;
511 } // CONTENT_* are not prefixed with HTTP_
512 elseif (isset($contentHeaders[$key])) {
513 $headers[$key] = $value;
514 }
515 }
516
517 if (isset($parameters['PHP_AUTH_USER'])) {
518 $headers['PHP_AUTH_USER'] = $parameters['PHP_AUTH_USER'];
519 $headers['PHP_AUTH_PW'] = isset($parameters['PHP_AUTH_PW']) ? $parameters['PHP_AUTH_PW'] : '';
520 } else {
521 /*
522 * php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default
523 * For this workaround to work, add these lines to your .htaccess file:
524 * RewriteCond %{HTTP:Authorization} ^(.+)$
525 * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
526 *
527 * A sample .htaccess file:
528 * RewriteEngine On
529 * RewriteCond %{HTTP:Authorization} ^(.+)$
530 * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
531 * RewriteCond %{REQUEST_FILENAME} !-f
532 * RewriteRule ^(.*)$ app.php [QSA,L]
533 */
534
535 $authorizationHeader = null;
536 if (isset($parameters['HTTP_AUTHORIZATION'])) {
537 $authorizationHeader = $parameters['HTTP_AUTHORIZATION'];
538 } elseif (isset($parameters['REDIRECT_HTTP_AUTHORIZATION'])) {
539 $authorizationHeader = $parameters['REDIRECT_HTTP_AUTHORIZATION'];
540 }
541
542 if (null !== $authorizationHeader) {
543 if (0 === stripos($authorizationHeader, 'basic ')) {
544 // Decode AUTHORIZATION header into PHP_AUTH_USER and PHP_AUTH_PW when authorization header is basic
545 $exploded = explode(':', base64_decode(substr($authorizationHeader, 6)), 2);
546 if (count($exploded) == 2) {
547 list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded;
548 }
549 } elseif (empty($parameters['PHP_AUTH_DIGEST']) && (0 === stripos($authorizationHeader, 'digest '))) {
550 // In some circumstances PHP_AUTH_DIGEST needs to be set
551 $headers['PHP_AUTH_DIGEST'] = $authorizationHeader;
552 $parameters['PHP_AUTH_DIGEST'] = $authorizationHeader;
553 } elseif (0 === stripos($authorizationHeader, 'bearer ')) {
554 /*
555 * XXX: Since there is no PHP_AUTH_BEARER in PHP predefined variables,
556 * I'll just set $headers['AUTHORIZATION'] here.
557 * http://php.net/manual/en/reserved.variables.server.php
558 */
559 $headers['AUTHORIZATION'] = $authorizationHeader;
560 }
561 }
562 }
563
564 if (isset($headers['AUTHORIZATION'])) {
565 return $headers;
566 }
567
568 // PHP_AUTH_USER/PHP_AUTH_PW
569 if (isset($headers['PHP_AUTH_USER'])) {
570 $headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']);
571 } elseif (isset($headers['PHP_AUTH_DIGEST'])) {
572 $headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST'];
573 }
574
575 return $headers;
576 }
577
578 public function method()
579 {
580 return $_SERVER['REQUEST_METHOD'];
581 }
582
583 /**
584 * Get the URL (no query string) for the request.
585 *
586 * @return string
587 */
588 public function url()
589 {
590 return get_site_url() . rtrim(
591 preg_replace('/\?.*/', '', $_SERVER['REQUEST_URI']), '/'
592 );
593 }
594
595 /**
596 * Validate the request.
597 *
598 * @param string $key
599 * @return mixed
600 */
601 public function validate(array $rules, array $messages = [])
602 {
603 $instance = $this->app->make('validator');
604
605 $validator = $instance->make($data = $this->all(), $rules, $messages);
606
607 if ($validator->validate()->fails()) {
608 throw new ValidationException(
609 'Unprocessable Entity!', 422, null, $validator->errors()
610 );
611 }
612
613 $this->validated = $validator->validated();
614
615 return $data;
616 }
617
618 /**
619 * Get the valid data after validation has been passed.
620 *
621 * @return array
622 */
623 public function validated($data = [])
624 {
625 if ($data) {
626 return $this->validated = $data;
627 }
628
629 return (array) $this->validated;
630 }
631
632 /**
633 * Abort the request.
634 *
635 * @param integer $status
636 * @param string $message
637 * @return \WP_REST_Response
638 */
639 public function abort($status = 403, $message = null)
640 {
641 if (is_object($status)) {
642 if (method_exists($status, 'errors')) {
643 throw new ValidationException(
644 'Unprocessable Entity!', 422, null, $status->errors()
645 );
646 }
647 }
648
649 if (!$message && !is_numeric($status) && is_string($status)) {
650 $message = $status;
651 $status = 403;
652 }
653
654 $message = $message ?: 'Request has benn aborted.';
655
656 return new \WP_REST_Response(
657 is_array($message) ? $message : ['message' => (string) $message], $status
658 );
659 }
660
661 /**
662 * Get an input element from the request.
663 *
664 * @param string $key
665 * @return mixed
666 */
667 public function __get($key)
668 {
669 return $this->get($key);
670 }
671
672 /**
673 * Dynamyc method calls (specially for WP_rest_request)
674 * @param string $method
675 * @param array $params
676 * @return mixed
677 */
678 public function __call($method, $params)
679 {
680 if ($method == 'route') {
681
682 if ($params) {
683 return $this->app->route->{$params[0]};
684 }
685
686 return $this->app->route;
687 }
688
689 if ($this->app->bound('wprestrequest')) {
690
691 if (!method_exists($this->app->wprestrequest, $method)) {
692 $method = strtolower(
693 preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $method)
694 );
695 }
696
697 return call_user_func_array([$this->app->wprestrequest, $method], $params);
698 }
699 }
700 }
701