run:R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
25.9 KB
2026-03-11 16:18:52
R W Run
7.2 KB
2026-03-11 16:18:52
R W Run
56.67 KB
2026-03-11 16:18:52
R W Run
error_log
📄class-wp-rest-request.php
1<?php
2/**
3 * REST API: WP_REST_Request class
4 *
5 * @package WordPress
6 * @subpackage REST_API
7 * @since 4.4.0
8 */
9
10/**
11 * Core class used to implement a REST request object.
12 *
13 * Contains data from the request, to be passed to the callback.
14 *
15 * Note: This implements ArrayAccess, and acts as an array of parameters when
16 * used in that manner. It does not use ArrayObject (as we cannot rely on SPL),
17 * so be aware it may have non-array behavior in some cases.
18 *
19 * Note: When using features provided by ArrayAccess, be aware that WordPress deliberately
20 * does not distinguish between arguments of the same name for different request methods.
21 * For instance, in a request with `GET id=1` and `POST id=2`, `$request['id']` will equal
22 * 2 (`POST`) not 1 (`GET`). For more precision between request methods, use
23 * WP_REST_Request::get_body_params(), WP_REST_Request::get_url_params(), etc.
24 *
25 * @since 4.4.0
26 *
27 * @link https://www.php.net/manual/en/class.arrayaccess.php
28 */
29#[AllowDynamicProperties]
30class WP_REST_Request implements ArrayAccess {
31
32 /**
33 * HTTP method.
34 *
35 * @since 4.4.0
36 * @var string
37 */
38 protected $method = '';
39
40 /**
41 * Parameters passed to the request.
42 *
43 * These typically come from the `$_GET`, `$_POST` and `$_FILES`
44 * superglobals when being created from the global scope.
45 *
46 * @since 4.4.0
47 * @var array Contains GET, POST and FILES keys mapping to arrays of data.
48 */
49 protected $params;
50
51 /**
52 * HTTP headers for the request.
53 *
54 * @since 4.4.0
55 * @var array Map of key to value. Key is always lowercase, as per HTTP specification.
56 */
57 protected $headers = array();
58
59 /**
60 * Body data.
61 *
62 * @since 4.4.0
63 * @var string Binary data from the request.
64 */
65 protected $body = null;
66
67 /**
68 * Route matched for the request.
69 *
70 * @since 4.4.0
71 * @var string
72 */
73 protected $route;
74
75 /**
76 * Attributes (options) for the route that was matched.
77 *
78 * This is the options array used when the route was registered, typically
79 * containing the callback as well as the valid methods for the route.
80 *
81 * @since 4.4.0
82 * @var array Attributes for the request.
83 */
84 protected $attributes = array();
85
86 /**
87 * Used to determine if the JSON data has been parsed yet.
88 *
89 * Allows lazy-parsing of JSON data where possible.
90 *
91 * @since 4.4.0
92 * @var bool
93 */
94 protected $parsed_json = false;
95
96 /**
97 * Used to determine if the body data has been parsed yet.
98 *
99 * @since 4.4.0
100 * @var bool
101 */
102 protected $parsed_body = false;
103
104 /**
105 * Constructor.
106 *
107 * @since 4.4.0
108 *
109 * @param string $method Optional. Request method. Default empty.
110 * @param string $route Optional. Request route. Default empty.
111 * @param array $attributes Optional. Request attributes. Default empty array.
112 */
113 public function __construct( $method = '', $route = '', $attributes = array() ) {
114 $this->params = array(
115 'URL' => array(),
116 'GET' => array(),
117 'POST' => array(),
118 'FILES' => array(),
119
120 // See parse_json_params.
121 'JSON' => null,
122
123 'defaults' => array(),
124 );
125
126 $this->set_method( $method );
127 $this->set_route( $route );
128 $this->set_attributes( $attributes );
129 }
130
131 /**
132 * Retrieves the HTTP method for the request.
133 *
134 * @since 4.4.0
135 *
136 * @return string HTTP method.
137 */
138 public function get_method() {
139 return $this->method;
140 }
141
142 /**
143 * Sets HTTP method for the request.
144 *
145 * @since 4.4.0
146 *
147 * @param string $method HTTP method.
148 */
149 public function set_method( $method ) {
150 $this->method = strtoupper( $method );
151 }
152
153 /**
154 * Retrieves all headers from the request.
155 *
156 * @since 4.4.0
157 *
158 * @return array Map of key to value. Key is always lowercase, as per HTTP specification.
159 */
160 public function get_headers() {
161 return $this->headers;
162 }
163
164 /**
165 * Determines if the request is the given method.
166 *
167 * @since 6.8.0
168 *
169 * @param string $method HTTP method.
170 * @return bool Whether the request is of the given method.
171 */
172 public function is_method( $method ) {
173 return $this->get_method() === strtoupper( $method );
174 }
175
176 /**
177 * Canonicalizes the header name.
178 *
179 * Ensures that header names are always treated the same regardless of
180 * source. Header names are always case-insensitive.
181 *
182 * Note that we treat `-` (dashes) and `_` (underscores) as the same
183 * character, as per header parsing rules in both Apache and nginx.
184 *
185 * @link https://stackoverflow.com/q/18185366
186 * @link https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#missing-disappearing-http-headers
187 * @link https://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers
188 *
189 * @since 4.4.0
190 *
191 * @param string $key Header name.
192 * @return string Canonicalized name.
193 */
194 public static function canonicalize_header_name( $key ) {
195 $key = strtolower( $key );
196 $key = str_replace( '-', '_', $key );
197
198 return $key;
199 }
200
201 /**
202 * Retrieves the given header from the request.
203 *
204 * If the header has multiple values, they will be concatenated with a comma
205 * as per the HTTP specification. Be aware that some non-compliant headers
206 * (notably cookie headers) cannot be joined this way.
207 *
208 * @since 4.4.0
209 *
210 * @param string $key Header name, will be canonicalized to lowercase.
211 * @return string|null String value if set, null otherwise.
212 */
213 public function get_header( $key ) {
214 $key = $this->canonicalize_header_name( $key );
215
216 if ( ! isset( $this->headers[ $key ] ) ) {
217 return null;
218 }
219
220 return implode( ',', $this->headers[ $key ] );
221 }
222
223 /**
224 * Retrieves header values from the request.
225 *
226 * @since 4.4.0
227 *
228 * @param string $key Header name, will be canonicalized to lowercase.
229 * @return array|null List of string values if set, null otherwise.
230 */
231 public function get_header_as_array( $key ) {
232 $key = $this->canonicalize_header_name( $key );
233
234 if ( ! isset( $this->headers[ $key ] ) ) {
235 return null;
236 }
237
238 return $this->headers[ $key ];
239 }
240
241 /**
242 * Sets the header on request.
243 *
244 * @since 4.4.0
245 *
246 * @param string $key Header name.
247 * @param string $value Header value, or list of values.
248 */
249 public function set_header( $key, $value ) {
250 $key = $this->canonicalize_header_name( $key );
251 $value = (array) $value;
252
253 $this->headers[ $key ] = $value;
254 }
255
256 /**
257 * Appends a header value for the given header.
258 *
259 * @since 4.4.0
260 *
261 * @param string $key Header name.
262 * @param string $value Header value, or list of values.
263 */
264 public function add_header( $key, $value ) {
265 $key = $this->canonicalize_header_name( $key );
266 $value = (array) $value;
267
268 if ( ! isset( $this->headers[ $key ] ) ) {
269 $this->headers[ $key ] = array();
270 }
271
272 $this->headers[ $key ] = array_merge( $this->headers[ $key ], $value );
273 }
274
275 /**
276 * Removes all values for a header.
277 *
278 * @since 4.4.0
279 *
280 * @param string $key Header name.
281 */
282 public function remove_header( $key ) {
283 $key = $this->canonicalize_header_name( $key );
284 unset( $this->headers[ $key ] );
285 }
286
287 /**
288 * Sets headers on the request.
289 *
290 * @since 4.4.0
291 *
292 * @param array $headers Map of header name to value.
293 * @param bool $override If true, replace the request's headers. Otherwise, merge with existing.
294 */
295 public function set_headers( $headers, $override = true ) {
296 if ( true === $override ) {
297 $this->headers = array();
298 }
299
300 foreach ( $headers as $key => $value ) {
301 $this->set_header( $key, $value );
302 }
303 }
304
305 /**
306 * Retrieves the Content-Type of the request.
307 *
308 * @since 4.4.0
309 *
310 * @return array|null Map containing 'value' and 'parameters' keys
311 * or null when no valid Content-Type header was
312 * available.
313 */
314 public function get_content_type() {
315 $value = $this->get_header( 'Content-Type' );
316 if ( empty( $value ) ) {
317 return null;
318 }
319
320 $parameters = '';
321 if ( strpos( $value, ';' ) ) {
322 list( $value, $parameters ) = explode( ';', $value, 2 );
323 }
324
325 $value = strtolower( $value );
326 if ( ! str_contains( $value, '/' ) ) {
327 return null;
328 }
329
330 // Parse type and subtype out.
331 list( $type, $subtype ) = explode( '/', $value, 2 );
332
333 $data = compact( 'value', 'type', 'subtype', 'parameters' );
334 $data = array_map( 'trim', $data );
335
336 return $data;
337 }
338
339 /**
340 * Checks if the request has specified a JSON Content-Type.
341 *
342 * @since 5.6.0
343 *
344 * @return bool True if the Content-Type header is JSON.
345 */
346 public function is_json_content_type() {
347 $content_type = $this->get_content_type();
348
349 return isset( $content_type['value'] ) && wp_is_json_media_type( $content_type['value'] );
350 }
351
352 /**
353 * Retrieves the parameter priority order.
354 *
355 * Used when checking parameters in WP_REST_Request::get_param().
356 *
357 * @since 4.4.0
358 *
359 * @return string[] Array of types to check, in order of priority.
360 */
361 protected function get_parameter_order() {
362 $order = array();
363
364 if ( $this->is_json_content_type() ) {
365 $order[] = 'JSON';
366 }
367
368 $this->parse_json_params();
369
370 // Ensure we parse the body data.
371 $body = $this->get_body();
372
373 if ( 'POST' !== $this->method && ! empty( $body ) ) {
374 $this->parse_body_params();
375 }
376
377 $accepts_body_data = array( 'POST', 'PUT', 'PATCH', 'DELETE' );
378 if ( in_array( $this->method, $accepts_body_data, true ) ) {
379 $order[] = 'POST';
380 }
381
382 $order[] = 'GET';
383 $order[] = 'URL';
384 $order[] = 'defaults';
385
386 /**
387 * Filters the parameter priority order for a REST API request.
388 *
389 * The order affects which parameters are checked when using WP_REST_Request::get_param()
390 * and family. This acts similarly to PHP's `request_order` setting.
391 *
392 * @since 4.4.0
393 *
394 * @param string[] $order Array of types to check, in order of priority.
395 * @param WP_REST_Request $request The request object.
396 */
397 return apply_filters( 'rest_request_parameter_order', $order, $this );
398 }
399
400 /**
401 * Retrieves a parameter from the request.
402 *
403 * @since 4.4.0
404 *
405 * @param string $key Parameter name.
406 * @return mixed|null Value if set, null otherwise.
407 */
408 public function get_param( $key ) {
409 $order = $this->get_parameter_order();
410
411 foreach ( $order as $type ) {
412 // Determine if we have the parameter for this type.
413 if ( isset( $this->params[ $type ][ $key ] ) ) {
414 return $this->params[ $type ][ $key ];
415 }
416 }
417
418 return null;
419 }
420
421 /**
422 * Checks if a parameter exists in the request.
423 *
424 * This allows distinguishing between an omitted parameter,
425 * and a parameter specifically set to null.
426 *
427 * @since 5.3.0
428 *
429 * @param string $key Parameter name.
430 * @return bool True if a param exists for the given key.
431 */
432 public function has_param( $key ) {
433 $order = $this->get_parameter_order();
434
435 foreach ( $order as $type ) {
436 if ( is_array( $this->params[ $type ] ) && array_key_exists( $key, $this->params[ $type ] ) ) {
437 return true;
438 }
439 }
440
441 return false;
442 }
443
444 /**
445 * Sets a parameter on the request.
446 *
447 * If the given parameter key exists in any parameter type an update will take place,
448 * otherwise a new param will be created in the first parameter type (respecting
449 * get_parameter_order()).
450 *
451 * @since 4.4.0
452 *
453 * @param string $key Parameter name.
454 * @param mixed $value Parameter value.
455 */
456 public function set_param( $key, $value ) {
457 $order = $this->get_parameter_order();
458 $found_key = false;
459
460 foreach ( $order as $type ) {
461 if ( 'defaults' !== $type && is_array( $this->params[ $type ] ) && array_key_exists( $key, $this->params[ $type ] ) ) {
462 $this->params[ $type ][ $key ] = $value;
463 $found_key = true;
464 }
465 }
466
467 if ( ! $found_key ) {
468 $this->params[ $order[0] ][ $key ] = $value;
469 }
470 }
471
472 /**
473 * Retrieves merged parameters from the request.
474 *
475 * The equivalent of get_param(), but returns all parameters for the request.
476 * Handles merging all the available values into a single array.
477 *
478 * @since 4.4.0
479 *
480 * @return array Map of key to value.
481 */
482 public function get_params() {
483 $order = $this->get_parameter_order();
484 $order = array_reverse( $order, true );
485
486 $params = array();
487 foreach ( $order as $type ) {
488 /*
489 * array_merge() / the "+" operator will mess up
490 * numeric keys, so instead do a manual foreach.
491 */
492 foreach ( (array) $this->params[ $type ] as $key => $value ) {
493 $params[ $key ] = $value;
494 }
495 }
496
497 // Exclude rest_route if pretty permalinks are not enabled.
498 if ( ! get_option( 'permalink_structure' ) ) {
499 unset( $params['rest_route'] );
500 }
501
502 return $params;
503 }
504
505 /**
506 * Retrieves parameters from the route itself.
507 *
508 * These are parsed from the URL using the regex.
509 *
510 * @since 4.4.0
511 *
512 * @return array Parameter map of key to value.
513 */
514 public function get_url_params() {
515 return $this->params['URL'];
516 }
517
518 /**
519 * Sets parameters from the route.
520 *
521 * Typically, this is set after parsing the URL.
522 *
523 * @since 4.4.0
524 *
525 * @param array $params Parameter map of key to value.
526 */
527 public function set_url_params( $params ) {
528 $this->params['URL'] = $params;
529 }
530
531 /**
532 * Retrieves parameters from the query string.
533 *
534 * These are the parameters you'd typically find in `$_GET`.
535 *
536 * @since 4.4.0
537 *
538 * @return array Parameter map of key to value.
539 */
540 public function get_query_params() {
541 return $this->params['GET'];
542 }
543
544 /**
545 * Sets parameters from the query string.
546 *
547 * Typically, this is set from `$_GET`.
548 *
549 * @since 4.4.0
550 *
551 * @param array $params Parameter map of key to value.
552 */
553 public function set_query_params( $params ) {
554 $this->params['GET'] = $params;
555 }
556
557 /**
558 * Retrieves parameters from the body.
559 *
560 * These are the parameters you'd typically find in `$_POST`.
561 *
562 * @since 4.4.0
563 *
564 * @return array Parameter map of key to value.
565 */
566 public function get_body_params() {
567 return $this->params['POST'];
568 }
569
570 /**
571 * Sets parameters from the body.
572 *
573 * Typically, this is set from `$_POST`.
574 *
575 * @since 4.4.0
576 *
577 * @param array $params Parameter map of key to value.
578 */
579 public function set_body_params( $params ) {
580 $this->params['POST'] = $params;
581 }
582
583 /**
584 * Retrieves multipart file parameters from the body.
585 *
586 * These are the parameters you'd typically find in `$_FILES`.
587 *
588 * @since 4.4.0
589 *
590 * @return array Parameter map of key to value.
591 */
592 public function get_file_params() {
593 return $this->params['FILES'];
594 }
595
596 /**
597 * Sets multipart file parameters from the body.
598 *
599 * Typically, this is set from `$_FILES`.
600 *
601 * @since 4.4.0
602 *
603 * @param array $params Parameter map of key to value.
604 */
605 public function set_file_params( $params ) {
606 $this->params['FILES'] = $params;
607 }
608
609 /**
610 * Retrieves the default parameters.
611 *
612 * These are the parameters set in the route registration.
613 *
614 * @since 4.4.0
615 *
616 * @return array Parameter map of key to value.
617 */
618 public function get_default_params() {
619 return $this->params['defaults'];
620 }
621
622 /**
623 * Sets default parameters.
624 *
625 * These are the parameters set in the route registration.
626 *
627 * @since 4.4.0
628 *
629 * @param array $params Parameter map of key to value.
630 */
631 public function set_default_params( $params ) {
632 $this->params['defaults'] = $params;
633 }
634
635 /**
636 * Retrieves the request body content.
637 *
638 * @since 4.4.0
639 *
640 * @return string Binary data from the request body.
641 */
642 public function get_body() {
643 return $this->body;
644 }
645
646 /**
647 * Sets body content.
648 *
649 * @since 4.4.0
650 *
651 * @param string $data Binary data from the request body.
652 */
653 public function set_body( $data ) {
654 $this->body = $data;
655
656 // Enable lazy parsing.
657 $this->parsed_json = false;
658 $this->parsed_body = false;
659 $this->params['JSON'] = null;
660 }
661
662 /**
663 * Retrieves the parameters from a JSON-formatted body.
664 *
665 * @since 4.4.0
666 *
667 * @return array Parameter map of key to value.
668 */
669 public function get_json_params() {
670 // Ensure the parameters have been parsed out.
671 $this->parse_json_params();
672
673 return $this->params['JSON'];
674 }
675
676 /**
677 * Parses the JSON parameters.
678 *
679 * Avoids parsing the JSON data until we need to access it.
680 *
681 * @since 4.4.0
682 * @since 4.7.0 Returns error instance if value cannot be decoded.
683 * @return true|WP_Error True if the JSON data was passed or no JSON data was provided, WP_Error if invalid JSON was passed.
684 */
685 protected function parse_json_params() {
686 if ( $this->parsed_json ) {
687 return true;
688 }
689
690 $this->parsed_json = true;
691
692 // Check that we actually got JSON.
693 if ( ! $this->is_json_content_type() ) {
694 return true;
695 }
696
697 $body = $this->get_body();
698 if ( empty( $body ) ) {
699 return true;
700 }
701
702 $params = json_decode( $body, true );
703
704 /*
705 * Check for a parsing error.
706 */
707 if ( null === $params && JSON_ERROR_NONE !== json_last_error() ) {
708 // Ensure subsequent calls receive error instance.
709 $this->parsed_json = false;
710
711 $error_data = array(
712 'status' => WP_Http::BAD_REQUEST,
713 'json_error_code' => json_last_error(),
714 'json_error_message' => json_last_error_msg(),
715 );
716
717 return new WP_Error( 'rest_invalid_json', __( 'Invalid JSON body passed.' ), $error_data );
718 }
719
720 $this->params['JSON'] = $params;
721
722 return true;
723 }
724
725 /**
726 * Parses the request body parameters.
727 *
728 * Parses out URL-encoded bodies for request methods that aren't supported
729 * natively by PHP.
730 *
731 * @since 4.4.0
732 */
733 protected function parse_body_params() {
734 if ( $this->parsed_body ) {
735 return;
736 }
737
738 $this->parsed_body = true;
739
740 /*
741 * Check that we got URL-encoded. Treat a missing Content-Type as
742 * URL-encoded for maximum compatibility.
743 */
744 $content_type = $this->get_content_type();
745
746 if ( ! empty( $content_type ) && 'application/x-www-form-urlencoded' !== $content_type['value'] ) {
747 return;
748 }
749
750 parse_str( $this->get_body(), $params );
751
752 /*
753 * Add to the POST parameters stored internally. If a user has already
754 * set these manually (via `set_body_params`), don't override them.
755 */
756 $this->params['POST'] = array_merge( $params, $this->params['POST'] );
757 }
758
759 /**
760 * Retrieves the route that matched the request.
761 *
762 * @since 4.4.0
763 *
764 * @return string Route matching regex.
765 */
766 public function get_route() {
767 return $this->route;
768 }
769
770 /**
771 * Sets the route that matched the request.
772 *
773 * @since 4.4.0
774 *
775 * @param string $route Route matching regex.
776 */
777 public function set_route( $route ) {
778 $this->route = $route;
779 }
780
781 /**
782 * Retrieves the attributes for the request.
783 *
784 * These are the options for the route that was matched.
785 *
786 * @since 4.4.0
787 *
788 * @return array Attributes for the request.
789 */
790 public function get_attributes() {
791 return $this->attributes;
792 }
793
794 /**
795 * Sets the attributes for the request.
796 *
797 * @since 4.4.0
798 *
799 * @param array $attributes Attributes for the request.
800 */
801 public function set_attributes( $attributes ) {
802 $this->attributes = $attributes;
803 }
804
805 /**
806 * Sanitizes (where possible) the params on the request.
807 *
808 * This is primarily based off the sanitize_callback param on each registered
809 * argument.
810 *
811 * @since 4.4.0
812 *
813 * @return true|WP_Error True if parameters were sanitized, WP_Error if an error occurred during sanitization.
814 */
815 public function sanitize_params() {
816 $attributes = $this->get_attributes();
817
818 // No arguments set, skip sanitizing.
819 if ( empty( $attributes['args'] ) ) {
820 return true;
821 }
822
823 $order = $this->get_parameter_order();
824
825 $invalid_params = array();
826 $invalid_details = array();
827
828 foreach ( $order as $type ) {
829 if ( empty( $this->params[ $type ] ) ) {
830 continue;
831 }
832
833 foreach ( $this->params[ $type ] as $key => $value ) {
834 if ( ! isset( $attributes['args'][ $key ] ) ) {
835 continue;
836 }
837
838 $param_args = $attributes['args'][ $key ];
839
840 // If the arg has a type but no sanitize_callback attribute, default to rest_parse_request_arg.
841 if ( ! array_key_exists( 'sanitize_callback', $param_args ) && ! empty( $param_args['type'] ) ) {
842 $param_args['sanitize_callback'] = 'rest_parse_request_arg';
843 }
844 // If there's still no sanitize_callback, nothing to do here.
845 if ( empty( $param_args['sanitize_callback'] ) ) {
846 continue;
847 }
848
849 /** @var mixed|WP_Error $sanitized_value */
850 $sanitized_value = call_user_func( $param_args['sanitize_callback'], $value, $this, $key );
851
852 if ( is_wp_error( $sanitized_value ) ) {
853 $invalid_params[ $key ] = implode( ' ', $sanitized_value->get_error_messages() );
854 $invalid_details[ $key ] = rest_convert_error_to_response( $sanitized_value )->get_data();
855 } else {
856 $this->params[ $type ][ $key ] = $sanitized_value;
857 }
858 }
859 }
860
861 if ( $invalid_params ) {
862 return new WP_Error(
863 'rest_invalid_param',
864 /* translators: %s: List of invalid parameters. */
865 sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ),
866 array(
867 'status' => 400,
868 'params' => $invalid_params,
869 'details' => $invalid_details,
870 )
871 );
872 }
873
874 return true;
875 }
876
877 /**
878 * Checks whether this request is valid according to its attributes.
879 *
880 * @since 4.4.0
881 *
882 * @return true|WP_Error True if there are no parameters to validate or if all pass validation,
883 * WP_Error if required parameters are missing.
884 */
885 public function has_valid_params() {
886 // If JSON data was passed, check for errors.
887 $json_error = $this->parse_json_params();
888 if ( is_wp_error( $json_error ) ) {
889 return $json_error;
890 }
891
892 $attributes = $this->get_attributes();
893 $required = array();
894
895 $args = empty( $attributes['args'] ) ? array() : $attributes['args'];
896
897 foreach ( $args as $key => $arg ) {
898 $param = $this->get_param( $key );
899 if ( isset( $arg['required'] ) && true === $arg['required'] && null === $param ) {
900 $required[] = $key;
901 }
902 }
903
904 if ( ! empty( $required ) ) {
905 return new WP_Error(
906 'rest_missing_callback_param',
907 /* translators: %s: List of required parameters. */
908 sprintf( __( 'Missing parameter(s): %s' ), implode( ', ', $required ) ),
909 array(
910 'status' => 400,
911 'params' => $required,
912 )
913 );
914 }
915
916 /*
917 * Check the validation callbacks for each registered arg.
918 *
919 * This is done after required checking as required checking is cheaper.
920 */
921 $invalid_params = array();
922 $invalid_details = array();
923
924 foreach ( $args as $key => $arg ) {
925
926 $param = $this->get_param( $key );
927
928 if ( null !== $param && ! empty( $arg['validate_callback'] ) ) {
929 /** @var bool|\WP_Error $valid_check */
930 $valid_check = call_user_func( $arg['validate_callback'], $param, $this, $key );
931
932 if ( false === $valid_check ) {
933 $invalid_params[ $key ] = __( 'Invalid parameter.' );
934 }
935
936 if ( is_wp_error( $valid_check ) ) {
937 $invalid_params[ $key ] = implode( ' ', $valid_check->get_error_messages() );
938 $invalid_details[ $key ] = rest_convert_error_to_response( $valid_check )->get_data();
939 }
940 }
941 }
942
943 if ( $invalid_params ) {
944 return new WP_Error(
945 'rest_invalid_param',
946 /* translators: %s: List of invalid parameters. */
947 sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ),
948 array(
949 'status' => 400,
950 'params' => $invalid_params,
951 'details' => $invalid_details,
952 )
953 );
954 }
955
956 if ( isset( $attributes['validate_callback'] ) ) {
957 $valid_check = call_user_func( $attributes['validate_callback'], $this );
958
959 if ( is_wp_error( $valid_check ) ) {
960 return $valid_check;
961 }
962
963 if ( false === $valid_check ) {
964 // A WP_Error instance is preferred, but false is supported for parity with the per-arg validate_callback.
965 return new WP_Error( 'rest_invalid_params', __( 'Invalid parameters.' ), array( 'status' => 400 ) );
966 }
967 }
968
969 return true;
970 }
971
972 /**
973 * Checks if a parameter is set.
974 *
975 * @since 4.4.0
976 *
977 * @param string $offset Parameter name.
978 * @return bool Whether the parameter is set.
979 */
980 #[ReturnTypeWillChange]
981 public function offsetExists( $offset ) {
982 $order = $this->get_parameter_order();
983
984 foreach ( $order as $type ) {
985 if ( isset( $this->params[ $type ][ $offset ] ) ) {
986 return true;
987 }
988 }
989
990 return false;
991 }
992
993 /**
994 * Retrieves a parameter from the request.
995 *
996 * @since 4.4.0
997 *
998 * @param string $offset Parameter name.
999 * @return mixed|null Value if set, null otherwise.
1000 */
1001 #[ReturnTypeWillChange]
1002 public function offsetGet( $offset ) {
1003 return $this->get_param( $offset );
1004 }
1005
1006 /**
1007 * Sets a parameter on the request.
1008 *
1009 * @since 4.4.0
1010 *
1011 * @param string $offset Parameter name.
1012 * @param mixed $value Parameter value.
1013 */
1014 #[ReturnTypeWillChange]
1015 public function offsetSet( $offset, $value ) {
1016 $this->set_param( $offset, $value );
1017 }
1018
1019 /**
1020 * Removes a parameter from the request.
1021 *
1022 * @since 4.4.0
1023 *
1024 * @param string $offset Parameter name.
1025 */
1026 #[ReturnTypeWillChange]
1027 public function offsetUnset( $offset ) {
1028 $order = $this->get_parameter_order();
1029
1030 // Remove the offset from every group.
1031 foreach ( $order as $type ) {
1032 unset( $this->params[ $type ][ $offset ] );
1033 }
1034 }
1035
1036 /**
1037 * Retrieves a WP_REST_Request object from a full URL.
1038 *
1039 * @since 4.5.0
1040 *
1041 * @param string $url URL with protocol, domain, path and query args.
1042 * @return WP_REST_Request|false WP_REST_Request object on success, false on failure.
1043 */
1044 public static function from_url( $url ) {
1045 $bits = parse_url( $url );
1046 $query_params = array();
1047
1048 if ( ! empty( $bits['query'] ) ) {
1049 wp_parse_str( $bits['query'], $query_params );
1050 }
1051
1052 $api_root = rest_url();
1053 if ( get_option( 'permalink_structure' ) && str_starts_with( $url, $api_root ) ) {
1054 // Pretty permalinks on, and URL is under the API root.
1055 $api_url_part = substr( $url, strlen( untrailingslashit( $api_root ) ) );
1056 $route = parse_url( $api_url_part, PHP_URL_PATH );
1057 } elseif ( ! empty( $query_params['rest_route'] ) ) {
1058 // ?rest_route=... set directly.
1059 $route = $query_params['rest_route'];
1060 unset( $query_params['rest_route'] );
1061 }
1062
1063 $request = false;
1064 if ( ! empty( $route ) ) {
1065 $request = new WP_REST_Request( 'GET', $route );
1066 $request->set_query_params( $query_params );
1067 }
1068
1069 /**
1070 * Filters the REST API request generated from a URL.
1071 *
1072 * @since 4.5.0
1073 *
1074 * @param WP_REST_Request|false $request Generated request object, or false if URL
1075 * could not be parsed.
1076 * @param string $url URL the request was generated from.
1077 */
1078 return apply_filters( 'rest_request_from_url', $request, $url );
1079 }
1080}
1081
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1