Make WordPress Core


Ignore:
Timestamp:
01/27/2023 10:01:59 PM (16 months ago)
Author:
adamsilverstein
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php

    r54130 r55154  
    361361        }
    362362
     363        // Only create an autosave when it is different from the saved post.
     364        $autosave_is_different = false;
     365        $new_autosave          = _wp_post_revision_data( $post_data, true );
     366
     367        foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) {
     368            if ( normalize_whitespace( $new_autosave[ $field ] ) !== normalize_whitespace( $post->$field ) ) {
     369                $autosave_is_different = true;
     370                break;
     371            }
     372        }
     373
     374        if ( ! $autosave_is_different ) {
     375            return new WP_Error(
     376                'rest_autosave_no_changes',
     377                __( 'There is nothing to save. The autosave and the post content are the same.' ),
     378                array( 'status' => 400 )
     379            );
     380        }
     381
    363382        $user_id = get_current_user_id();
    364383
     
    367386
    368387        if ( $old_autosave ) {
    369             $new_autosave                = _wp_post_revision_data( $post_data, true );
    370388            $new_autosave['ID']          = $old_autosave->ID;
    371389            $new_autosave['post_author'] = $user_id;
    372 
    373             // If the new autosave has the same content as the post, delete the autosave.
    374             $autosave_is_different = false;
    375 
    376             foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) {
    377                 if ( normalize_whitespace( $new_autosave[ $field ] ) !== normalize_whitespace( $post->$field ) ) {
    378                     $autosave_is_different = true;
    379                     break;
    380                 }
    381             }
    382 
    383             if ( ! $autosave_is_different ) {
    384                 wp_delete_post_revision( $old_autosave->ID );
    385                 return new WP_Error(
    386                     'rest_autosave_no_changes',
    387                     __( 'There is nothing to save. The autosave and the post content are the same.' ),
    388                     array( 'status' => 400 )
    389                 );
    390             }
    391390
    392391            /** This filter is documented in wp-admin/post.php */
Note: See TracChangeset for help on using the changeset viewer.