| 93 | | // if new data is supplied, check that it is different from last saved revision, unless a plugin tells us to always save regardless |
| 94 | | if ( apply_filters( 'wp_save_post_revision_check_for_changes', true, $post, $new_data ) && is_array( $new_data ) ) { |
| 95 | | $post_has_changed = false; |
| 96 | | foreach ( array_keys( _wp_post_revision_fields() ) as $field ) { |
| 97 | | if ( normalize_whitespace( $new_data[ $field ] ) != normalize_whitespace( $post[ $field ] ) ) { |
| 98 | | $post_has_changed = true; |
| 99 | | break; |
| | 102 | // compare the proposed update with the last stored revision, verify |
| | 103 | // different, unless a plugin tells us to always save regardless |
| | 104 | if ( $revisions = wp_get_post_revisions( $post_id ) ) { |
| | 105 | // grab the last revision |
| | 106 | $last_revision = array_shift( $revisions ); |
| | 107 | |
| | 108 | //if no previous revisions, save one for sure |
| | 109 | if ( $last_revision_array = get_post( $last_revision->ID, ARRAY_A ) ) { |
| | 110 | |
| | 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 | } |
| | 121 | } |
| | 122 | |
| | 123 | //don't save revision if post unchanged |
| | 124 | if( ! $post_has_changed ) |
| | 125 | return; |
| | 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 { |
| | 481 | return false; |
| | 482 | } |
| | 483 | |
| | 484 | if ( ! preg_match( '/^([\d-]+)(?:autosave|revision)(?:-v)([\d-]+)$/', $name, $matches ) ) { |
| | 485 | return 0; |
| | 486 | } |
| | 487 | |
| | 488 | if ( '1' === $matches[2] ) { |
| | 489 | return 1; |
| | 490 | } |
| | 491 | |
| | 492 | return 0; |
| | 493 | } |
| | 494 | |
| | 495 | /** |
| | 496 | * Upgrade the data |
| | 497 | * |
| | 498 | * @package WordPress |
| | 499 | * @subpackage Post_Revisions |
| | 500 | * @since 3.6.0 |
| | 501 | * |
| | 502 | * @uses get_post() |
| | 503 | * @uses post_type_supports() |
| | 504 | * @uses wp_get_post_revisions() |
| | 505 | * @uses wp_save_post_revision() |
| | 506 | * |
| | 507 | * @param int|object $post_id Post ID or post object |
| | 508 | * @return true if success, false if problems |
| | 509 | */ |
| | 510 | function _wp_upgrade_revisions_of_post( $post ) { |
| | 511 | global $wpdb; |
| | 512 | |
| | 513 | $post = get_post( $post ); |
| | 514 | if ( ! $post ) |
| | 515 | return false; |
| | 516 | |
| | 517 | //make sure we have a current revision, only adds one if missing |
| | 518 | wp_save_post_revision( $post->ID ); |
| | 519 | |
| | 520 | if ( ! post_type_supports( $post->post_type, 'revisions' ) ) |
| | 521 | return false; |
| | 522 | |
| | 523 | $revisions = wp_get_post_revisions( $post->ID ); // array( 'order' => 'DESC', 'orderby' => 'date' ); // Always work from most recent to oldest |
| | 524 | |
| | 525 | |
| | 526 | if ( ! $revisions ) |
| | 527 | return true; |
| | 528 | |
| | 529 | // 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 ) ); |
| | 533 | if ( ! $result ) { |
| | 534 | // If we couldn't get a lock, see how old the previous lock is |
| | 535 | $locked_at = get_option( $lock ); |
| | 536 | if ( !$locked_at ) { |
| | 537 | // Can't write to the lock, and can't read the lock. |
| | 538 | // Something broken has happened |
| | 539 | return false; |
| | 540 | } |
| | 541 | |
| | 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 ); |
| | 546 | } |
| | 547 | |
| | 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 ); |
| | 553 | } |
| | 554 | |
| | 555 | $success = true; |
| | 556 | |
| | 557 | reset( $revisions ); |
| | 558 | do { |
| | 559 | $this_revision = current( $revisions ); |
| | 560 | $prev_revision = next( $revisions ); |
| | 561 | |
| | 562 | $this_revision_version = _wp_get_post_revision_version( $this_revision ); |
| | 563 | |
| | 564 | error_log($this_revision_version); |
| | 565 | |
| | 566 | // Something terrible happened |
| | 567 | if ( false === $this_revision_version ) |
| | 568 | continue; |
| | 569 | |
| | 570 | // 1 is the latest revision version, so we're already up to date |
| | 571 | if ( 0 < $this_revision_version ) |
| | 572 | continue; |
| | 573 | |
| | 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 | } |
| | 580 | |
| | 581 | $prev_revision_version = _wp_get_post_revision_version( $prev_revision ); |
| | 582 | |
| | 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; |
| | 586 | } |
| | 587 | |
| | 588 | // 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 | } |
| | 602 | } while ( $prev_revision ); |
| | 603 | |
| | 604 | delete_option( $lock ); |
| | 605 | return true; |
| | 606 | } |
| | 607 | |
| | 608 | |