Ticket #20564: 20564-10.diff
File 20564-10.diff, 11.7 KB (added by , 11 years ago) |
---|
-
src/wp-admin/includes/post.php
1350 1350 $new_autosave['ID'] = $old_autosave->ID; 1351 1351 $new_autosave['post_author'] = $post_author; 1352 1352 1353 // Auto-save revisioned meta fields. 1354 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 1355 if ( isset( $_POST[ $meta_key ] ) && get_post_meta( $new_autosave['ID'], $meta_key, true ) != $_POST[ $meta_key ] ) { 1356 // Use the underlying delete_metadata and add_metadata vs delete_post_meta 1357 // and add_post_meta to make sure we're working with the actual revision meta. 1358 delete_metadata( 'post', $new_autosave['ID'], $meta_key ); 1359 if ( ! empty( $_POST[ $meta_key ] ) ) 1360 add_metadata( 'post', $new_autosave['ID'], $meta_key, $_POST[ $meta_key ] ); 1361 } 1362 } 1363 1364 // Save the post format as part of the autosave if different. 1365 if ( isset( $_POST['post_format'] ) && get_post_meta( $new_autosave['ID'], '_revision_post_format', true ) != $_POST['post_format'] ) { 1366 delete_metadata( 'post', $new_autosave['ID'], '_revision_post_format' ); 1367 if ( ! empty( $_POST['post_format'] ) ) 1368 update_metadata( 'post', $new_autosave['ID'], '_revision_post_format', $_POST['post_format'] ); 1369 } 1370 1353 1371 // If the new autosave is the same content as the post, delete the old autosave. 1354 1372 $post = get_post( $post_id ); 1355 1373 $autosave_is_different = false; -
src/wp-includes/js/autosave.js
328 328 (function($){ 329 329 // Returns the data for saving in both localStorage and autosaves to the server 330 330 wp.autosave.getPostData = function() { 331 var ed = typeof tinymce != 'undefined' ? tinymce.activeEditor : null, post_name, parent_id, cats = [],331 var ed = typeof tinymce != 'undefined' ? tinymce.activeEditor : null, post_name, parent_id, post_format, cats = [], 332 332 data = { 333 333 action: 'autosave', 334 334 autosave: true, … … 387 387 if ( $('#auto_draft').val() == '1' ) 388 388 data.auto_draft = '1'; 389 389 390 post_format = $('#post_format').val() || ''; 391 data['post_format'] = post_format == 'standard' ? '' : post_format; 392 393 // Add the post format selected on the edit screen. 394 $('#post-formats-select').find('input[name="post_format"]').each( function(i, field) { 395 data[ field.name ] = $(field).is(':checked') || ''; 396 }); 397 390 398 return data; 391 399 }; 392 400 -
src/wp-includes/revision.php
28 28 if ( !$fields ) { 29 29 // Allow these to be versioned 30 30 $fields = array( 31 'post_title' => __( 'Title' ),31 'post_title' => __( 'Title' ), 32 32 'post_content' => __( 'Content' ), 33 33 'post_excerpt' => __( 'Excerpt' ), 34 34 ); 35 35 36 // Runs only once 37 $fields = apply_filters( '_wp_post_revision_fields', $fields ); 36 /** 37 * Filter the list of post fields that are revisioned. 38 * 39 * @since 3.6.0 40 * 41 * @param array $fields An array of fields to be be revisioned. 42 * 43 */ 44 $fields = apply_filters( '_wp_post_revision_fields', $fields ); // Runs only once 38 45 39 46 // WP uses these internally either in versioning or elsewhere - they cannot be versioned 40 47 foreach ( array( 'ID', 'post_name', 'post_parent', 'post_date', 'post_date_gmt', 'post_status', 'post_type', 'comment_count', 'post_author' ) as $protect ) … … 59 66 } 60 67 61 68 /** 69 * Determines which post meta fields are revisioned. 70 * 71 * @since 3.8.0 72 * 73 * @access private 74 * @return array An array of meta keys that should be revisioned. 75 * 76 */ 77 function _wp_post_revision_meta_keys() { 78 // By default, revision the post format meta values 79 $keys = array( 80 '_wp_format_url', 81 '_wp_format_quote', 82 '_wp_format_quote_source', 83 '_wp_format_image', 84 '_wp_format_gallery', 85 '_wp_format_audio', 86 '_wp_format_video', 87 ); 88 89 /** 90 * Filter the list of post meta keys that are revisioned. 91 * 92 * @since 3.8.0 93 * 94 * @param array $keys An array of fields to be be revisioned. 95 * 96 */ 97 return apply_filters( 'wp_post_revision_meta_keys', $keys ); 98 } 99 100 /** 62 101 * Saves an already existing post as a post revision. 63 102 * 64 103 * Typically used immediately after post updates. … … 102 141 if ( isset( $last_revision ) && apply_filters( 'wp_save_post_revision_check_for_changes', true, $last_revision, $post ) ) { 103 142 $post_has_changed = false; 104 143 144 // Check whether revisioned fields have been changed 105 145 foreach ( array_keys( _wp_post_revision_fields() ) as $field ) { 106 146 if ( normalize_whitespace( $post->$field ) != normalize_whitespace( $last_revision->$field ) ) { 107 147 $post_has_changed = true; 108 148 break; 109 149 } 110 150 } 111 //don't save revision if post unchanged 151 152 // Check whether revisioned meta fields have changed 153 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 154 if ( get_post_meta( $post->ID, $meta_key ) != get_post_meta( $last_revision->ID, $meta_key ) ) { 155 $post_has_changed = true; 156 break; 157 } 158 } 159 160 // Check whether the post format has changed 161 if ( get_post_format( $post->ID ) != get_post_meta( $last_revision->ID, '_revision_post_format', true ) ) 162 $post_has_changed = true; 163 164 // Don't save revision if post unchanged 112 165 if( ! $post_has_changed ) 113 166 return; 114 167 } … … 240 293 if ( $revision_id ) 241 294 do_action( '_wp_put_post_revision', $revision_id ); 242 295 243 return $revision_id; 244 } 296 // Save revisioned meta fields. 297 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 298 $meta_value = get_post_meta( $post_id, $meta_key, true ); 299 if ( empty( $meta_value ) ) 300 continue; 301 // Use the underlying add_metadata vs add_post_meta to make sure 302 // metadata is added to the revision post and not its parent. 303 add_metadata( 'post', $revision_id, $meta_key, wp_slash( $meta_value ) ); 304 } 305 // Save the post format 306 if ( $post_format = get_post_format( $post_id ) ) 307 add_metadata( 'post', $revision_id, '_revision_post_format', $post_format ); 245 308 309 return $revision_id; 310 } 311 246 312 /** 247 313 * Gets a post revision. 248 314 * … … 308 374 309 375 $update['ID'] = $revision['post_parent']; 310 376 377 // Restore revisioned meta fields. 378 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 379 $meta_value = get_post_meta( $revision['ID'], $meta_key, true ); 380 if ( empty( $meta_value ) ) 381 $meta_value = ''; 382 // Add slashes to data pulled from the db 383 update_post_meta( $update['ID'], $meta_key, wp_slash( $meta_value ) ); 384 } 385 311 386 $update = wp_slash( $update ); //since data is from db 387 // Restore post format 388 set_post_format( $update['ID'], get_post_meta( $revision['ID'], '_revision_post_format', true ) ); 312 389 390 // Restore revisioned meta fields. 391 foreach ( _wp_post_revision_meta_keys() as $meta_key ) { 392 delete_post_meta( $update['ID'], $meta_key ); 393 $meta_values = get_post_meta( $revision['ID'], $meta_key ); 394 if ( false === $meta_values ) 395 continue; 396 397 foreach ( $meta_values as $meta_value ) 398 add_post_meta( $update['ID'], $meta_key, $meta_value ); 399 } 400 313 401 $post_id = wp_update_post( $update ); 314 402 if ( ! $post_id || is_wp_error( $post_id ) ) 315 403 return $post_id; … … 449 537 $post->post_excerpt = $preview->post_excerpt; 450 538 451 539 add_filter( 'get_the_terms', '_wp_preview_terms_filter', 10, 3 ); 540 add_filter( 'get_post_metadata', '_wp_preview_meta_filter', 10, 4 ); 452 541 453 542 return $post; 454 543 } … … 472 561 } 473 562 474 563 /** 564 * Filters post meta retrieval to get values from the actual autosave post, 565 * and not its parent. Filters revisioned meta keys only. 566 * 567 * @since 3.6.0 568 * @access private 569 */ 570 function _wp_preview_meta_filter( $value, $object_id, $meta_key, $single ) { 571 $post = get_post(); 572 if ( empty( $post ) || $post->ID != $object_id || ! in_array( $meta_key, _wp_post_revision_meta_keys() ) || 'revision' == $post->post_type ) 573 return $value; 574 $preview = wp_get_post_autosave( $post->ID ); 575 if ( ! is_object( $preview ) ) 576 return $value; 577 return get_post_meta( $preview->ID, $meta_key, $single ); 578 } 579 580 /** 475 581 * Filters terms lookup to set the post format. 476 582 * 477 583 * @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 & post format 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 /** 353 * First set up some meta values, one custom and one _wp_format_gallery (one of the default wp_post_revision_meta_keys) 354 */ 355 356 // Store a custom meta value, which is not revisioned by default 357 update_post_meta( $post_id, 'meta_revision_test', 'original' ); 358 359 // Store a _wp_format_ meta, which is revisioned by defeault 360 update_post_meta( $post_id, '_wp_format_gallery', 'active' ); 361 362 // Update the post, storing a revision 363 wp_update_post( array( 'post_content' => 'some more content', 'ID' => $post_id ) ); 364 365 /** 366 * Next, store some updated meta values for the same keys 367 */ 368 369 update_post_meta( $post_id, 'meta_revision_test', 'update1' ); 370 update_post_meta( $post_id, '_wp_format_gallery', 'inactive' ); 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 /** 376 * Now restore the original revision 377 */ 378 379 // Get all the revisions 380 $revisions = (Array)wp_get_post_revisions( $post_id ); 381 382 // Go back two revisions (the 1st revision matches the current post) 383 $last_revision = array_pop( $revisions ); 384 $last_revision = array_pop( $revisions ); 385 386 // Restore! 387 wp_restore_post_revision( $last_revision->ID ); 388 389 /** 390 * Check the meta values to see if they are revisioned 391 */ 392 393 // Custom post met should NOT be restored, orignal value should not be restored, value still 'update1' 394 $this->assertEquals( 'update1', get_post_meta( $post_id, 'meta_revision_test', true ) ); 395 396 // _wp_format_ metas should be revisioned, original value should be restored 397 $this->assertEquals( 'active', get_post_meta( $post_id, '_wp_format_gallery', true ) ); 398 399 /** 400 * Now test the revisioning of custom meta when enabled by the 401 */ 402 403 // Add the custom field to be revised via the wp_post_revision_meta_keys filter wp_post_revision_meta_keys filter 404 add_filter( 'wp_post_revision_meta_keys', function( $keys ) { 405 $keys[] = 'meta_revision_test'; 406 return $keys; 407 }); 408 409 /** 410 * Save new meta in the revisioned field 411 */ 412 413 // Save the post again, custom meta should now be revisioned - note no change in content, revision still saved 414 wp_update_post( array( 'ID' => $post_id ) ); 415 416 // Store custom meta values, which should now be revisioned 417 update_post_meta( $post_id, 'meta_revision_test', 'update2' ); 418 419 // Save the post again 420 wp_update_post( array( 'ID' => $post_id ) ); 421 422 // Retore the previous revision 423 $revisions = wp_get_post_revisions( $post_id ); 424 425 // Go back two 426 $last_revision = array_pop( $revisions ); 427 $last_revision = array_pop( $revisions ); 428 wp_restore_post_revision( $last_revision->ID ); 429 430 $this->assertEquals( 'update1', get_post_meta( $post_id, 'meta_revision_test', true ) ); 431 432 // Cleanup! 433 wp_delete_post( $original_post_id ); 434 435 436 } 341 437 }