PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 1.10.0
Fluent Support – Helpdesk & Customer Support Ticket System v1.10.0
2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 68 releases
fluent-support / vendor / wpfluent / framework / src / WPFluent / Request / Request.php

Request.php in Fluent Support – Helpdesk & Customer Support Ticket System 1.10.0, at vendor/wpfluent/framework/src/WPFluent/Request/Request.php

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