REST API: Prevent database error when deleting meta data.

Add a check to `WP_REST_Meta_Fields::delete_meta_value()` ensuring meta data is set before attempting to delete it from the database. If the data does not exist, the delete is considered successful as the data matches the desired state.

Props BrechtVds, goaroundagain, TimothyBlynJacobs.
Fixes #52787.


git-svn-id: https://develop.svn.wordpress.org/trunk@50567 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Peter Wilson
2021-03-23 23:34:59 +00:00
parent 6388364fec
commit e2fff3fddc
2 changed files with 40 additions and 0 deletions

View File

@@ -232,6 +232,10 @@ abstract class WP_REST_Meta_Fields {
);
}
if ( null === get_metadata_raw( $meta_type, $object_id, wp_slash( $meta_key ) ) ) {
return true;
}
if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ) ) ) {
return new WP_Error(
'rest_meta_database_error',

View File

@@ -1052,6 +1052,42 @@ class WP_Test_REST_Post_Meta_Fields extends WP_Test_REST_TestCase {
$this->assertEmpty( $meta );
}
/**
* Ensure deleting non-existant meta data behaves gracefully.
*
* @ticket 52787
* @dataProvider data_delete_does_not_trigger_error_if_no_meta_values
*
* @param array|null $delete_value Value used to delete meta data.
*/
public function test_delete_does_not_trigger_error_if_no_meta_values( $delete_value ) {
$this->grant_write_permission();
$data = array(
'meta' => array(
'test_multi' => $delete_value,
),
);
$request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
$request->set_body_params( $data );
$response = rest_get_server()->dispatch( $request );
$this->assertSame( 200, $response->get_status() );
}
/**
* Data provider for test_delete_does_not_trigger_error_if_no_meta_values().
*
* @return array[] Array of test parameters.
*/
public function data_delete_does_not_trigger_error_if_no_meta_values() {
return array(
array( array() ),
array( null ),
);
}
public function test_remove_multi_value_db_error() {
add_post_meta( self::$post_id, 'test_multi', 'val1' );
$values = get_post_meta( self::$post_id, 'test_multi', false );