Ticket #20564: 20564.16.diff
File 20564.16.diff, 12.0 KB (added by , 10 years ago) |
---|
-
src/wp-admin/includes/post.php
1523 1523 $new_autosave['ID'] = $old_autosave->ID; 1524 1524 $new_autosave['post_author'] = $post_author; 1525 1525 1526 // Auto-save revisioned meta fields. 1527 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 1528 if ( isset( $_POST[ $meta_key ] ) 1529 && '' !== $_POST[ $meta_key ] 1530 && get_post_meta( $new_autosave['ID'], $meta_key, true ) != wp_unslash( $_POST[ $meta_key ] ) ) 1531 { 1532 /* 1533 * Use the underlying delete_metadata() and add_metadata() functions 1534 * vs delete_post_meta() and add_post_meta() to make sure we're working 1535 * with the actual revision meta. 1536 */ 1537 delete_metadata( 'post', $new_autosave['ID'], $meta_key ); 1538 if ( ! empty( $_POST[ $meta_key ] ) ) { 1539 add_metadata( 'post', $new_autosave['ID'], $meta_key, $_POST[ $meta_key ] ); 1540 } 1541 } 1542 } 1543 1526 1544 // If the new autosave has the same content as the post, delete the autosave. 1527 1545 $post = get_post( $post_id ); 1528 1546 $autosave_is_different = false; -
src/wp-content/themes/twentyfourteen/functions.php
25 25 * @since Twenty Fourteen 1.0 26 26 */ 27 27 28 28 29 /** 29 30 * Set up the content width value based on the theme's design. 30 31 * -
src/wp-includes/revision.php
70 70 } 71 71 72 72 /** 73 * Determine which post meta fields should be revisioned. 74 * 75 * @access private 76 * @since 4.0.0 77 * 78 * @return array An array of meta keys to be revisioned. 79 */ 80 function _wp_post_revision_meta_keys() { 81 /** 82 * Filter the list of post meta keys to be revisioned. 83 * 84 * @since 4.0.0 85 * 86 * @param array $keys An array of default meta fields to be revisioned. 87 */ 88 return apply_filters( 'wp_post_revision_meta_keys', array() ); 89 } 90 91 /** 73 92 * Saves an already existing post as a post revision. 74 93 * 75 94 * Typically used immediately after post updates. … … 127 146 if ( isset( $last_revision ) && apply_filters( 'wp_save_post_revision_check_for_changes', $check_for_changes = true, $last_revision, $post ) ) { 128 147 $post_has_changed = false; 129 148 149 // Check whether revisioned post fields have been changed. 130 150 foreach ( array_keys( _wp_post_revision_fields() ) as $field ) { 131 151 if ( normalize_whitespace( $post->$field ) != normalize_whitespace( $last_revision->$field ) ) { 132 152 $post_has_changed = true; … … 133 153 break; 134 154 } 135 155 } 136 //don't save revision if post unchanged 156 157 // Check whether revisioned post meta fields have changed. 158 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 159 if ( get_post_meta( $post->ID, $meta_key ) != get_post_meta( $last_revision->ID, $meta_key ) ) { 160 $post_has_changed = true; 161 break; 162 } 163 } 164 165 // Don't save revision if the post is unchanged. 137 166 if( ! $post_has_changed ) 138 167 return; 139 168 } … … 253 282 if ( isset($post['post_type']) && 'revision' == $post['post_type'] ) 254 283 return new WP_Error( 'post_type', __( 'Cannot create a revision of a revision' ) ); 255 284 285 $post_id = (int) $post['ID']; 256 286 $post = _wp_post_revision_fields( $post, $autosave ); 257 287 $post = wp_slash($post); //since data is from db 258 288 … … 271 301 do_action( '_wp_put_post_revision', $revision_id ); 272 302 } 273 303 304 // Save revisioned meta fields. 305 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 306 $meta_value = get_post_meta( $post_id, $meta_key, true ); 307 308 // Don't save blank meta values 309 if( '' == $meta_value ) { 310 continue; 311 } 312 /* 313 * Use the underlying add_metadata() function vs add_post_meta() 314 * to ensure metadata is added to the revision post and not its parent. 315 */ 316 add_metadata( 'post', $revision_id, $meta_key, wp_slash( $meta_value ) ); 317 } 318 // Save the revisioned meta keys so we know which meta keys were revisioned 319 add_metadata( 'post', $revision_id, '_wp_post_revision_meta_keys', _wp_post_revision_meta_keys() ); 320 274 321 return $revision_id; 275 322 } 276 323 … … 336 383 337 384 $update['ID'] = $revision['post_parent']; 338 385 386 // Restore revisioned meta fields; first get the keys for this revision 387 $metas_revisioned = wp_unslash( get_metadata( 'post', $revision_id, '_wp_post_revision_meta_keys' ) ); 388 389 if ( ! empty( $metas_revisioned[0] ) ) { 390 foreach ( $metas_revisioned[0] as $meta_key ) { 391 // Get the stored meta, not stored === blank 392 $meta_value = get_post_meta( $revision['ID'], $meta_key, true ); 393 // Add slashes to data pulled from the database. 394 update_post_meta( $update['ID'], $meta_key, wp_slash( $meta_value ) ); 395 } 396 } 339 397 $update = wp_slash( $update ); //since data is from db 340 398 341 399 $post_id = wp_update_post( $update ); … … 503 561 $post->post_excerpt = $preview->post_excerpt; 504 562 505 563 add_filter( 'get_the_terms', '_wp_preview_terms_filter', 10, 3 ); 564 add_filter( 'get_post_metadata', '_wp_preview_meta_filter', 10, 4 ); 506 565 507 566 return $post; 508 567 } … … 526 585 } 527 586 528 587 /** 588 * Filters post meta retrieval to get values from the actual autosave post, 589 * and not its parent. 590 * 591 * Filters revisioned meta keys only. 592 * 593 * @access private 594 * @since 4.0.0 595 * 596 * @param mixed $value Meta value to filter. 597 * @param int $object_id Object ID. 598 * @param string $meta_key Meta key to filter a value for. 599 * @param bool $single Whether to return a single value. Default false. 600 * @return mixed Original meta value if the meta key isn't revisioned, the object doesn't exist, 601 * the post type is a revisionm or the post ID doesn't match the object ID. 602 * Otherwise, the revisioned meta value is returned for the preview. 603 */ 604 function _wp_preview_meta_filter( $value, $object_id, $meta_key, $single ) { 605 $post = get_post(); 606 if ( empty( $post ) 607 || $post->ID != $object_id 608 || ! in_array( $meta_key, _wp_post_revision_meta_keys() ) 609 || 'revision' == $post->post_type ) 610 { 611 return $value; 612 } 613 614 // Grab the autosave. 615 $preview = wp_get_post_autosave( $post->ID ); 616 if ( ! is_object( $preview ) ) { 617 return $value; 618 } 619 620 return get_post_meta( $preview->ID, $meta_key, $single ); 621 } 622 623 /** 529 624 * Filters terms lookup to set the post format. 530 625 * 531 626 * @since 3.6.0 -
tests/phpunit/tests/post/revisions.php
385 385 $this->assertEquals( 100, $ok ); 386 386 $this->assertEquals( 0, $reversed ); 387 387 } 388 389 /** 390 * Test the revisions system for storage of meta values 391 * @ticket 20564 392 */ 393 function test_revisions_stores_meta_values() { 394 // Set up a new post 395 $original_post_id = $post_id = $this->factory->post->create(); 396 // And update to store an initial revision 397 wp_update_post( array( 'post_content' => 'some initial content', 'ID' => $post_id ) ); 398 399 // One revision so far 400 $revisions = wp_get_post_revisions( $post_id ); 401 $this->assertCount( 1, $revisions ); 402 /** 403 * First set up a meta value 404 */ 405 406 // Store a custom meta value, which is not revisioned by default 407 update_post_meta( $post_id, 'meta_revision_test', 'original' ); 408 409 // Update the post, storing a revision 410 wp_update_post( array( 'post_content' => 'some more content', 'ID' => $post_id ) ); 411 412 $revisions = wp_get_post_revisions( $post_id ); 413 $this->assertCount( 2, $revisions ); 414 415 416 // Next, store some updated meta values for the same key 417 update_post_meta( $post_id, 'meta_revision_test', 'update1' ); 418 419 // Save the post, changing content to force a revision 420 wp_update_post( array( 'post_content' => 'some updated content', 'ID' => $post_id ) ); 421 422 $revisions = wp_get_post_revisions( $post_id ); 423 $this->assertCount( 3, $revisions ); 424 425 426 /** 427 * Now restore the original revision 428 */ 429 430 // Restore the previous revision 431 $revisions = (Array)wp_get_post_revisions( $post_id ); 432 // Go back two to load the previous revision 433 array_shift( $revisions ); 434 $last_revision = array_shift( $revisions ); 435 // Restore! 436 wp_restore_post_revision( $last_revision->ID ); 437 438 wp_update_post( array( 'ID' => $post_id ) ); 439 $revisions = wp_get_post_revisions( $post_id ); 440 $this->assertCount( 4, $revisions ); 441 442 /** 443 * Check the meta values to verify they are NOT revisioned - they are not revisioned by default 444 */ 445 446 // Custom post meta should NOT be restored, orignal value should not be restored, value still 'update1' 447 $this->assertEquals( 'update1', get_post_meta( $post_id, 'meta_revision_test', true ) ); 448 449 update_post_meta( $post_id, 'meta_revision_test', 'update2' ); 450 451 452 /* 453 * Now test the revisioning of custom meta when enabled by the wp_post_revision_meta_keys filter 454 */ 455 456 // Add the custom field to be revised via the wp_post_revision_meta_keys filter 457 add_filter( 'wp_post_revision_meta_keys', function( $keys ) { 458 $keys[] = 'meta_revision_test'; 459 return $keys; 460 }); 461 462 // Save the post, changing content to force a revision 463 wp_update_post( array( 'post_content' => 'more updated content', 'ID' => $post_id ) ); 464 465 $revisions = wp_get_post_revisions( $post_id ); 466 $this->assertCount( 5, $revisions ); 467 468 // Store custom meta values, which should now be revisioned 469 update_post_meta( $post_id, 'meta_revision_test', 'update3' ); 470 471 /** 472 * Save the post again, custom meta should now be revisioned 473 * 474 * Note that a revision is saved even though there is no change 475 * in post content, becaused the revisioned post_meta has changed 476 * 477 */ 478 wp_update_post( array( 'ID' => $post_id ) ); 479 480 // This revision contains the existing post meta ('update3') 481 $revisions = wp_get_post_revisions( $post_id ); 482 $this->assertCount( 6, $revisions ); 483 484 // Verify that previous post meta is set 485 $this->assertEquals( 'update3', get_post_meta( $post_id, 'meta_revision_test', true ) ); 486 487 // Retore the previous revision 488 $revisions = wp_get_post_revisions( $post_id ); 489 490 // Go back two to load the previous revision 491 array_shift( $revisions ); 492 $last_revision = array_shift( $revisions ); 493 wp_restore_post_revision( $last_revision->ID ); 494 495 // Verify that previous post meta is restored 496 $this->assertEquals( 'update2', get_post_meta( $post_id, 'meta_revision_test', true ) ); 497 498 // Try storing a blank meta 499 update_post_meta( $post_id, 'meta_revision_test', '' ); 500 wp_update_post( array( 'ID' => $post_id ) ); 501 502 update_post_meta( $post_id, 'meta_revision_test', 'update 4' ); 503 wp_update_post( array( 'ID' => $post_id ) ); 504 505 // Retore the previous revision 506 $revisions = wp_get_post_revisions( $post_id ); 507 array_shift( $revisions ); 508 $last_revision = array_shift( $revisions ); 509 wp_restore_post_revision( $last_revision->ID ); 510 511 // Verify that previous post meta is restored 512 $this->assertEquals( '', get_post_meta( $post_id, 'meta_revision_test', true ) ); 513 514 // Test not tracking a key 515 remove_all_filters( 'wp_post_revision_meta_keys' ); 516 517 // Should no longer be revisioned 518 update_post_meta( $post_id, 'meta_revision_test', 'update 5' ); 519 wp_update_post( array( 'ID' => $post_id, 'post_content' => 'changed content' ) ); 520 update_post_meta( $post_id, 'meta_revision_test', 'update 6' ); 521 wp_update_post( array( 'ID' => $post_id, 'post_content' => 'go updated content' ) ); 522 // Retore the previous revision 523 $revisions = wp_get_post_revisions( $post_id ); 524 array_shift( $revisions ); 525 $last_revision = array_shift( $revisions ); 526 wp_restore_post_revision( $last_revision->ID ); 527 528 // Verify that previous post meta is NOT restored 529 $this->assertEquals( 'update 6', get_post_meta( $post_id, 'meta_revision_test', true ) ); 530 531 532 // Cleanup! 533 wp_delete_post( $original_post_id ); 534 535 } 388 536 }