mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2025-10-16 12:05:38 +00:00
Revisions: only create autosave when content changed.
In the autosave REST API endpoint, avoid excessive database writes when an autosave is sent with content that is unchanged from the saved post. Before this fix, clicking "preview" in the editor (which uses the autosave feature) multiple times would cause an identical autosave entry to be deleted and re-created repeatedly. Props inwerpsel, aduth, mukesh27, ironprogrammer. Fixes #49532. git-svn-id: https://develop.svn.wordpress.org/trunk@55154 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
ece2e850ca
commit
30175c97ac
@ -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 );
|
||||
|
||||
|
||||
@ -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"' );
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user