Changeset 41758
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
r41591 r41758 546 546 } 547 547 548 foreach ( array( 'type', 'format', 'enum', 'items' ) as $schema_prop ) {548 foreach ( array( 'type', 'format', 'enum', 'items', 'properties' ) as $schema_prop ) { 549 549 if ( isset( $params[ $schema_prop ] ) ) { 550 550 $endpoint_args[ $field_id ][ $schema_prop ] = $params[ $schema_prop ]; -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php
r41731 r41758 120 120 */ 121 121 protected function prepare_value( $value, $schema ) { 122 // If the value is not a scalar, it's not possible to cast it to anything. 123 if ( ! is_scalar( $value ) ) { 122 // If the value is not valid by the schema, set the value to null. Null 123 // values are specifcally non-destructive so this will not cause overwriting 124 // the current invalid value to null. 125 if ( is_wp_error( rest_validate_value_from_schema( $value, $schema ) ) ) { 124 126 return null; 125 127 } 126 127 switch ( $schema['type'] ) { 128 case 'string': 129 return (string) $value; 130 case 'integer': 131 return (int) $value; 132 case 'number': 133 return (float) $value; 134 case 'boolean': 135 return (bool) $value; 136 default: 137 return null; 138 } 128 return rest_sanitize_value_from_schema( $value, $schema ); 139 129 } 140 130 … … 149 139 public function update_item( $request ) { 150 140 $options = $this->get_registered_options(); 141 151 142 $params = $request->get_params(); 152 143 … … 188 179 * To protect clients from accidentally including the null 189 180 * values from a response object in a request, we do not allow 190 * options with non-scalar valuesto be updated to null.181 * options with values that don't pass validation to be updated to null. 191 182 * Without this added protection a client could mistakenly 192 * delete all options that have non-scalarvalues from the183 * delete all options that have invalid values from the 193 184 * database. 194 185 */ 195 if ( ! is_scalar( get_option( $args['option_name'], false) ) ) {186 if ( is_wp_error( rest_validate_value_from_schema( get_option( $args['option_name'], false ), $args['schema'] ) ) ) { 196 187 return new WP_Error( 197 188 'rest_invalid_stored_value', sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), array( 'status' => 500 ) … … 254 245 * to be updated with arbitrary values that we can't do decent sanitizing for. 255 246 */ 256 if ( ! in_array( $rest_args['schema']['type'], array( 'number', 'integer', 'string', 'boolean' ), true ) ) {247 if ( ! in_array( $rest_args['schema']['type'], array( 'number', 'integer', 'string', 'boolean', 'array', 'object' ), true ) ) { 257 248 continue; 258 249 } -
trunk/tests/phpunit/tests/rest-api/rest-settings-controller.php
r41228 r41758 128 128 } 129 129 130 public function test_get_item_with_custom_array_setting() { 131 wp_set_current_user( self::$administrator ); 132 133 register_setting( 'somegroup', 'mycustomsetting', array( 134 'show_in_rest' => array( 135 'schema' => array( 136 'type' => 'array', 137 'items' => array( 138 'type' => 'integer', 139 ), 140 ), 141 ), 142 'type' => 'array', 143 ) ); 144 145 // Array is cast to correct types. 146 update_option( 'mycustomsetting', array( '1', '2' ) ); 147 $request = new WP_REST_Request( 'GET', '/wp/v2/settings' ); 148 $response = $this->server->dispatch( $request ); 149 $data = $response->get_data(); 150 $this->assertEquals( array( 1, 2 ), $data['mycustomsetting'] ); 151 152 // Empty array works as expected. 153 update_option( 'mycustomsetting', array() ); 154 $request = new WP_REST_Request( 'GET', '/wp/v2/settings' ); 155 $response = $this->server->dispatch( $request ); 156 $data = $response->get_data(); 157 $this->assertEquals( array(), $data['mycustomsetting'] ); 158 159 // Invalid value 160 update_option( 'mycustomsetting', array( array( 1 ) ) ); 161 $request = new WP_REST_Request( 'GET', '/wp/v2/settings' ); 162 $response = $this->server->dispatch( $request ); 163 $data = $response->get_data(); 164 $this->assertEquals( null, $data['mycustomsetting'] ); 165 166 // No option value 167 delete_option( 'mycustomsetting' ); 168 $request = new WP_REST_Request( 'GET', '/wp/v2/settings' ); 169 $response = $this->server->dispatch( $request ); 170 $data = $response->get_data(); 171 $this->assertEquals( null, $data['mycustomsetting'] ); 172 173 unregister_setting( 'somegroup', 'mycustomsetting' ); 174 } 175 176 public function test_get_item_with_custom_object_setting() { 177 wp_set_current_user( self::$administrator ); 178 179 register_setting( 'somegroup', 'mycustomsetting', array( 180 'show_in_rest' => array( 181 'schema' => array( 182 'type' => 'object', 183 'properties' => array( 184 'a' => array( 185 'type' => 'integer', 186 ), 187 ), 188 ), 189 ), 190 'type' => 'object', 191 ) ); 192 193 // Object is cast to correct types. 194 update_option( 'mycustomsetting', array( 'a' => '1' ) ); 195 $request = new WP_REST_Request( 'GET', '/wp/v2/settings' ); 196 $response = $this->server->dispatch( $request ); 197 $data = $response->get_data(); 198 $this->assertEquals( array( 'a' => 1 ), $data['mycustomsetting'] ); 199 200 // Empty array works as expected. 201 update_option( 'mycustomsetting', array() ); 202 $request = new WP_REST_Request( 'GET', '/wp/v2/settings' ); 203 $response = $this->server->dispatch( $request ); 204 $data = $response->get_data(); 205 $this->assertEquals( array(), $data['mycustomsetting'] ); 206 207 // Invalid value 208 update_option( 'mycustomsetting', array( 'a' => 1, 'b' => 2 ) ); 209 $request = new WP_REST_Request( 'GET', '/wp/v2/settings' ); 210 $response = $this->server->dispatch( $request ); 211 $data = $response->get_data(); 212 $this->assertEquals( array( 'a' => 1 ), $data['mycustomsetting'] ); 213 214 unregister_setting( 'somegroup', 'mycustomsetting' ); 215 } 216 130 217 public function get_setting_custom_callback( $result, $name, $args ) { 131 218 switch ( $name ) { … … 216 303 $data = $response->get_data(); 217 304 $this->assertEquals( null, $data['mycustomsettinginrest'] ); 305 unregister_setting( 'somegroup', 'mycustomsetting' ); 218 306 } 219 307 … … 243 331 } 244 332 333 public function test_update_item_with_array() { 334 register_setting( 'somegroup', 'mycustomsetting', array( 335 'show_in_rest' => array( 336 'schema' => array( 337 'type' => 'array', 338 'items' => array( 339 'type' => 'integer', 340 ), 341 ), 342 ), 343 'type' => 'array', 344 ) ); 345 346 // We have to re-register the route, as the args changes based off registered settings. 347 $this->server->override_by_default = true; 348 $this->endpoint->register_routes(); 349 wp_set_current_user( self::$administrator ); 350 351 $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' ); 352 $request->set_param( 'mycustomsetting', array( '1', '2' ) ); 353 $response = $this->server->dispatch( $request ); 354 $data = $response->get_data(); 355 $this->assertEquals( array( 1, 2 ), $data['mycustomsetting'] ); 356 $this->assertEquals( array( 1, 2 ), get_option( 'mycustomsetting' ) ); 357 358 // Setting an empty array. 359 $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' ); 360 $request->set_param( 'mycustomsetting', array() ); 361 $response = $this->server->dispatch( $request ); 362 $data = $response->get_data(); 363 $this->assertEquals( array(), $data['mycustomsetting'] ); 364 $this->assertEquals( array(), get_option( 'mycustomsetting' ) ); 365 366 // Setting an invalid array. 367 $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' ); 368 $request->set_param( 'mycustomsetting', array( 'invalid' ) ); 369 $response = $this->server->dispatch( $request ); 370 371 $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); 372 unregister_setting( 'somegroup', 'mycustomsetting' ); 373 } 374 375 public function test_update_item_with_object() { 376 register_setting( 'somegroup', 'mycustomsetting', array( 377 'show_in_rest' => array( 378 'schema' => array( 379 'type' => 'object', 380 'properties' => array( 381 'a' => array( 382 'type' => 'integer', 383 ), 384 ), 385 ), 386 ), 387 'type' => 'object', 388 ) ); 389 390 // We have to re-register the route, as the args changes based off registered settings. 391 $this->server->override_by_default = true; 392 $this->endpoint->register_routes(); 393 wp_set_current_user( self::$administrator ); 394 395 $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' ); 396 $request->set_param( 'mycustomsetting', array( 'a' => 1 ) ); 397 $response = $this->server->dispatch( $request ); 398 $data = $response->get_data(); 399 $this->assertEquals( array( 'a' => 1 ), $data['mycustomsetting'] ); 400 $this->assertEquals( array( 'a' => 1 ), get_option( 'mycustomsetting' ) ); 401 402 // Setting an empty object. 403 $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' ); 404 $request->set_param( 'mycustomsetting', array() ); 405 $response = $this->server->dispatch( $request ); 406 $data = $response->get_data(); 407 $this->assertEquals( array(), $data['mycustomsetting'] ); 408 $this->assertEquals( array(), get_option( 'mycustomsetting' ) ); 409 410 // Setting an invalid object. 411 $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' ); 412 $request->set_param( 'mycustomsetting', array( 'a' => 'invalid' ) ); 413 $response = $this->server->dispatch( $request ); 414 $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); 415 unregister_setting( 'somegroup', 'mycustomsetting' ); 416 } 417 245 418 public function test_update_item_with_filter() { 246 419 wp_set_current_user( self::$administrator );
Note: See TracChangeset
for help on using the changeset viewer.