From 8c319e694b6f92ab9485f9cb7275ef5cde627feb Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Fri, 24 Jul 2026 12:26:25 +0530 Subject: [PATCH 1/8] Remove new line --- .../rest-api/endpoints/class-wp-rest-autosaves-controller.php | 1 - 1 file changed, 1 deletion(-) 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 65ca4e0018cb6..3adfb76c0947d 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 @@ -376,7 +376,6 @@ public function get_item_schema() { * @return mixed The autosave revision ID or WP_Error. */ public function create_post_autosave( $post_data, array $meta = array() ) { - $post_id = (int) $post_data['ID']; $post = get_post( $post_id ); From df2d93d7c48d577dc5ca84de5866c51f0c9eb7d7 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Fri, 24 Jul 2026 12:27:11 +0530 Subject: [PATCH 2/8] Remove diff autosave flag --- .../rest-api/endpoints/class-wp-rest-autosaves-controller.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 3adfb76c0947d..37a6f24307f63 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 @@ -383,9 +383,7 @@ public function create_post_autosave( $post_data, array $meta = array() ) { 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 ); + $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 ) ) { From a241154fedda32c10cb670939743e4ec443cddc1 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Fri, 24 Jul 2026 12:28:16 +0530 Subject: [PATCH 3/8] Remove redundant meta cheks --- .../class-wp-rest-autosaves-controller.php | 18 ------------------ 1 file changed, 18 deletions(-) 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 37a6f24307f63..71f29b5fc9434 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 @@ -385,26 +385,8 @@ public function create_post_autosave( $post_data, array $meta = array() ) { $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; - } - } - - // Check if meta values have changed. if ( ! empty( $meta ) ) { $revisioned_meta_keys = wp_post_revision_meta_keys( $post->post_type ); - foreach ( $revisioned_meta_keys as $meta_key ) { - // get_metadata_raw is used to avoid retrieving the default value. - $old_meta = get_metadata_raw( 'post', $post_id, $meta_key, true ); - $new_meta = $meta[ $meta_key ] ?? ''; - - if ( $new_meta !== $old_meta ) { - $autosave_is_different = true; - break; - } - } } $user_id = get_current_user_id(); From d39dd056e842b6f1400e7ef06dcfaff2a82f2cb0 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Fri, 24 Jul 2026 12:28:51 +0530 Subject: [PATCH 4/8] Update stale autosave fields when the submitted data matches the published post --- .../class-wp-rest-autosaves-controller.php | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) 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 71f29b5fc9434..22df7bcfeed46 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 @@ -394,12 +394,39 @@ public function create_post_autosave( $post_data, array $meta = array() ) { // Store one autosave per author. If there is already an autosave, overwrite it. $old_autosave = wp_get_post_autosave( $post_id, $user_id ); - if ( ! $autosave_is_different && $old_autosave ) { + if ( $old_autosave ) { + /* + * When an autosave revision already exists, compare the incoming data + * against its current field values rather than the published post. A field + * reverted to the published value - such as a title edit that was undone - + * must still overwrite any stale value in the existing autosave, otherwise + * consumers like Preview will display incorrect content indefinitely. + */ + $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( $old_autosave->$field ) ) { + $autosave_is_different = true; + break; + } + } + + if ( ! $autosave_is_different && ! empty( $meta ) ) { + foreach ( $revisioned_meta_keys as $meta_key ) { + $old_meta_value = get_metadata_raw( 'post', $old_autosave->ID, $meta_key, true ); + $new_meta_value = $meta[ $meta_key ] ?? ''; + + if ( $new_meta_value !== $old_meta_value ) { + $autosave_is_different = true; + break; + } + } + } + + if ( ! $autosave_is_different ) { // Nothing to save, return the existing autosave. return $old_autosave->ID; } - if ( $old_autosave ) { $new_autosave['ID'] = $old_autosave->ID; $new_autosave['post_author'] = $user_id; From d49a0c65f50f08d99dd8fd1ee34cb27782b9ddab Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Fri, 24 Jul 2026 12:30:10 +0530 Subject: [PATCH 5/8] Update doc block comment --- .../endpoints/class-wp-rest-autosaves-controller.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 22df7bcfeed46..a9e0de4714fc9 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 @@ -370,6 +370,8 @@ public function get_item_schema() { * * @since 5.0.0 * @since 6.4.0 The `$meta` parameter was added. + * @since 7.1.0 Compares incoming data against the existing autosave instead + * of the published post. * * @param array $post_data Associative array containing the post data. * @param array $meta Associative array containing the post meta data. @@ -423,9 +425,9 @@ public function create_post_autosave( $post_data, array $meta = array() ) { } if ( ! $autosave_is_different ) { - // Nothing to save, return the existing autosave. - return $old_autosave->ID; - } + // Nothing to save, return the existing autosave. + return $old_autosave->ID; + } $new_autosave['ID'] = $old_autosave->ID; $new_autosave['post_author'] = $user_id; From 61389da81fef6edd33a73d6e3b8445a94dc2f218 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Fri, 24 Jul 2026 13:07:52 +0530 Subject: [PATCH 6/8] ensure REST API autosaves correctly handle identical post content and missing meta keys --- .../endpoints/class-wp-rest-autosaves-controller.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 a9e0de4714fc9..00924b79a15e0 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 @@ -414,8 +414,12 @@ public function create_post_autosave( $post_data, array $meta = array() ) { if ( ! $autosave_is_different && ! empty( $meta ) ) { foreach ( $revisioned_meta_keys as $meta_key ) { + if ( ! array_key_exists( $meta_key, $meta ) ) { + continue; + } + $old_meta_value = get_metadata_raw( 'post', $old_autosave->ID, $meta_key, true ); - $new_meta_value = $meta[ $meta_key ] ?? ''; + $new_meta_value = $meta[ $meta_key ]; if ( $new_meta_value !== $old_meta_value ) { $autosave_is_different = true; From 94cef60cce30e75ac315e8e893bf8476c7eae97f Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Fri, 24 Jul 2026 13:08:34 +0530 Subject: [PATCH 7/8] Test create post autosave updates stale field on revert --- .../rest-api/rest-autosaves-controller.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php index 7815f8ced23c9..280c24054e0a1 100644 --- a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php +++ b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php @@ -920,4 +920,32 @@ public static function data_head_request_with_specified_fields_returns_success_r 'get_items request' => array( '/wp/v2/posts/%d' ), ); } + + /** + * @ticket 65694 + */ + public function test_create_post_autosave_updates_stale_field_on_revert() { + wp_set_current_user( self::$editor_id ); + + $post_id = $this->factory->post->create( array( + 'post_title' => 'Original Title', + 'post_status' => 'publish', + 'post_author' => self::$editor_id, + ) ); + + $controller = new WP_REST_Autosaves_Controller( 'post' ); + + $controller->create_post_autosave( array( + 'ID' => $post_id, + 'post_title' => 'Original Title !!', + ) ); + + $controller->create_post_autosave( array( + 'ID' => $post_id, + 'post_title' => 'Original Title', + ) ); + + $autosave = wp_get_post_autosave( $post_id, self::$editor_id ); + $this->assertSame( 'Original Title', $autosave->post_title ); + } } From cd87a3917f220adb2d3e63ffc96f63d1d9bf5ac4 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Fri, 24 Jul 2026 13:11:32 +0530 Subject: [PATCH 8/8] Fix linting --- .../rest-api/rest-autosaves-controller.php | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php index 280c24054e0a1..7b43f6354faf9 100644 --- a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php +++ b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php @@ -927,23 +927,29 @@ public static function data_head_request_with_specified_fields_returns_success_r public function test_create_post_autosave_updates_stale_field_on_revert() { wp_set_current_user( self::$editor_id ); - $post_id = $this->factory->post->create( array( - 'post_title' => 'Original Title', - 'post_status' => 'publish', - 'post_author' => self::$editor_id, - ) ); + $post_id = $this->factory->post->create( + array( + 'post_title' => 'Original Title', + 'post_status' => 'publish', + 'post_author' => self::$editor_id, + ) + ); $controller = new WP_REST_Autosaves_Controller( 'post' ); - $controller->create_post_autosave( array( - 'ID' => $post_id, - 'post_title' => 'Original Title !!', - ) ); + $controller->create_post_autosave( + array( + 'ID' => $post_id, + 'post_title' => 'Original Title !!', + ) + ); - $controller->create_post_autosave( array( - 'ID' => $post_id, - 'post_title' => 'Original Title', - ) ); + $controller->create_post_autosave( + array( + 'ID' => $post_id, + 'post_title' => 'Original Title', + ) + ); $autosave = wp_get_post_autosave( $post_id, self::$editor_id ); $this->assertSame( 'Original Title', $autosave->post_title );