diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php index f99a201974..e5409e7329 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php @@ -360,35 +360,34 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller { return $post; } + // Only create an autosave when it is different from the saved post. + $autosave_is_different = false; + $new_autosave = _wp_post_revision_data( $post_data, true ); + + foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) { + if ( normalize_whitespace( $new_autosave[ $field ] ) !== normalize_whitespace( $post->$field ) ) { + $autosave_is_different = true; + break; + } + } + + if ( ! $autosave_is_different ) { + return new WP_Error( + 'rest_autosave_no_changes', + __( 'There is nothing to save. The autosave and the post content are the same.' ), + array( 'status' => 400 ) + ); + } + $user_id = get_current_user_id(); // Store one autosave per author. If there is already an autosave, overwrite it. $old_autosave = wp_get_post_autosave( $post_id, $user_id ); if ( $old_autosave ) { - $new_autosave = _wp_post_revision_data( $post_data, true ); $new_autosave['ID'] = $old_autosave->ID; $new_autosave['post_author'] = $user_id; - // If the new autosave has the same content as the post, delete the autosave. - $autosave_is_different = false; - - foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) { - if ( normalize_whitespace( $new_autosave[ $field ] ) !== normalize_whitespace( $post->$field ) ) { - $autosave_is_different = true; - break; - } - } - - if ( ! $autosave_is_different ) { - wp_delete_post_revision( $old_autosave->ID ); - return new WP_Error( - 'rest_autosave_no_changes', - __( 'There is nothing to save. The autosave and the post content are the same.' ), - array( 'status' => 400 ) - ); - } - /** This filter is documented in wp-admin/post.php */ do_action( 'wp_creating_autosave', $new_autosave ); diff --git a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php index 088f02b67d..32ba9768e7 100644 --- a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php +++ b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php @@ -674,4 +674,38 @@ class WP_Test_REST_Autosaves_Controller extends WP_Test_REST_Post_Type_Controlle wp_delete_post( $post_id ); } + + /** + * @ticket 49532 + * + * @covers WP_REST_Autosaves_Controller::create_post_autosave + */ + public function test_rest_autosave_do_not_create_autosave_when_post_is_unchanged() { + // Create a post by the editor. + $post_data = array( + 'post_content' => 'Test post content', + 'post_title' => 'Test post title', + 'post_excerpt' => 'Test post excerpt', + 'post_author' => self::$editor_id, + 'post_status' => 'publish', + ); + $post_id = wp_insert_post( $post_data ); + + wp_set_current_user( self::$editor_id ); + + $autosave_data = array( + 'post_content' => $post_data['post_content'], + ); + + // Create autosaves response. + $request = new WP_REST_Request( 'POST', '/wp/v2/posts/' . $post_id . '/autosaves' ); + $request->add_header( 'content-type', 'application/json' ); + $request->set_body( wp_json_encode( $autosave_data ) ); + + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + + $this->assertSame( 400, $response->get_status(), 'Response status is not 400.' ); + $this->assertSame( 'rest_autosave_no_changes', $data['code'], 'Response "code" is not "rest_autosave_no_changes"' ); + } }