PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.0.13
Kirki – Freeform Page Builder, Website Builder & Customizer v6.0.13
6.1.1 6.1.0 6.0.14 6.0.13 6.0.12 6.0.11 6.0.10 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.19 4.0.20 4.0.21 4.0.22 4.0.23 4.0.24 4.1 4.2.0 5.0.0 5.1.0 5.1.1 5.2.0 5.2.1 5.2.2 5.2.3 6.0.0 trunk 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.1.0 3.1.1 3.1.2
kirki / libraries / framework / Http / Request.php
kirki / libraries / framework / Http Last commit date
Client 2 weeks ago Concerns 2 weeks ago JsonResponse.php 2 weeks ago Request.php 2 weeks ago Response.php 2 weeks ago
Request.php
823 lines
1 <?php
2
3 /**
4 * Handles REST API request data abstraction for operations.
5 *
6 * @package Framework
7 * @subpackage Http
8 * @since 1.0.0
9 */
10 namespace Kirki\Framework\Http;
11
12 \defined('ABSPATH') || exit;
13 use BadMethodCallException;
14 use Kirki\Framework\Contracts\Request as RequestContract;
15 use Kirki\Framework\Contracts\Support\Arrayable;
16 use Kirki\Framework\Sanitizer;
17 use Kirki\Framework\Exceptions\AuthorizationException;
18 use Kirki\Framework\Http\Concerns\InteractsWithFiles;
19 use Kirki\Framework\Supports\Arr;
20 use Kirki\Framework\Validation\Validator;
21 use WP_REST_Request;
22 use Kirki\Framework\Supports\Str;
23 use function Kirki\Framework\message;
24 use function Kirki\Framework\user;
25 /**
26 * The Request class for handling HTTP requests.
27 *
28 * @method mixed|null string(string $key, $default = null)
29 * @method mixed|null date(string $key, $default = null)
30 * @method mixed|null datetime(string $key, $default = null)
31 * @method mixed|null text(string $key, $default = null)
32 * @method mixed|null html(string $key, $default = null)
33 * @method mixed|null email(string $key, $default = null)
34 * @method mixed|null url(string $key, $default = null)
35 * @method mixed|null key(string $key, $default = null)
36 * @method mixed|null title(string $key, $default = null)
37 * @method mixed|null file_name(string $key, $default = null)
38 * @method mixed|null mime_type(string $key, $default = null)
39 * @method mixed|null int(string $key, $default = null)
40 * @method mixed|null bool(string $key, $default = null)
41 * @method mixed|null float(string $key, $default = null)
42 * @method mixed|null array(string $key, $default = null)
43 * @method mixed|null whitelisted(string $key, $default = null, array $whitelist = [])
44 */
45 class Request implements RequestContract, Arrayable
46 {
47 use InteractsWithFiles;
48 /**
49 * The request's input attributes.
50 *
51 * @var array
52 *
53 * @since 1.0.0
54 */
55 protected $attributes = [];
56 /**
57 * The HTTP method used for the request (e.g. GET, POST).
58 *
59 * @var string
60 *
61 * @since 1.0.0
62 */
63 protected $method;
64 /**
65 * The route URI for the request.
66 *
67 * @var string
68 *
69 * @since 1.0.0
70 */
71 protected $route;
72 /**
73 * The headers associated with the request.
74 *
75 * @var array
76 *
77 * @since 1.0.0
78 */
79 protected $headers;
80 /**
81 * The sanitized data.
82 *
83 * @var array
84 *
85 * @since 1.0.0
86 */
87 protected array $sanitized = [];
88 /**
89 * The validated data.
90 *
91 * @var array
92 *
93 * @since 1.0.0
94 */
95 protected array $validated = [];
96 /**
97 * Whether the validation has been resolved.
98 *
99 * @var bool
100 *
101 * @since 1.0.0
102 */
103 protected bool $validation_resolved = \false;
104 /**
105 * Registered sanitizer method suffixes for typed request accessors.
106 *
107 * @var array<int, string>
108 *
109 * @since 1.0.0
110 */
111 protected static array $types = ['string', 'date', 'datetime', 'text', 'html', 'email', 'url', 'key', 'title', 'file_name', 'mime_type', 'int', 'bool', 'float', 'array', 'whitelisted'];
112 /**
113 * Magic getter to retrieve request attributes.
114 *
115 * @param string $name The name of the attribute.
116 *
117 * @return mixed|null The attribute value or null if not set.
118 *
119 * @since 1.0.0
120 */
121 public function __get(string $name)
122 {
123 return Arr::get($this->all(), $name, null);
124 }
125 /**
126 * Magic isset to check if an attribute exists.
127 *
128 * @param string $name The name of the attribute.
129 *
130 * @return bool
131 *
132 * @since 1.0.0
133 */
134 public function __isset(string $name)
135 {
136 return !\is_null($this->__get($name));
137 }
138 /**
139 * Magic setter to set request attributes.
140 *
141 * @param string $name The name of the attribute.
142 * @param mixed $value The value to assign.
143 *
144 * @return void
145 *
146 * @since 1.0.0
147 */
148 public function __set(string $name, $value)
149 {
150 $this->attributes[$name] = $value;
151 }
152 /**
153 * Dynamically handle calls to the class.
154 *
155 * @param string $name The name of the method.
156 * @param array $arguments The arguments of the method.
157 *
158 * @return mixed
159 *
160 * @since 1.0.0
161 */
162 public function __call(string $name, array $arguments)
163 {
164 $name = \strtolower($name);
165 if (!\in_array($name, static::$types, \true)) {
166 throw new BadMethodCallException(\sprintf('Method %s::%s does not exist.', static::class, $name));
167 }
168 $method_name = 'get_' . $name;
169 return $this->{$method_name}(...$arguments);
170 }
171 /**
172 * Create a new Request instance from a WP_REST_Request.
173 *
174 * @param WP_REST_Request $request The WordPress REST request object.
175 *
176 * @return self
177 *
178 * @since 1.0.0
179 */
180 public static function from_wp_rest_request(WP_REST_Request $request)
181 {
182 return (new static())->make_request($request);
183 }
184 /**
185 * Make a new request instance from a WP_REST_Request.
186 *
187 * @param WP_REST_Request $request The WordPress REST request object.
188 *
189 * @return self
190 *
191 * @since 1.0.0
192 */
193 public function make_request(WP_REST_Request $request)
194 {
195 $this->attributes = \array_merge($this->attributes, $request->get_params(), $request->get_file_params());
196 $this->method = $request->get_method();
197 $this->route = $request->get_route();
198 $this->headers = $request->get_headers();
199 return $this;
200 }
201 /**
202 * Get the validation rules for the request.
203 *
204 * @return array
205 *
206 * @since 1.0.0
207 */
208 protected function rules()
209 {
210 return [];
211 }
212 /**
213 * Run the validation on the request data.
214 *
215 * @param array $data The data to validate.
216 * @param array $rules The rules.
217 *
218 * @return array
219 *
220 * @since 1.0.0
221 */
222 protected function run_validation(array $data, array $rules)
223 {
224 $validator = Validator::make($data, $rules, $this->messages());
225 if ($validator->validate()) {
226 return $validator->validated();
227 }
228 }
229 /**
230 * Define the sanitization filters for the request.
231 * This will be defined into the extended request class.
232 *
233 * @return array<string,string|callable(mixed):mixed|array>
234 *
235 * @since 1.0.0
236 */
237 protected function filters()
238 {
239 return [];
240 }
241 /**
242 * Define the validation messages for the request.
243 * This will be defined into the extended request class.
244 *
245 * @return array<string,string|callable(mixed):mixed|array>
246 *
247 * @since 1.0.0
248 */
249 protected function messages()
250 {
251 return [];
252 }
253 /**
254 * Run the sanitization on the data.
255 *
256 * @param array $data The data to sanitize.
257 * @param array $filters The filters to apply.
258 *
259 * @return array
260 *
261 * @since 1.0.0
262 */
263 protected function run_sanitization(array $data, array $filters)
264 {
265 return Sanitizer::make($data, $filters)->get_sanitized_data();
266 }
267 /**
268 * Get the current user instance from the request.
269 *
270 * @return \Framework\Wordpress\User
271 *
272 * @since 1.0.0
273 */
274 public function user()
275 {
276 return user();
277 }
278 /**
279 * Get the HTTP method used in the request.
280 *
281 * @return string
282 *
283 * @since 1.0.0
284 */
285 public function get_method()
286 {
287 return $this->method;
288 }
289 /**
290 * Alias of `get_method()`.
291 *
292 * @return string
293 *
294 * @since 1.0.0
295 */
296 public function method()
297 {
298 return $this->get_method();
299 }
300 /**
301 * Get the route URI of the request.
302 *
303 * @return string
304 *
305 * @since 1.0.0
306 */
307 public function get_route()
308 {
309 return $this->route;
310 }
311 /**
312 * Get the headers associated with the request.
313 *
314 * @return array
315 *
316 * @since 1.0.0
317 */
318 public function get_headers()
319 {
320 return $this->headers;
321 }
322 /**
323 * Get a single HTTP header from the request.
324 *
325 * @param string $name The name.
326 * @param mixed $default The default.
327 *
328 * @return mixed
329 *
330 * @since 1.0.0
331 */
332 public function get_header(string $name, $default = null)
333 {
334 $value = $this->headers[$name] ?? $default;
335 if (\is_array($value)) {
336 return $value[0] ?? $default;
337 }
338 return $value;
339 }
340 /**
341 * Alias of `get_header()`.
342 *
343 * @param string $name The name.
344 * @param mixed $default The default.
345 *
346 * @return mixed
347 *
348 * @since 1.0.0
349 */
350 public function header(string $name, $default = null)
351 {
352 return $this->get_header($name, $default);
353 }
354 /**
355 * Get all input attributes.
356 *
357 * @return array
358 *
359 * @since 1.0.0
360 */
361 public function all()
362 {
363 return $this->attributes;
364 }
365 /**
366 * Get the sanitized data.
367 *
368 * @return array
369 *
370 * @since 1.0.0
371 */
372 public function sanitized()
373 {
374 return $this->sanitized;
375 }
376 /**
377 * Get the validated data.
378 *
379 * @return array
380 *
381 * @since 1.0.0
382 */
383 public function validated()
384 {
385 return $this->validated;
386 }
387 /**
388 * Get all input attributes.
389 *
390 * @return array
391 *
392 * @since 1.0.0
393 */
394 public function attributes()
395 {
396 if ($this->has('_method')) {
397 $this->remove('_method');
398 }
399 return $this->attributes;
400 }
401 /**
402 * Authorize the request.
403 *
404 * @return static
405 *
406 * @throws AuthorizationException
407 *
408 * @since 1.0.0
409 */
410 public function authorize_request()
411 {
412 if (!$this->authorize()) {
413 throw new AuthorizationException(message('auth.unauthorized_request'));
414 }
415 return $this;
416 }
417 /**
418 * Validate the request data and sanitize the data.
419 *
420 * @return static
421 *
422 * @since 1.0.0
423 */
424 public function validate_request()
425 {
426 if ($this->validation_resolved) {
427 return $this;
428 }
429 $this->resolve_validation_and_sanitization();
430 $this->validation_resolved = \true;
431 return $this;
432 }
433 /**
434 * Resolve the validation and sanitization.
435 *
436 * @return void
437 *
438 * @throws AuthorizationException
439 *
440 * @since 1.0.0
441 */
442 protected function resolve_validation_and_sanitization()
443 {
444 $this->prepare_for_validation();
445 $sanitized = $this->run_sanitization($this->attributes(), $this->filters());
446 $this->sanitized = $sanitized;
447 $this->merge($sanitized);
448 $validated = $this->run_validation($this->attributes(), $this->rules());
449 $this->validated = $validated;
450 $this->passed_validation();
451 }
452 /**
453 * Prepare the request data for validation.
454 *
455 * @return void
456 *
457 * @since 1.0.0
458 */
459 protected function prepare_for_validation()
460 {
461 // Override this method to prepare the request data for validation.
462 }
463 /**
464 * Handle the passed validation.
465 *
466 * @return void
467 *
468 * @since 1.0.0
469 */
470 protected function passed_validation()
471 {
472 // Override this method to handle the passed validation.
473 }
474 /**
475 * Determine if the user is authorized to make this request.
476 *
477 * @return bool
478 *
479 * @since 1.0.0
480 */
481 protected function authorize()
482 {
483 return \true;
484 }
485 /**
486 * Merge the given input with the existing attributes.
487 *
488 * @param array $input The input to merge.
489 *
490 * @return static
491 *
492 * @since 1.0.0
493 */
494 public function merge(array $input)
495 {
496 $this->attributes = \array_merge($this->attributes, $input);
497 return $this;
498 }
499 /**
500 * Check if an attribute exists.
501 *
502 * @param string $key The key of the attribute.
503 *
504 * @return bool
505 *
506 * @since 1.0.0
507 */
508 public function has(string $key)
509 {
510 return isset($this->attributes[$key]);
511 }
512 /**
513 * Remove an attribute.
514 *
515 * @param string $key The key of the attribute.
516 *
517 * @return void
518 *
519 * @since 1.0.0
520 */
521 public function remove(string $key)
522 {
523 unset($this->attributes[$key]);
524 }
525 /**
526 * Get all input attributes except the specified keys.
527 *
528 * @param array $attributes The attribute keys to exclude.
529 *
530 * @return array
531 *
532 * @since 1.0.0
533 */
534 public function except(array $attributes)
535 {
536 return \array_diff_key($this->attributes, \array_flip($attributes));
537 }
538 /**
539 * Get a single input attribute by key.
540 *
541 * @param string $key The key of the attribute.
542 *
543 * @return mixed|null
544 *
545 * @since 1.0.0
546 */
547 public function only(string $key)
548 {
549 return $this->attributes[$key] ?? null;
550 }
551 /**
552 * Alias for the `only()` method.
553 *
554 * @param string $key The key of the attribute.
555 *
556 * @return mixed|null
557 *
558 * @since 1.0.0
559 */
560 public function input(string $key)
561 {
562 return $this->only($key);
563 }
564 /**
565 * Get a value from the request with optional default and type casting.
566 *
567 * @param string $key The key to retrieve.
568 * @param mixed $default Default value if the key doesn't exist.
569 * @param string|null $type Optional type to cast the result to:
570 * int, float, bool, string, array with proper sanitization.
571 *
572 * @return mixed|null
573 *
574 * @since 1.0.0
575 */
576 public function get(string $key, $default = null, $type = null)
577 {
578 $value = isset($this->attributes[$key]) ? $this->attributes[$key] : $default;
579 $value = Sanitizer::apply_rule($value, $type);
580 return $value;
581 }
582 /**
583 * Get a value from the request with optional default and type casting.
584 *
585 * @param string $key The key to retrieve.
586 * @param mixed $default Default value if the key doesn't exist.
587 * @param array $whitelist Optional whitelist of allowed values.
588 *
589 * @return mixed
590 *
591 * @since 1.0.0
592 */
593 public function get_whitelisted(string $key, $default = null, array $whitelist = [])
594 {
595 $value = $this->get($key);
596 if (!\in_array($value, $whitelist, \true)) {
597 return $default;
598 }
599 return $value;
600 }
601 /**
602 * Get a string value with sanitization applied.
603 *
604 * @param string $key The key to retrieve.
605 * @param string|null $default Default value if the key doesn't exist.
606 *
607 * @return string|null
608 *
609 * @since 1.0.0
610 */
611 public function get_string(string $key, $default = null)
612 {
613 return $this->get($key, $default, Sanitizer::TEXT);
614 }
615 /**
616 * Get a date value.
617 *
618 * @param string $key The key to retrieve.
619 * @param string|null $default Default value if the key doesn't exist.
620 *
621 * @return string
622 *
623 * @since 1.0.0
624 */
625 public function get_date(string $key, $default = null)
626 {
627 return $this->get($key, $default, Sanitizer::DATE);
628 }
629 /**
630 * Get a datetime value.
631 *
632 * @param string $key The key to retrieve.
633 * @param string|null $default Default value if the key doesn't exist.
634 *
635 * @return string
636 *
637 * @since 1.0.0
638 */
639 public function get_datetime(string $key, $default = null)
640 {
641 return $this->get($key, $default, Sanitizer::DATETIME);
642 }
643 /**
644 * Get a text with sanitization applied.
645 *
646 * @param string $key The key to retrieve.
647 * @param string|null $default Default value if the key doesn't exist.
648 *
649 * @return string|null
650 *
651 * @since 1.0.0
652 */
653 public function get_text(string $key, $default = null)
654 {
655 return $this->get_string($key, $default);
656 }
657 /**
658 * Get a html supported content with sanitization applied.
659 *
660 * @param string $key The key to retrieve.
661 * @param string|null $default Default value if the key doesn't exist.
662 *
663 * @return string|null
664 *
665 * @since 1.0.0
666 */
667 public function get_html(string $key, $default = null)
668 {
669 return $this->get($key, $default, Sanitizer::RICH_TEXT);
670 }
671 /**
672 * Get a email with sanitization applied.
673 *
674 * @param string $key The key to retrieve.
675 * @param string|null $default Default value if the key doesn't exist.
676 *
677 * @return string|null
678 *
679 * @since 1.0.0
680 */
681 public function get_email(string $key, $default = null)
682 {
683 return $this->get($key, $default, Sanitizer::EMAIL);
684 }
685 /**
686 * Get a url with sanitization applied.
687 *
688 * @param string $key The key to retrieve.
689 * @param string|null $default Default value if the key doesn't exist.
690 *
691 * @return string|null
692 *
693 * @since 1.0.0
694 */
695 public function get_url(string $key, $default = null)
696 {
697 return $this->get($key, $default, Sanitizer::URL);
698 }
699 /**
700 * Get a key value with sanitization applied.
701 *
702 * @param string $key The key to retrieve.
703 * @param string|null $default Default value if the key doesn't exist.
704 *
705 * @return string|null
706 *
707 * @since 1.0.0
708 */
709 public function get_key(string $key, $default = null)
710 {
711 return $this->get($key, $default, Sanitizer::KEY);
712 }
713 /**
714 * Get a title value with sanitization applied.
715 *
716 * @param string $key The key to retrieve.
717 * @param string|null $default Default value if the key doesn't exist.
718 *
719 * @return string|null
720 *
721 * @since 1.0.0
722 */
723 public function get_title(string $key, $default = null)
724 {
725 return $this->get($key, $default, Sanitizer::TITLE);
726 }
727 /**
728 * Get a file name with sanitization applied.
729 *
730 * @param string $key The key to retrieve.
731 * @param string|null $default Default value if the key doesn't exist.
732 *
733 * @return string|null
734 *
735 * @since 1.0.0
736 */
737 public function get_file_name(string $key, $default = null)
738 {
739 return $this->get($key, $default, Sanitizer::FILE_NAME);
740 }
741 /**
742 * Get mime type with sanitization applied.
743 *
744 * @param string $key The key to retrieve.
745 * @param string|null $default Default value if the key doesn't exist.
746 *
747 * @return string|null
748 *
749 * @since 1.0.0
750 */
751 public function get_mime_type(string $key, $default = null)
752 {
753 return $this->get($key, $default, Sanitizer::MIME_TYPE);
754 }
755 /**
756 * Get an integer value.
757 *
758 * @param string $key The key to retrieve.
759 * @param int|null $default Default value if the key doesn't exist.
760 *
761 * @return int|null
762 *
763 * @since 1.0.0
764 */
765 public function get_int(string $key, $default = null)
766 {
767 return $this->get($key, $default, Sanitizer::INT);
768 }
769 /**
770 * Get a boolean value.
771 *
772 * @param string $key The key to retrieve.
773 * @param bool $default Default value if the key doesn't exist.
774 *
775 * @return bool
776 *
777 * @since 1.0.0
778 */
779 public function get_bool(string $key, bool $default = \false)
780 {
781 return $this->get($key, $default, Sanitizer::BOOL);
782 }
783 /**
784 * Get a float value.
785 *
786 * @param string $key The key to retrieve.
787 * @param float|null $default Default value if the key doesn't exist.
788 *
789 * @return float|null
790 *
791 * @since 1.0.0
792 */
793 public function get_float(string $key, $default = null)
794 {
795 return $this->get($key, $default, Sanitizer::FLOAT);
796 }
797 /**
798 * Get an array value.
799 *
800 * @param string $key The key to retrieve.
801 * @param array|null $default Default value if the key doesn't exist.
802 *
803 * @return array|null
804 *
805 * @since 1.0.0
806 */
807 public function get_array(string $key, $default = null)
808 {
809 return $this->get($key, $default, Sanitizer::ARRAY);
810 }
811 /**
812 * Convert the request to an array.
813 *
814 * @return array
815 *
816 * @since 1.0.0
817 */
818 public function to_array()
819 {
820 return $this->all();
821 }
822 }
823