REST API: Fix updating "multiple" meta keys with non-string values.

Previously, the REST API would end up deleting each row of metadata and recreating it unnecessarily. This was caused by a type mismatch where the metadata API would always return a string value, and the REST API operated on a typed value.

The REST API now applies the same sanitization and type casting for "multiple" meta keys and "single" meta keys.

Fixes #49339.
Props renathoc.


git-svn-id: https://develop.svn.wordpress.org/trunk@47943 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Timothy Jacobs
2020-06-10 02:20:18 +00:00
parent 45e9cb7066
commit ddf897db05
2 changed files with 163 additions and 15 deletions
@@ -2655,6 +2655,133 @@ class WP_Test_REST_Post_Meta_Fields extends WP_Test_REST_TestCase {
$this->assertEquals( '0', get_post_meta( self::$post_id, 'boolean', true ) );
}
/**
* @ticket 49339
*/
public function test_update_multi_meta_value_handles_integer_types() {
$this->grant_write_permission();
register_post_meta(
'post',
'multi_integer',
array(
'type' => 'integer',
'show_in_rest' => true,
)
);
$mid1 = add_post_meta( self::$post_id, 'multi_integer', 1 );
$mid2 = add_post_meta( self::$post_id, 'multi_integer', 2 );
$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
$request->set_body_params(
array(
'meta' => array(
'multi_integer' => array( 2, 3 ),
),
)
);
$response = rest_get_server()->dispatch( $request );
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( array( 2, 3 ), $response->get_data()['meta']['multi_integer'] );
$this->assertFalse( get_metadata_by_mid( 'post', $mid1 ) );
$this->assertNotFalse( get_metadata_by_mid( 'post', $mid2 ) );
}
/**
* @ticket 49339
*/
public function test_update_multi_meta_value_handles_boolean_types() {
$this->grant_write_permission();
register_post_meta(
'post',
'multi_boolean',
array(
'type' => 'boolean',
'sanitize_callback' => 'absint',
'show_in_rest' => true,
)
);
$mid1 = add_post_meta( self::$post_id, 'multi_boolean', 1 );
$mid2 = add_post_meta( self::$post_id, 'multi_boolean', 0 );
$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
$request->set_body_params(
array(
'meta' => array(
'multi_boolean' => array( 0 ),
),
)
);
$response = rest_get_server()->dispatch( $request );
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( array( 0 ), $response->get_data()['meta']['multi_boolean'] );
$this->assertFalse( get_metadata_by_mid( 'post', $mid1 ) );
$this->assertNotFalse( get_metadata_by_mid( 'post', $mid2 ) );
}
/**
* @ticket 49339
*/
public function test_update_multi_meta_value_handles_object_types() {
$this->grant_write_permission();
register_post_meta(
'post',
'multi_object',
array(
'type' => 'object',
'show_in_rest' => array(
'schema' => array(
'type' => 'object',
'properties' => array(
'a' => array(
'type' => 'string',
),
),
),
),
)
);
$mid1 = add_post_meta( self::$post_id, 'multi_object', array( 'a' => 'ant' ) );
$mid2 = add_post_meta( self::$post_id, 'multi_object', array( 'a' => 'anaconda' ) );
$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
$request->set_body_params(
array(
'meta' => array(
'multi_object' => array(
array( 'a' => 'anaconda' ),
array( 'a' => 'alpaca' ),
),
),
)
);
$response = rest_get_server()->dispatch( $request );
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals(
array(
array( 'a' => 'anaconda' ),
array( 'a' => 'alpaca' ),
),
$response->get_data()['meta']['multi_object']
);
$this->assertFalse( get_metadata_by_mid( 'post', $mid1 ) );
$this->assertNotFalse( get_metadata_by_mid( 'post', $mid2 ) );
}
/**
* Internal function used to disable an insert query which
* will trigger a wpdb error for testing purposes.