wp/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
   121 	 * @param mixed $value  Value to prepare.
   121 	 * @param mixed $value  Value to prepare.
   122 	 * @param array $schema Schema to match.
   122 	 * @param array $schema Schema to match.
   123 	 * @return mixed The prepared value.
   123 	 * @return mixed The prepared value.
   124 	 */
   124 	 */
   125 	protected function prepare_value( $value, $schema ) {
   125 	protected function prepare_value( $value, $schema ) {
   126 		// If the value is not valid by the schema, set the value to null. Null
   126 		/*
   127 		// values are specifcally non-destructive so this will not cause overwriting
   127 		 * If the value is not valid by the schema, set the value to null.
   128 		// the current invalid value to null.
   128 		 * Null values are specifically non-destructive, so this will not cause
       
   129 		 * overwriting the current invalid value to null.
       
   130 		 */
   129 		if ( is_wp_error( rest_validate_value_from_schema( $value, $schema ) ) ) {
   131 		if ( is_wp_error( rest_validate_value_from_schema( $value, $schema ) ) ) {
   130 			return null;
   132 			return null;
   131 		}
   133 		}
       
   134 
   132 		return rest_sanitize_value_from_schema( $value, $schema );
   135 		return rest_sanitize_value_from_schema( $value, $schema );
   133 	}
   136 	}
   134 
   137 
   135 	/**
   138 	/**
   136 	 * Updates settings for the settings object.
   139 	 * Updates settings for the settings object.
   188 				 * database.
   191 				 * database.
   189 				 */
   192 				 */
   190 				if ( is_wp_error( rest_validate_value_from_schema( get_option( $args['option_name'], false ), $args['schema'] ) ) ) {
   193 				if ( is_wp_error( rest_validate_value_from_schema( get_option( $args['option_name'], false ), $args['schema'] ) ) ) {
   191 					return new WP_Error(
   194 					return new WP_Error(
   192 						'rest_invalid_stored_value',
   195 						'rest_invalid_stored_value',
       
   196 						/* translators: %s: Property name. */
   193 						sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ),
   197 						sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ),
   194 						array( 'status' => 500 )
   198 						array( 'status' => 500 )
   195 					);
   199 					);
   196 				}
   200 				}
   197 
   201 
   245 			if ( empty( $rest_args['schema']['type'] ) ) {
   249 			if ( empty( $rest_args['schema']['type'] ) ) {
   246 				continue;
   250 				continue;
   247 			}
   251 			}
   248 
   252 
   249 			/*
   253 			/*
   250 			 * Whitelist the supported types for settings, as we don't want invalid types
   254 			 * Allow the supported types for settings, as we don't want invalid types
   251 			 * to be updated with arbitrary values that we can't do decent sanitizing for.
   255 			 * to be updated with arbitrary values that we can't do decent sanitizing for.
   252 			 */
   256 			 */
   253 			if ( ! in_array( $rest_args['schema']['type'], array( 'number', 'integer', 'string', 'boolean', 'array', 'object' ), true ) ) {
   257 			if ( ! in_array( $rest_args['schema']['type'], array( 'number', 'integer', 'string', 'boolean', 'array', 'object' ), true ) ) {
   254 				continue;
   258 				continue;
   255 			}
   259 			}
   268 	 * @since 4.7.0
   272 	 * @since 4.7.0
   269 	 *
   273 	 *
   270 	 * @return array Item schema data.
   274 	 * @return array Item schema data.
   271 	 */
   275 	 */
   272 	public function get_item_schema() {
   276 	public function get_item_schema() {
       
   277 		if ( $this->schema ) {
       
   278 			return $this->add_additional_fields_schema( $this->schema );
       
   279 		}
       
   280 
   273 		$options = $this->get_registered_options();
   281 		$options = $this->get_registered_options();
   274 
   282 
   275 		$schema = array(
   283 		$schema = array(
   276 			'$schema'    => 'http://json-schema.org/draft-04/schema#',
   284 			'$schema'    => 'http://json-schema.org/draft-04/schema#',
   277 			'title'      => 'settings',
   285 			'title'      => 'settings',
   284 			$schema['properties'][ $option_name ]['arg_options'] = array(
   292 			$schema['properties'][ $option_name ]['arg_options'] = array(
   285 				'sanitize_callback' => array( $this, 'sanitize_callback' ),
   293 				'sanitize_callback' => array( $this, 'sanitize_callback' ),
   286 			);
   294 			);
   287 		}
   295 		}
   288 
   296 
   289 		return $this->add_additional_fields_schema( $schema );
   297 		$this->schema = $schema;
       
   298 
       
   299 		return $this->add_additional_fields_schema( $this->schema );
   290 	}
   300 	}
   291 
   301 
   292 	/**
   302 	/**
   293 	 * Custom sanitize callback used for all options to allow the use of 'null'.
   303 	 * Custom sanitize callback used for all options to allow the use of 'null'.
   294 	 *
   304 	 *
   295 	 * By default, the schema of settings will throw an error if a value is set to
   305 	 * By default, the schema of settings will throw an error if a value is set to
   296 	 * `null` as it's not a valid value for something like "type => string". We
   306 	 * `null` as it's not a valid value for something like "type => string". We
   297 	 * provide a wrapper sanitizer to whitelist the use of `null`.
   307 	 * provide a wrapper sanitizer to allow the use of `null`.
   298 	 *
   308 	 *
   299 	 * @since 4.7.0
   309 	 * @since 4.7.0
   300 	 *
   310 	 *
   301 	 * @param  mixed           $value   The value for the setting.
   311 	 * @param mixed           $value   The value for the setting.
   302 	 * @param  WP_REST_Request $request The request object.
   312 	 * @param WP_REST_Request $request The request object.
   303 	 * @param  string          $param   The parameter name.
   313 	 * @param string          $param   The parameter name.
   304 	 * @return mixed|WP_Error
   314 	 * @return mixed|WP_Error
   305 	 */
   315 	 */
   306 	public function sanitize_callback( $value, $request, $param ) {
   316 	public function sanitize_callback( $value, $request, $param ) {
   307 		if ( is_null( $value ) ) {
   317 		if ( is_null( $value ) ) {
   308 			return $value;
   318 			return $value;
   309 		}
   319 		}
       
   320 
   310 		return rest_parse_request_arg( $value, $request, $param );
   321 		return rest_parse_request_arg( $value, $request, $param );
   311 	}
   322 	}
   312 
   323 
   313 	/**
   324 	/**
   314 	 * Recursively add additionalProperties = false to all objects in a schema.
   325 	 * Recursively add additionalProperties = false to all objects in a schema.
   326 		switch ( $schema['type'] ) {
   337 		switch ( $schema['type'] ) {
   327 			case 'object':
   338 			case 'object':
   328 				foreach ( $schema['properties'] as $key => $child_schema ) {
   339 				foreach ( $schema['properties'] as $key => $child_schema ) {
   329 					$schema['properties'][ $key ] = $this->set_additional_properties_to_false( $child_schema );
   340 					$schema['properties'][ $key ] = $this->set_additional_properties_to_false( $child_schema );
   330 				}
   341 				}
       
   342 
   331 				$schema['additionalProperties'] = false;
   343 				$schema['additionalProperties'] = false;
   332 				break;
   344 				break;
   333 			case 'array':
   345 			case 'array':
   334 				$schema['items'] = $this->set_additional_properties_to_false( $schema['items'] );
   346 				$schema['items'] = $this->set_additional_properties_to_false( $schema['items'] );
   335 				break;
   347 				break;