Ticket #16215: 16215-14.patch
File 16215-14.patch, 12.1 KB (added by , 12 years ago) |
---|
-
wp-includes/post-template.php
1424 1424 1425 1425 // Since 3.6 revisions include a copy of the current post data as a revision. 1426 1426 // 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 ); 1428 1428 if ( $parent_included && ! $parent ) 1429 1429 array_pop( $revisions ); 1430 1430 elseif ( ! $parent_included && $parent ) -
wp-includes/revision.php
63 63 /** 64 64 * Saves an already existing post as a post revision. 65 65 * 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 69 68 * 70 69 * @package WordPress 71 70 * @subpackage Post_Revisions 72 71 * @since 2.6.0 73 72 * 74 73 * @uses _wp_put_post_revision() 75 * @uses wp_first_revision_matches_current_version()76 74 * 77 75 * @param int $post_id The ID of the post to save as a revision. 78 76 * @return mixed Null or 0 if error, new revision ID, if success. 79 77 */ 80 78 function wp_save_post_revision( $post_id ) { 81 //check to see if the post's first revision already matches the post data82 //should be true before post update, _except_ for old data which83 //doesn't include a copy of the current post data in revisions84 if ( wp_first_revision_matches_current_version( $post_id ) )85 return;86 87 79 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 88 80 return; 89 81 90 if ( ! $post = get_post( $post_id , ARRAY_A) )82 if ( ! $post = get_post( $post_id ) ) 91 83 return; 92 84 93 if ( ! wp_revisions_enabled( (object) $post) )85 if ( ! post_type_supports( $post->post_type, 'revisions' ) ) 94 86 return; 95 87 96 if ( 'auto-draft' == $post ['post_status'])88 if ( 'auto-draft' == $post->post_status ) 97 89 return; 98 90 99 if ( ! post_type_supports( $post['post_type'], 'revisions') )91 if ( ! wp_revisions_enabled( $post ) ) 100 92 return; 101 93 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 104 97 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 } 107 105 108 //if no previous revisions, save one for sure109 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; 110 108 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; 121 113 } 114 } 122 115 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; 127 119 } 128 120 } 129 121 130 122 $return = _wp_put_post_revision( $post ); 131 123 132 $revisions_to_keep = wp_revisions_to_keep( (object)$post );124 $revisions_to_keep = wp_revisions_to_keep( $post ); 133 125 134 126 if ( $revisions_to_keep < 0 ) 135 127 return $return; 136 128 137 // all revisions and (possibly) one autosave129 // all revisions and autosaves 138 130 $revisions = wp_get_post_revisions( $post_id, array( 'order' => 'ASC' ) ); 139 131 140 132 $delete = count($revisions) - $revisions_to_keep; … … 144 136 145 137 $revisions = array_slice( $revisions, 0, $delete ); 146 138 147 for ( $i = 0; isset( $revisions[$i]); $i++ ) {139 for ( $i = 0; isset( $revisions[$i] ); $i++ ) { 148 140 if ( false !== strpos( $revisions[ $i ]->post_name, 'autosave' ) ) 149 141 continue; 142 150 143 wp_delete_post_revision( $revisions[ $i ]->ID ); 151 144 } 152 145 … … 444 437 return (int) apply_filters( 'wp_revisions_to_keep', $num, $post ); 445 438 } 446 439 447 448 440 function _set_preview($post) { 449 441 450 442 if ( ! is_object($post) ) … … 464 456 return $post; 465 457 } 466 458 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 { 459 function _wp_get_post_revision_version( $revision ) { 460 if ( is_object( $revision ) ) 461 $revision = get_object_vars( $revision ); 462 elseif ( !is_array( $revision ) ) 481 463 return false; 482 }483 464 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]; 487 467 488 if ( '1' === $matches[2] ) {489 return 1;490 }491 492 468 return 0; 493 469 } 494 470 … … 502 478 * @uses get_post() 503 479 * @uses post_type_supports() 504 480 * @uses wp_get_post_revisions() 505 * @uses wp_save_post_revision()506 481 * 507 482 * @param int|object $post_id Post ID or post object 508 483 * @return true if success, false if problems … … 514 489 if ( ! $post ) 515 490 return false; 516 491 517 //make sure we have a current revision, only adds one if missing518 wp_save_post_revision( $post->ID );519 520 492 if ( ! post_type_supports( $post->post_type, 'revisions' ) ) 521 493 return false; 522 494 523 495 $revisions = wp_get_post_revisions( $post->ID ); // array( 'order' => 'DESC', 'orderby' => 'date' ); // Always work from most recent to oldest 524 496 497 if ( ! $first = reset( $revisions ) ) 498 return true; 525 499 526 if ( ! $revisions ) 500 // Check if the revisions have already been updated 501 if ( preg_match( '/^\d+-(?:autosave|revision)-v\d+$/', $first->post_name ) ) 527 502 return true; 528 503 529 504 // Add post option exclusively 530 $lock 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 ) ); 533 508 if ( ! $result ) { 534 509 // 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 ) { 537 512 // Can't write to the lock, and can't read the lock. 538 513 // Something broken has happened 539 514 return false; 540 515 } 541 516 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; 546 520 } 547 521 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 553 523 } 554 524 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 ); 556 527 557 528 reset( $revisions ); 529 558 530 do { 559 531 $this_revision = current( $revisions ); 560 532 $prev_revision = next( $revisions ); 561 533 562 534 $this_revision_version = _wp_get_post_revision_version( $this_revision ); 563 535 564 error_log($this_revision_version);565 566 536 // Something terrible happened 567 537 if ( false === $this_revision_version ) 568 538 continue; … … 571 541 if ( 0 < $this_revision_version ) 572 542 continue; 573 543 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 ); 580 548 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 ); 582 554 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; 586 558 } 587 559 588 560 // 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 602 566 } while ( $prev_revision ); 603 567 604 568 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; 606 573 } 607 574 608 575 … … 628 595 * @param int|object $post Post ID or post object. 629 596 * @return bool false if not a match, otherwise true. 630 597 */ 631 function wp_first_revision_matches_current_version( $post ) { 632 598 function _wp_last_revision_matches_current_post( $post ) { 633 599 if ( ! $post = get_post( $post ) ) 634 600 return false; 635 601 636 602 if ( ! $revisions = wp_get_post_revisions( $post->ID ) ) 637 603 return false; 638 604 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 } 640 611 641 if ( ! ($last_revision->post_modified == $post->post_modified ) ) 612 // No revisions yet, only autosaves 613 if ( ! isset( $last_revision ) ) 642 614 return false; 643 615 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; 645 629 } 646 630 647 631 /** … … 706 690 $r .= "</table>"; 707 691 708 692 return array( 'html' => $r, 'linesadded' => $linesadded, 'linesdeleted' => $linesdeleted ); 709 693 }