From e2fff3fddc8b26f9b28414066f3c0c23f31b090d Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Tue, 23 Mar 2021 23:34:59 +0000 Subject: [PATCH] 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 --- .../fields/class-wp-rest-meta-fields.php | 4 +++ .../tests/rest-api/rest-post-meta-fields.php | 36 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php b/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php index 78cef6f910..817f5c106a 100644 --- a/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php +++ b/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php @@ -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', diff --git a/tests/phpunit/tests/rest-api/rest-post-meta-fields.php b/tests/phpunit/tests/rest-api/rest-post-meta-fields.php index 2b24cfc667..0953a9fd41 100644 --- a/tests/phpunit/tests/rest-api/rest-post-meta-fields.php +++ b/tests/phpunit/tests/rest-api/rest-post-meta-fields.php @@ -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 );