wp/wp-includes/rest-api/class-wp-rest-request.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
    12  *
    12  *
    13  * Contains data from the request, to be passed to the callback.
    13  * Contains data from the request, to be passed to the callback.
    14  *
    14  *
    15  * Note: This implements ArrayAccess, and acts as an array of parameters when
    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),
    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 behaviour in some cases.
    17  * so be aware it may have non-array behavior in some cases.
    18  *
    18  *
    19  * Note: When using features provided by ArrayAccess, be aware that WordPress deliberately
    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.
    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
    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
    22  * 2 (`POST`) not 1 (`GET`). For more precision between request methods, use
    24  *
    24  *
    25  * @since 4.4.0
    25  * @since 4.4.0
    26  *
    26  *
    27  * @link https://www.php.net/manual/en/class.arrayaccess.php
    27  * @link https://www.php.net/manual/en/class.arrayaccess.php
    28  */
    28  */
       
    29 #[AllowDynamicProperties]
    29 class WP_REST_Request implements ArrayAccess {
    30 class WP_REST_Request implements ArrayAccess {
    30 
    31 
    31 	/**
    32 	/**
    32 	 * HTTP method.
    33 	 * HTTP method.
    33 	 *
    34 	 *
   288 			$this->set_header( $key, $value );
   289 			$this->set_header( $key, $value );
   289 		}
   290 		}
   290 	}
   291 	}
   291 
   292 
   292 	/**
   293 	/**
   293 	 * Retrieves the content-type of the request.
   294 	 * Retrieves the Content-Type of the request.
   294 	 *
   295 	 *
   295 	 * @since 4.4.0
   296 	 * @since 4.4.0
   296 	 *
   297 	 *
   297 	 * @return array|null Map containing 'value' and 'parameters' keys
   298 	 * @return array|null Map containing 'value' and 'parameters' keys
   298 	 *                    or null when no valid content-type header was
   299 	 *                    or null when no valid Content-Type header was
   299 	 *                    available.
   300 	 *                    available.
   300 	 */
   301 	 */
   301 	public function get_content_type() {
   302 	public function get_content_type() {
   302 		$value = $this->get_header( 'content-type' );
   303 		$value = $this->get_header( 'Content-Type' );
   303 		if ( empty( $value ) ) {
   304 		if ( empty( $value ) ) {
   304 			return null;
   305 			return null;
   305 		}
   306 		}
   306 
   307 
   307 		$parameters = '';
   308 		$parameters = '';
   308 		if ( strpos( $value, ';' ) ) {
   309 		if ( strpos( $value, ';' ) ) {
   309 			list( $value, $parameters ) = explode( ';', $value, 2 );
   310 			list( $value, $parameters ) = explode( ';', $value, 2 );
   310 		}
   311 		}
   311 
   312 
   312 		$value = strtolower( $value );
   313 		$value = strtolower( $value );
   313 		if ( false === strpos( $value, '/' ) ) {
   314 		if ( ! str_contains( $value, '/' ) ) {
   314 			return null;
   315 			return null;
   315 		}
   316 		}
   316 
   317 
   317 		// Parse type and subtype out.
   318 		// Parse type and subtype out.
   318 		list( $type, $subtype ) = explode( '/', $value, 2 );
   319 		list( $type, $subtype ) = explode( '/', $value, 2 );
   322 
   323 
   323 		return $data;
   324 		return $data;
   324 	}
   325 	}
   325 
   326 
   326 	/**
   327 	/**
   327 	 * Checks if the request has specified a JSON content-type.
   328 	 * Checks if the request has specified a JSON Content-Type.
   328 	 *
   329 	 *
   329 	 * @since 5.6.0
   330 	 * @since 5.6.0
   330 	 *
   331 	 *
   331 	 * @return bool True if the content-type header is JSON.
   332 	 * @return bool True if the Content-Type header is JSON.
   332 	 */
   333 	 */
   333 	public function is_json_content_type() {
   334 	public function is_json_content_type() {
   334 		$content_type = $this->get_content_type();
   335 		$content_type = $this->get_content_type();
   335 
   336 
   336 		return isset( $content_type['value'] ) && wp_is_json_media_type( $content_type['value'] );
   337 		return isset( $content_type['value'] ) && wp_is_json_media_type( $content_type['value'] );
   470 		$order = $this->get_parameter_order();
   471 		$order = $this->get_parameter_order();
   471 		$order = array_reverse( $order, true );
   472 		$order = array_reverse( $order, true );
   472 
   473 
   473 		$params = array();
   474 		$params = array();
   474 		foreach ( $order as $type ) {
   475 		foreach ( $order as $type ) {
   475 			// array_merge() / the "+" operator will mess up
   476 			/*
   476 			// numeric keys, so instead do a manual foreach.
   477 			 * array_merge() / the "+" operator will mess up
       
   478 			 * numeric keys, so instead do a manual foreach.
       
   479 			 */
   477 			foreach ( (array) $this->params[ $type ] as $key => $value ) {
   480 			foreach ( (array) $this->params[ $type ] as $key => $value ) {
   478 				$params[ $key ] = $value;
   481 				$params[ $key ] = $value;
   479 			}
   482 			}
   480 		}
   483 		}
   481 
   484 
   716 		}
   719 		}
   717 
   720 
   718 		$this->parsed_body = true;
   721 		$this->parsed_body = true;
   719 
   722 
   720 		/*
   723 		/*
   721 		 * Check that we got URL-encoded. Treat a missing content-type as
   724 		 * Check that we got URL-encoded. Treat a missing Content-Type as
   722 		 * URL-encoded for maximum compatibility.
   725 		 * URL-encoded for maximum compatibility.
   723 		 */
   726 		 */
   724 		$content_type = $this->get_content_type();
   727 		$content_type = $this->get_content_type();
   725 
   728 
   726 		if ( ! empty( $content_type ) && 'application/x-www-form-urlencoded' !== $content_type['value'] ) {
   729 		if ( ! empty( $content_type ) && 'application/x-www-form-urlencoded' !== $content_type['value'] ) {
  1028 		if ( ! empty( $bits['query'] ) ) {
  1031 		if ( ! empty( $bits['query'] ) ) {
  1029 			wp_parse_str( $bits['query'], $query_params );
  1032 			wp_parse_str( $bits['query'], $query_params );
  1030 		}
  1033 		}
  1031 
  1034 
  1032 		$api_root = rest_url();
  1035 		$api_root = rest_url();
  1033 		if ( get_option( 'permalink_structure' ) && 0 === strpos( $url, $api_root ) ) {
  1036 		if ( get_option( 'permalink_structure' ) && str_starts_with( $url, $api_root ) ) {
  1034 			// Pretty permalinks on, and URL is under the API root.
  1037 			// Pretty permalinks on, and URL is under the API root.
  1035 			$api_url_part = substr( $url, strlen( untrailingslashit( $api_root ) ) );
  1038 			$api_url_part = substr( $url, strlen( untrailingslashit( $api_root ) ) );
  1036 			$route        = parse_url( $api_url_part, PHP_URL_PATH );
  1039 			$route        = parse_url( $api_url_part, PHP_URL_PATH );
  1037 		} elseif ( ! empty( $query_params['rest_route'] ) ) {
  1040 		} elseif ( ! empty( $query_params['rest_route'] ) ) {
  1038 			// ?rest_route=... set directly.
  1041 			// ?rest_route=... set directly.