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 1b6a7fe37f..60c3c3ab24 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 @@ -368,6 +368,16 @@ abstract class WP_REST_Meta_Fields { protected function update_meta_value( $object_id, $meta_key, $name, $value ) { $meta_type = $this->get_meta_type(); + // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false. + $old_value = get_metadata( $meta_type, $object_id, $meta_key ); + $subtype = get_object_subtype( $meta_type, $object_id ); + + if ( is_array( $old_value ) && 1 === count( $old_value ) + && $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value ) + ) { + return true; + } + if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { return new WP_Error( 'rest_cannot_update', @@ -380,16 +390,6 @@ abstract class WP_REST_Meta_Fields { ); } - // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false. - $old_value = get_metadata( $meta_type, $object_id, $meta_key ); - $subtype = get_object_subtype( $meta_type, $object_id ); - - if ( is_array( $old_value ) && 1 === count( $old_value ) - && $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value ) - ) { - return true; - } - if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { 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 3c627dfd59..2142e80582 100644 --- a/tests/phpunit/tests/rest-api/rest-post-meta-fields.php +++ b/tests/phpunit/tests/rest-api/rest-post-meta-fields.php @@ -2299,6 +2299,42 @@ class WP_Test_REST_Post_Meta_Fields extends WP_Test_REST_TestCase { $this->assertSame( array( 'project' => 'WordCamp' ), $data['meta']['object'] ); } + /** + * @ticket 57745 + */ + public function test_update_meta_with_unchanged_values_and_custom_authentication() { + register_post_meta( + 'post', + 'authenticated', + array( + 'single' => true, + 'type' => 'boolean', + 'default' => false, + 'show_in_rest' => true, + 'auth_callback' => '__return_false', + ) + ); + + add_post_meta( self::$post_id, 'authenticated', false ); + + $this->grant_write_permission(); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); + $request->set_body_params( + array( + 'meta' => array( + 'authenticated' => false, + ), + ) + ); + + $response = rest_get_server()->dispatch( $request ); + $this->assertSame( 200, $response->get_status() ); + + $data = $response->get_data(); + $this->assertSame( false, $data['meta']['authenticated'] ); + } + /** * @ticket 43392 */