Ticket #20564: 20564.13.diff
File 20564.13.diff, 10.3 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 && get_post_meta( $new_autosave['ID'], $meta_key, true ) != wp_unslash( $_POST[ $meta_key ] ) ) 1530 { 1531 /* 1532 * Use the underlying delete_metadata() and add_metadata() functions 1533 * vs delete_post_meta() and add_post_meta() to make sure we're working 1534 * with the actual revision meta. 1535 */ 1536 delete_metadata( 'post', $new_autosave['ID'], $meta_key ); 1537 if ( ! empty( $_POST[ $meta_key ] ) ) { 1538 add_metadata( 'post', $new_autosave['ID'], $meta_key, $_POST[ $meta_key ] ); 1539 } 1540 } 1541 } 1542 1526 1543 // If the new autosave has the same content as the post, delete the autosave. 1527 1544 $post = get_post( $post_id ); 1528 1545 $autosave_is_different = false; -
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 } 140 169 } 141 142 170 $return = _wp_put_post_revision( $post ); 143 171 144 172 $revisions_to_keep = wp_revisions_to_keep( $post ); … … 242 270 * @return mixed WP_Error or 0 if error, new revision ID if success. 243 271 */ 244 272 function _wp_put_post_revision( $post = null, $autosave = false ) { 273 245 274 if ( is_object($post) ) 246 275 $post = get_object_vars( $post ); 247 276 elseif ( !is_array($post) ) … … 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 … … 260 290 if ( is_wp_error($revision_id) ) 261 291 return $revision_id; 262 292 293 294 263 295 if ( $revision_id ) { 264 296 /** 265 297 * Fires once a revision has been saved. … … 271 303 do_action( '_wp_put_post_revision', $revision_id ); 272 304 } 273 305 306 307 // Save revisioned meta fields. 308 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 309 $meta_value = get_post_meta( $post_id, $meta_key, true ); 310 if ( empty( $meta_value ) ) { 311 continue; 312 } 313 314 /* 315 * Use the underlying add_metadata() function vs add_post_meta() 316 * to ensure metadata is added to the revision post and not its parent. 317 */ 318 add_metadata( 'post', $revision_id, $meta_key, wp_slash( $meta_value ) ); 319 } 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. 387 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 388 $meta_value = get_post_meta( $revision['ID'], $meta_key, true ); 389 if ( empty( $meta_value ) ) { 390 $meta_value = ''; 391 } 392 // Add slashes to data pulled from the database. 393 update_post_meta( $update['ID'], $meta_key, wp_slash( $meta_value ) ); 394 } 395 339 396 $update = wp_slash( $update ); //since data is from db 340 397 341 398 $post_id = wp_update_post( $update ); … … 503 560 $post->post_excerpt = $preview->post_excerpt; 504 561 505 562 add_filter( 'get_the_terms', '_wp_preview_terms_filter', 10, 3 ); 563 add_filter( 'get_post_metadata', '_wp_preview_meta_filter', 10, 4 ); 506 564 507 565 return $post; 508 566 } … … 526 584 } 527 585 528 586 /** 587 * Filters post meta retrieval to get values from the actual autosave post, 588 * and not its parent. 589 * 590 * Filters revisioned meta keys only. 591 * 592 * @access private 593 * @since 4.0.0 594 * 595 * @param mixed $value Meta value to filter. 596 * @param int $object_id Object ID. 597 * @param string $meta_key Meta key to filter a value for. 598 * @param bool $single Whether to return a single value. Default false. 599 * @return mixed Original meta value if the meta key isn't revisioned, the object doesn't exist, 600 * the post type is a revisionm or the post ID doesn't match the object ID. 601 * Otherwise, the revisioned meta value is returned for the preview. 602 */ 603 function _wp_preview_meta_filter( $value, $object_id, $meta_key, $single ) { 604 $post = get_post(); 605 if ( empty( $post ) 606 || $post->ID != $object_id 607 || ! in_array( $meta_key, _wp_post_revision_meta_keys() ) 608 || 'revision' == $post->post_type ) 609 { 610 return $value; 611 } 612 613 // Grab the autosave. 614 $preview = wp_get_post_autosave( $post->ID ); 615 if ( ! is_object( $preview ) ) { 616 return $value; 617 } 618 619 return get_post_meta( $preview->ID, $meta_key, $single ); 620 } 621 622 /** 529 623 * Filters terms lookup to set the post format. 530 624 * 531 625 * @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' => $original_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 491 // Go back two to load the previous revision 492 array_shift( $revisions ); 493 $last_revision = array_shift( $revisions ); 494 wp_restore_post_revision( $last_revision->ID ); 495 496 // Verify that previous post meta is restored 497 $this->assertEquals( 'update2', get_post_meta( $post_id, 'meta_revision_test', true ) ); 498 499 // Cleanup! 500 wp_delete_post( $original_post_id ); 501 502 } 388 503 }