WordPress.org

Make WordPress Core

Ticket #16215: 16215-14.patch

File 16215-14.patch, 12.1 KB (added by azaozz, 13 months ago)
  • wp-includes/post-template.php

     
    14241424 
    14251425        // Since 3.6 revisions include a copy of the current post data as a revision. 
    14261426        // The following removes that revision when $parent == false 
    1427         $parent_included = wp_first_revision_matches_current_version( $post_id ); 
     1427        $parent_included = _wp_last_revision_matches_current_post( $post_id ); 
    14281428        if ( $parent_included && ! $parent ) 
    14291429                array_pop( $revisions ); 
    14301430        elseif ( ! $parent_included && $parent ) 
  • wp-includes/revision.php

     
    6363/** 
    6464 * Saves an already existing post as a post revision. 
    6565 * 
    66  * Typically used immediately prior and after post updates. 
    67  * Prior to update checks for old revision data (latest revision != current post before update) and adds a copy of the current post as a revision if missing 
    68  * After update adds a copy of the current post as a revision, so latest revision always matches current post 
     66 * Typically used immediately after post updates. 
     67 * Adds a copy of the current post as a revision, so latest revision always matches current post 
    6968 * 
    7069 * @package WordPress 
    7170 * @subpackage Post_Revisions 
    7271 * @since 2.6.0 
    7372 * 
    7473 * @uses _wp_put_post_revision() 
    75  * @uses wp_first_revision_matches_current_version() 
    7674 * 
    7775 * @param int $post_id The ID of the post to save as a revision. 
    7876 * @return mixed Null or 0 if error, new revision ID, if success. 
    7977 */ 
    8078function wp_save_post_revision( $post_id ) { 
    81         //check to see if the post's first revision already matches the post data 
    82         //should be true before post update, _except_ for old data which 
    83         //doesn't include a copy of the current post data in revisions 
    84         if ( wp_first_revision_matches_current_version( $post_id ) ) 
    85                 return; 
    86  
    8779        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
    8880                return; 
    8981 
    90         if ( ! $post = get_post( $post_id, ARRAY_A ) ) 
     82        if ( ! $post = get_post( $post_id ) ) 
    9183                return; 
    9284 
    93         if ( ! wp_revisions_enabled( (object) $post ) ) 
     85        if ( ! post_type_supports( $post->post_type, 'revisions' ) ) 
    9486                return; 
    9587 
    96         if ( 'auto-draft' == $post['post_status'] ) 
     88        if ( 'auto-draft' == $post->post_status ) 
    9789                return; 
    9890 
    99         if ( ! post_type_supports( $post['post_type'], 'revisions' ) ) 
     91        if ( ! wp_revisions_enabled( $post ) ) 
    10092                return; 
    10193 
    102         // compare the proposed update with the last stored revision, verify 
    103         // different, unless a plugin tells us to always save regardless 
     94        // Compare the proposed update with the last stored revision verifying that 
     95        // they are different, unless a plugin tells us to always save regardless. 
     96        // If no previous revisions, save one 
    10497        if ( $revisions = wp_get_post_revisions( $post_id ) ) { 
    105                 // grab the last revision 
    106                 $last_revision = array_shift( $revisions ); 
     98                // grab the last revision, but not an autosave 
     99                foreach ( $revisions as $revision ) { 
     100                        if ( false !== strpos( $revision->post_name, "{$revision->post_parent}-revision" ) ) { 
     101                                $last_revision = $revision; 
     102                                break; 
     103                        } 
     104                } 
    107105 
    108                 //if no previous revisions, save one for sure 
    109                 if ( $last_revision_array = get_post( $last_revision->ID, ARRAY_A ) ) { 
     106                if ( isset( $last_revision ) && apply_filters( 'wp_save_post_revision_check_for_changes', true, $last_revision, $post ) ) { 
     107                        $post_has_changed = false; 
    110108 
    111                         if ( apply_filters( 'wp_save_post_revision_check_for_changes', true, $last_revision_array, $post ) && is_array( $post ) ) { 
    112                                 $post_has_changed = false; 
    113  
    114                                 foreach ( array_keys( _wp_post_revision_fields() ) as $field ) { 
    115  
    116                                         if ( normalize_whitespace( $post[ $field ] ) != normalize_whitespace( $last_revision_array[ $field ] ) ) { 
    117                                                 $post_has_changed = true; 
    118                                                 break; 
    119  
    120                                         } 
     109                        foreach ( array_keys( _wp_post_revision_fields() ) as $field ) { 
     110                                if ( normalize_whitespace( $post->$field ) != normalize_whitespace( $last_revision->$field ) ) { 
     111                                        $post_has_changed = true; 
     112                                        break; 
    121113                                } 
     114                        } 
    122115 
    123                                 //don't save revision if post unchanged 
    124                                 if( ! $post_has_changed ) 
    125                                         return; 
    126                         } 
     116                        //don't save revision if post unchanged 
     117                        if( ! $post_has_changed ) 
     118                                return; 
    127119                } 
    128120        } 
    129121 
    130122        $return = _wp_put_post_revision( $post ); 
    131123 
    132         $revisions_to_keep = wp_revisions_to_keep( (object) $post ); 
     124        $revisions_to_keep = wp_revisions_to_keep( $post ); 
    133125 
    134126        if ( $revisions_to_keep < 0 ) 
    135127                return $return; 
    136128 
    137         // all revisions and (possibly) one autosave 
     129        // all revisions and autosaves 
    138130        $revisions = wp_get_post_revisions( $post_id, array( 'order' => 'ASC' ) ); 
    139131 
    140132        $delete = count($revisions) - $revisions_to_keep; 
     
    144136 
    145137        $revisions = array_slice( $revisions, 0, $delete ); 
    146138 
    147         for ( $i = 0; isset($revisions[$i]); $i++ ) { 
     139        for ( $i = 0; isset( $revisions[$i] ); $i++ ) { 
    148140                if ( false !== strpos( $revisions[ $i ]->post_name, 'autosave' ) ) 
    149141                        continue; 
     142 
    150143                wp_delete_post_revision( $revisions[ $i ]->ID ); 
    151144        } 
    152145 
     
    444437        return (int) apply_filters( 'wp_revisions_to_keep', $num, $post ); 
    445438} 
    446439 
    447  
    448440function _set_preview($post) { 
    449441 
    450442        if ( ! is_object($post) ) 
     
    464456        return $post; 
    465457} 
    466458 
    467 function _wp_get_post_revision_version( $post ) { 
    468         if ( is_array( $post ) ) { 
    469                 if ( ! isset( $post['post_name'] ) ) { 
    470                         return false; 
    471                 } 
    472  
    473                 $name = $post['post_name']; 
    474         } elseif ( is_object( $post ) ) { 
    475                 if ( ! isset( $post->post_name ) ) { 
    476                         return false; 
    477                 } 
    478  
    479                 $name = $post->post_name; 
    480         } else { 
     459function _wp_get_post_revision_version( $revision ) { 
     460        if ( is_object( $revision ) ) 
     461                $revision = get_object_vars( $revision ); 
     462        elseif ( !is_array( $revision ) ) 
    481463                return false; 
    482         } 
    483464 
    484         if ( ! preg_match( '/^(\d+-)(?:autosave|revision)(?:-v)(\d+)$/', $name, $matches ) ) { 
    485                 return 0; 
    486         } 
     465        if ( preg_match( '/^\d+-(?:autosave|revision)-v(\d+)$/', $revision['post_name'], $matches ) ) 
     466                return (int) $matches[1]; 
    487467 
    488         if ( '1' === $matches[2] ) { 
    489                 return 1; 
    490         } 
    491  
    492468        return 0; 
    493469} 
    494470 
     
    502478 * @uses get_post() 
    503479 * @uses post_type_supports() 
    504480 * @uses wp_get_post_revisions() 
    505  * @uses wp_save_post_revision() 
    506481 * 
    507482 * @param int|object $post_id Post ID or post object 
    508483 * @return true if success, false if problems 
     
    514489        if ( ! $post ) 
    515490                return false; 
    516491 
    517         //make sure we have a current revision, only adds one if missing 
    518         wp_save_post_revision( $post->ID ); 
    519  
    520492        if ( ! post_type_supports( $post->post_type, 'revisions' ) ) 
    521493                return false; 
    522494 
    523495        $revisions = wp_get_post_revisions( $post->ID ); // array( 'order' => 'DESC', 'orderby' => 'date' ); // Always work from most recent to oldest 
    524496 
     497        if ( ! $first = reset( $revisions ) ) 
     498                return true; 
    525499 
    526         if ( ! $revisions ) 
     500        // Check if the revisions have already been updated 
     501        if ( preg_match( '/^\d+-(?:autosave|revision)-v\d+$/', $first->post_name ) ) 
    527502                return true; 
    528503 
    529504        // Add post option exclusively 
    530         $lock      = "revision-upgrade-{$post->ID}"; 
    531         $locked_at = number_format( microtime( true ), 10, '.', '' ); 
    532         $result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, 'no') /* LOCK */", $lock, $locked_at ) ); 
     505        $lock = "revision-upgrade-{$post->ID}"; 
     506        $now = time(); 
     507        $result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, 'no') /* LOCK */", $lock, $now ) ); 
    533508        if ( ! $result ) { 
    534509                // If we couldn't get a lock, see how old the previous lock is 
    535                 $locked_at = get_option( $lock ); 
    536                 if ( !$locked_at ) { 
     510                $locked = get_option( $lock ); 
     511                if ( ! $locked ) { 
    537512                        // Can't write to the lock, and can't read the lock. 
    538513                        // Something broken has happened 
    539514                        return false; 
    540515                } 
    541516 
    542                 if ( $lock_at < number_format( microtime( true ), 10, '.', '' ) - 3600 ) { 
    543                         // Lock is too old - try again 
    544                         delete_option( $lock ); 
    545                         return wp_upgrade_revisions_of_post( $post ); 
     517                if ( $locked > $now - 3600 ) { 
     518                        // Lock is not too old: some other process may be upgrading this post.  Bail. 
     519                        return false; 
    546520                } 
    547521 
    548                 // Lock is not too old: some other process may be upgrading this post.  Bail. 
    549                 return; 
    550         } else { 
    551                 // If we could get a lock, re-"add" the option to fire all the correct filters. 
    552                 add_option( $lock, $locked_at ); 
     522                // Lock is too old - update it (below) and continue 
    553523        } 
    554524 
    555         $success = true; 
     525        // If we could get a lock, re-"add" the option to fire all the correct filters. 
     526        update_option( $lock, $now ); 
    556527 
    557528        reset( $revisions ); 
     529 
    558530        do { 
    559531                $this_revision = current( $revisions ); 
    560532                $prev_revision = next( $revisions ); 
    561533 
    562534                $this_revision_version = _wp_get_post_revision_version( $this_revision ); 
    563535 
    564                 error_log($this_revision_version); 
    565  
    566536                // Something terrible happened 
    567537                if ( false === $this_revision_version ) 
    568538                        continue; 
     
    571541                if ( 0 < $this_revision_version ) 
    572542                        continue; 
    573543 
    574                 // This revision is the oldest revision of the post. 
    575                 // The correct post_author is probably $post->post_author, but that's only a good guess. 
    576                 // Leave un-upgraded. 
    577                 if ( ! $prev_revision ) { 
    578                         continue; 
    579                 } 
     544                // Always update the revision version 
     545                $update = array( 
     546                        'post_name' => preg_replace( '/^(\d+-(?:autosave|revision))[\d-]*$/', '$1-v1', $this_revision->post_name ), 
     547                ); 
    580548 
    581                 $prev_revision_version = _wp_get_post_revision_version( $prev_revision ); 
     549                // If this revision is the oldest revision of the post, i.e. no $prev_revision, 
     550                // the correct post_author is probably $post->post_author, but that's only a good guess. 
     551                // Update the revision version only and Leave the author as-is. 
     552                if ( $prev_revision ) { 
     553                        $prev_revision_version = _wp_get_post_revision_version( $prev_revision ); 
    582554 
    583                 // If the previous revision is already up to date, it no longer has the information we need :( 
    584                 if ( 0 < $prev_revision_version ) { 
    585                         continue; 
     555                        // If the previous revision is already up to date, it no longer has the information we need :( 
     556                        if ( $prev_revision_version < 1 ) 
     557                                $update['post_author'] = $prev_revision->post_author; 
    586558                } 
    587559 
    588560                // Upgrade this revision 
    589                 // Cast as object so that wp_update_post() handles slashing for us 
    590                 $update = (object) array( 
    591                         'ID'          => $this_revision->ID, 
    592                         'post_name'   => preg_replace( '/^(\d+-)(autosave|revision)-(\d+)$/', '$1$2-v1', $this_revision->post_name ), 
    593                         'post_author' => $prev_revision->post_author, 
    594                 ); 
    595                 //error_log(json_encode($update)); 
    596                 $result = wp_update_post( $update ); 
    597                 if ( ! $result || is_wp_error( $result ) ) { 
    598                         // Wilhelm! 
    599                         $success = false; 
    600                         break; 
    601                 } 
     561                $result = $wpdb->update( $wpdb->posts, $update, array( 'ID' => $this_revision->ID ) ); 
     562 
     563                if ( $result ) 
     564                        wp_cache_delete( $this_revision->ID, 'posts' ); 
     565 
    602566        } while ( $prev_revision ); 
    603567 
    604568        delete_option( $lock ); 
    605         return true; 
     569         
     570        // Add a copy of the post as latest revision. 
     571        wp_save_post_revision( $post->ID ); 
     572        return $success; 
    606573} 
    607574 
    608575 
     
    628595 * @param int|object $post Post ID or post object. 
    629596 * @return bool false if not a match, otherwise true. 
    630597 */ 
    631 function wp_first_revision_matches_current_version( $post ) { 
    632  
     598function _wp_last_revision_matches_current_post( $post ) { 
    633599        if ( ! $post = get_post( $post ) ) 
    634600                return false; 
    635601 
    636602        if ( ! $revisions = wp_get_post_revisions( $post->ID ) ) 
    637603                return false; 
    638604 
    639         $last_revision = array_shift( $revisions ); 
     605        foreach ( $revisions as $revision ) { 
     606                if ( false !== strpos( $revision->post_name, "{$revision->post_parent}-revision" ) ) { 
     607                        $last_revision = $revision; 
     608                        break; 
     609                } 
     610        } 
    640611 
    641         if ( ! ($last_revision->post_modified == $post->post_modified ) ) 
     612        // No revisions yet, only autosaves 
     613        if ( ! isset( $last_revision ) ) 
    642614                return false; 
    643615 
    644         return true; 
     616        $post_has_changed = false; 
     617        if ( $last_revision->post_modified == $post->post_modified ) { 
     618                foreach ( array_keys( _wp_post_revision_fields() ) as $field ) { 
     619                        if ( normalize_whitespace( $post->$field ) != normalize_whitespace( $last_revision->$field ) ) { 
     620                                $post_has_changed = true; 
     621                                break; 
     622                        } 
     623                } 
     624        } else { 
     625                return false; 
     626        } 
     627 
     628        return ! $post_has_changed; 
    645629} 
    646630 
    647631/** 
     
    706690        $r .= "</table>"; 
    707691 
    708692        return array( 'html' => $r, 'linesadded' => $linesadded, 'linesdeleted' => $linesdeleted ); 
    709         } 
     693}