Ticket #20564: 20564.12.diff
File 20564.12.diff, 9.9 KB (added by , 10 years ago) |
---|
-
src/wp-admin/includes/post.php
1527 1527 $new_autosave['ID'] = $old_autosave->ID; 1528 1528 $new_autosave['post_author'] = $post_author; 1529 1529 1530 // Auto-save revisioned meta fields. 1531 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 1532 if ( isset( $_POST[ $meta_key ] ) 1533 && get_post_meta( $new_autosave['ID'], $meta_key, true ) != wp_unslash( $_POST[ $meta_key ] ) ) 1534 { 1535 /* 1536 * Use the underlying delete_metadata() and add_metadata() functions 1537 * vs delete_post_meta() and add_post_meta() to make sure we're working 1538 * with the actual revision meta. 1539 */ 1540 delete_metadata( 'post', $new_autosave['ID'], $meta_key ); 1541 if ( ! empty( $_POST[ $meta_key ] ) ) { 1542 add_metadata( 'post', $new_autosave['ID'], $meta_key, $_POST[ $meta_key ] ); 1543 } 1544 } 1545 } 1546 1530 1547 // If the new autosave has the same content as the post, delete the autosave. 1531 1548 $post = get_post( $post_id ); 1532 1549 $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 } … … 243 272 * @return mixed WP_Error or 0 if error, new revision ID if success. 244 273 */ 245 274 function _wp_put_post_revision( $post = null, $autosave = false ) { 275 246 276 if ( is_object($post) ) 247 277 $post = get_object_vars( $post ); 248 278 elseif ( !is_array($post) ) … … 262 292 if ( is_wp_error($revision_id) ) 263 293 return $revision_id; 264 294 295 296 265 297 if ( $revision_id ) { 266 298 /** 267 299 * Fires once a revision has been saved. … … 273 305 do_action( '_wp_put_post_revision', $revision_id ); 274 306 } 275 307 308 309 // Save revisioned meta fields. 310 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 311 $meta_value = get_post_meta( $post_id, $meta_key, true ); 312 if ( empty( $meta_value ) ) { 313 continue; 314 } 315 316 /* 317 * Use the underlying add_metadata() function vs add_post_meta() 318 * to ensure metadata is added to the revision post and not its parent. 319 */ 320 add_metadata( 'post', $revision_id, $meta_key, wp_slash( $meta_value ) ); 321 } 322 276 323 return $revision_id; 277 324 } 278 325 … … 338 385 339 386 $update['ID'] = $revision['post_parent']; 340 387 388 // Restore revisioned meta fields. 389 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 390 $meta_value = get_post_meta( $revision['ID'], $meta_key, true ); 391 if ( empty( $meta_value ) ) { 392 $meta_value = ''; 393 } 394 // Add slashes to data pulled from the database. 395 update_post_meta( $update['ID'], $meta_key, wp_slash( $meta_value ) ); 396 } 397 341 398 $update = wp_slash( $update ); //since data is from db 342 399 343 400 $post_id = wp_update_post( $update ); … … 505 562 $post->post_excerpt = $preview->post_excerpt; 506 563 507 564 add_filter( 'get_the_terms', '_wp_preview_terms_filter', 10, 3 ); 565 add_filter( 'get_post_metadata', '_wp_preview_meta_filter', 10, 4 ); 508 566 509 567 return $post; 510 568 } … … 528 586 } 529 587 530 588 /** 589 * Filters post meta retrieval to get values from the actual autosave post, 590 * and not its parent. 591 * 592 * Filters revisioned meta keys only. 593 * 594 * @access private 595 * @since 4.0.0 596 * 597 * @param mixed $value Meta value to filter. 598 * @param int $object_id Object ID. 599 * @param string $meta_key Meta key to filter a value for. 600 * @param bool $single Whether to return a single value. Default false. 601 * @return mixed Original meta value if the meta key isn't revisioned, the object doesn't exist, 602 * the post type is a revisionm or the post ID doesn't match the object ID. 603 * Otherwise, the revisioned meta value is returned for the preview. 604 */ 605 function _wp_preview_meta_filter( $value, $object_id, $meta_key, $single ) { 606 $post = get_post(); 607 if ( empty( $post ) 608 || $post->ID != $object_id 609 || ! in_array( $meta_key, _wp_post_revision_meta_keys() ) 610 || 'revision' == $post->post_type ) 611 { 612 return $value; 613 } 614 615 // Grab the autosave. 616 $preview = wp_get_post_autosave( $post->ID ); 617 if ( ! is_object( $preview ) ) { 618 return $value; 619 } 620 621 return get_post_meta( $preview->ID, $meta_key, $single ); 622 } 623 624 /** 531 625 * Filters terms lookup to set the post format. 532 626 * 533 627 * @since 3.6.0 -
tests/phpunit/tests/post/revisions.php
338 338 $this->assertTrue( user_can( $author_user_id, 'read_post', $revision->ID ) ); 339 339 } 340 340 } 341 342 /** 343 * Test the revisions system for storage of meta values 344 * @ticket 20564 345 */ 346 function test_revisions_stores_meta_values() { 347 // Set up a new post 348 $original_post_id = $post_id = $this->factory->post->create(); 349 // And update to store an initial revision 350 wp_update_post( array( 'post_content' => 'some initial content', 'ID' => $post_id ) ); 351 352 // One revision so far 353 $revisions = wp_get_post_revisions( $post_id ); 354 $this->assertCount( 1, $revisions ); 355 /** 356 * First set up a meta value 357 */ 358 359 // Store a custom meta value, which is not revisioned by default 360 update_post_meta( $post_id, 'meta_revision_test', 'original' ); 361 362 // Update the post, storing a revision 363 wp_update_post( array( 'post_content' => 'some more content', 'ID' => $post_id ) ); 364 365 $revisions = wp_get_post_revisions( $post_id ); 366 $this->assertCount( 2, $revisions ); 367 368 369 // Next, store some updated meta values for the same key 370 update_post_meta( $post_id, 'meta_revision_test', 'update1' ); 371 372 // Save the post, changing content to force a revision 373 wp_update_post( array( 'post_content' => 'some updated content', 'ID' => $post_id ) ); 374 375 $revisions = wp_get_post_revisions( $post_id ); 376 $this->assertCount( 3, $revisions ); 377 378 379 /** 380 * Now restore the original revision 381 */ 382 383 // Restore the previous revision 384 $revisions = (Array)wp_get_post_revisions( $post_id ); 385 // Go back two to load the previous revision 386 array_pop( $revisions ); 387 $last_revision = array_pop( $revisions ); 388 389 // Restore! 390 wp_restore_post_revision( $last_revision->ID ); 391 392 wp_update_post( array( 'ID' => $post_id ) ); 393 $revisions = wp_get_post_revisions( $post_id ); 394 $this->assertCount( 5, $revisions ); 395 396 /** 397 * Check the meta values to verify they are NOT revisioned - they are not revisioned by default 398 */ 399 400 // Custom post meta should NOT be restored, orignal value should not be restored, value still 'update1' 401 $this->assertEquals( 'update1', get_post_meta( $post_id, 'meta_revision_test', true ) ); 402 403 update_post_meta( $post_id, 'meta_revision_test', 'update2' ); 404 405 406 /* 407 * Now test the revisioning of custom meta when enabled by the wp_post_revision_meta_keys filter 408 */ 409 410 // Add the custom field to be revised via the wp_post_revision_meta_keys filter 411 add_filter( 'wp_post_revision_meta_keys', function( $keys ) { 412 $keys[] = 'meta_revision_test'; 413 return $keys; 414 }); 415 416 // Save the post, changing content to force a revision 417 wp_update_post( array( 'post_content' => 'more updated content', 'ID' => $post_id ) ); 418 419 $revisions = wp_get_post_revisions( $post_id ); 420 $this->assertCount( 6, $revisions ); 421 422 // Store custom meta values, which should now be revisioned 423 update_post_meta( $post_id, 'meta_revision_test', 'update3' ); 424 425 /** 426 * Save the post again, custom meta should now be revisioned 427 * 428 * Note that a revision is saved even though there is no change 429 * in post content, becaused the revisioned post_meta has changed 430 * 431 */ 432 wp_update_post( array( 'ID' => $post_id ) ); 433 434 // Tthis revision contains the existing post meta ('update2') 435 $revisions = wp_get_post_revisions( $post_id ); 436 $this->assertCount( 7, $revisions ); 437 438 // Verify that previous post meta is set 439 $this->assertEquals( 'update3', get_post_meta( $post_id, 'meta_revision_test', true ) ); 440 441 // Retore the previous revision 442 $revisions = wp_get_post_revisions( $post_id ); 443 444 445 // Go back two to load the previous revision 446 array_pop( $revisions ); 447 $last_revision = array_pop( $revisions ); 448 wp_restore_post_revision( $last_revision->ID ); 449 450 // Verify that previous post meta is restored 451 $this->assertEquals( 'update2', get_post_meta( $post_id, 'meta_revision_test', true ) ); 452 453 // Cleanup! 454 wp_delete_post( $original_post_id ); 455 456 } 341 457 }