Ticket #20564: 20564.24.diff
File 20564.24.diff, 48.7 KB (added by , 20 months ago) |
---|
-
src/wp-admin/includes/post.php
diff --git src/wp-admin/includes/post.php src/wp-admin/includes/post.php index ed73b8ff5f..4bc92d1e4c 100644
function wp_create_post_autosave( $post_data ) { 1961 1961 * @param array $new_autosave Post array - the autosave that is about to be saved. 1962 1962 */ 1963 1963 do_action( 'wp_creating_autosave', $new_autosave ); 1964 1964 wp_autosave_post_revisioned_meta_fields( $new_autosave ); 1965 1965 return wp_update_post( $new_autosave ); 1966 1966 } 1967 1967 … … function wp_create_post_autosave( $post_data ) { 1969 1969 $post_data = wp_unslash( $post_data ); 1970 1970 1971 1971 // Otherwise create the new autosave as a special post revision. 1972 return _wp_put_post_revision( $post_data, true ); 1972 $revision = _wp_put_post_revision( $post_data, true ); 1973 1974 // Update the revisioned meta data as well. 1975 wp_autosave_post_revisioned_meta_fields( $revision ); 1976 return $revision; 1977 } 1978 1979 /** 1980 * Autosave the revisioned meta fields. 1981 * 1982 * Iterates thru the revisioned meta fields and checks each to see if they are set, 1983 * and have a changed value. If so, the meta value is saved and attached to the autosave. 1984 * 1985 * @since 6.4.0 1986 * 1987 * @param Post object $new_autosave The new post being autosaved. 1988 */ 1989 function wp_autosave_post_revisioned_meta_fields( $new_autosave ) { 1990 /* 1991 * The post data arrives as either $_POST['data']['wp_autosave'] or the $_POST 1992 * itself. This sets $posted_data to the correct variable. 1993 * 1994 * Ignoring sanitization to avoid altering meta. Ignoring the nonce check because 1995 * this is hooked on inner core hooks where a valid nonce was already checked. 1996 * 1997 * @phpcs:disable WordPress.Security 1998 */ 1999 $posted_data = isset( $_POST['data']['wp_autosave'] ) ? $_POST['data']['wp_autosave'] : $_POST; 2000 // phpcs:enable 2001 2002 /* 2003 * Go thru the revisioned meta keys and save them as part of the autosave, if 2004 * the meta key is part of the posted data, the meta value is not blank and 2005 * the the meta value has changes from the last autosaved value. 2006 */ 2007 foreach ( wp_post_revision_meta_keys() as $meta_key ) { 2008 2009 if ( 2010 isset( $posted_data[ $meta_key ] ) && 2011 get_post_meta( $new_autosave['ID'], $meta_key, true ) !== wp_unslash( $posted_data[ $meta_key ] ) 2012 ) { 2013 /* 2014 * Use the underlying delete_metadata() and add_metadata() functions 2015 * vs delete_post_meta() and add_post_meta() to make sure we're working 2016 * with the actual revision meta. 2017 */ 2018 delete_metadata( 'post', $new_autosave['ID'], $meta_key ); 2019 2020 /* 2021 * One last check to ensure meta value not empty(). 2022 */ 2023 if ( ! empty( $posted_data[ $meta_key ] ) ) { 2024 /* 2025 * Add the revisions meta data to the autosave. 2026 */ 2027 add_metadata( 'post', $new_autosave['ID'], $meta_key, $posted_data[ $meta_key ] ); 2028 } 2029 } 2030 } 1973 2031 } 1974 2032 1975 2033 /** -
src/wp-includes/blocks/footnotes.php
diff --git src/wp-includes/blocks/footnotes.php src/wp-includes/blocks/footnotes.php index bd7734d7d0..5f57890956 100644
function register_block_core_footnotes() { 68 68 $post_type, 69 69 'footnotes', 70 70 array( 71 'show_in_rest' => true, 72 'single' => true, 73 'type' => 'string', 71 'show_in_rest' => true, 72 'single' => true, 73 'type' => 'string', 74 'revisions_enabled' => true, 74 75 ) 75 76 ); 76 77 } … … function register_block_core_footnotes() { 83 84 } 84 85 add_action( 'init', 'register_block_core_footnotes' ); 85 86 86 /**87 * Saves the footnotes meta value to the revision.88 *89 * @since 6.3.090 *91 * @param int $revision_id The revision ID.92 */93 function wp_save_footnotes_meta( $revision_id ) {94 $post_id = wp_is_post_revision( $revision_id );95 96 if ( $post_id ) {97 $footnotes = get_post_meta( $post_id, 'footnotes', true );98 99 if ( $footnotes ) {100 // Can't use update_post_meta() because it doesn't allow revisions.101 update_metadata( 'post', $revision_id, 'footnotes', $footnotes );102 }103 }104 }105 add_action( 'wp_after_insert_post', 'wp_save_footnotes_meta' );106 107 /**108 * Keeps track of the revision ID for "rest_after_insert_{$post_type}".109 *110 * @since 6.3.0111 *112 * @global int $wp_temporary_footnote_revision_id The footnote revision ID.113 *114 * @param int $revision_id The revision ID.115 */116 function wp_keep_footnotes_revision_id( $revision_id ) {117 global $wp_temporary_footnote_revision_id;118 $wp_temporary_footnote_revision_id = $revision_id;119 }120 add_action( '_wp_put_post_revision', 'wp_keep_footnotes_revision_id' );121 122 /**123 * This is a specific fix for the REST API. The REST API doesn't update124 * the post and post meta in one go (through `meta_input`). While it125 * does fix the `wp_after_insert_post` hook to be called correctly after126 * updating meta, it does NOT fix hooks such as post_updated and127 * save_post, which are normally also fired after post meta is updated128 * in `wp_insert_post()`. Unfortunately, `wp_save_post_revision` is129 * added to the `post_updated` action, which means the meta is not130 * available at the time, so we have to add it afterwards through the131 * `"rest_after_insert_{$post_type}"` action.132 *133 * @since 6.3.0134 *135 * @global int $wp_temporary_footnote_revision_id The footnote revision ID.136 *137 * @param WP_Post $post The post object.138 */139 function wp_add_footnotes_revisions_to_post_meta( $post ) {140 global $wp_temporary_footnote_revision_id;141 142 if ( $wp_temporary_footnote_revision_id ) {143 $revision = get_post( $wp_temporary_footnote_revision_id );144 145 if ( ! $revision ) {146 return;147 }148 149 $post_id = $revision->post_parent;150 151 // Just making sure we're updating the right revision.152 if ( $post->ID === $post_id ) {153 $footnotes = get_post_meta( $post_id, 'footnotes', true );154 155 if ( $footnotes ) {156 // Can't use update_post_meta() because it doesn't allow revisions.157 update_metadata( 'post', $wp_temporary_footnote_revision_id, 'footnotes', $footnotes );158 }159 }160 }161 }162 163 foreach ( array( 'post', 'page' ) as $post_type ) {164 add_action( "rest_after_insert_{$post_type}", 'wp_add_footnotes_revisions_to_post_meta' );165 }166 167 /**168 * Restores the footnotes meta value from the revision.169 *170 * @since 6.3.0171 *172 * @param int $post_id The post ID.173 * @param int $revision_id The revision ID.174 */175 function wp_restore_footnotes_from_revision( $post_id, $revision_id ) {176 $footnotes = get_post_meta( $revision_id, 'footnotes', true );177 178 if ( $footnotes ) {179 update_post_meta( $post_id, 'footnotes', $footnotes );180 } else {181 delete_post_meta( $post_id, 'footnotes' );182 }183 }184 add_action( 'wp_restore_post_revision', 'wp_restore_footnotes_from_revision', 10, 2 );185 186 87 /** 187 88 * Adds the footnotes field to the revision. 188 89 * … … add_filter( '_wp_post_revision_fields', 'wp_add_footnotes_to_revision' ); 209 110 * @return string The field value. 210 111 */ 211 112 function wp_get_footnotes_from_revision( $revision_field, $field, $revision ) { 212 return get_metadata( 'post', $revision->ID, $field, true ); 113 $footnotes = json_decode( get_metadata( 'post', $revision->ID, $field, true ) ); 114 if ( empty( $footnotes ) ) { 115 return $revision_field; 116 } 117 $footnotes_html = ''; 118 $x = 1; 119 foreach( $footnotes as $footnote ) { 120 $footnotes_html .= sprintf( 121 "%s. %s\n", 122 $x++, 123 $footnote->content 124 ); 125 } 126 return $footnotes_html; 213 127 } 214 128 add_filter( '_wp_post_revision_field_footnotes', 'wp_get_footnotes_from_revision', 10, 3 ); 215 129 -
src/wp-includes/default-filters.php
diff --git src/wp-includes/default-filters.php src/wp-includes/default-filters.php index bf39f29b4d..666b30368b 100644
add_action( 'init', 'wp_register_persisted_preferences_meta' ); 719 719 // CPT wp_block custom postmeta field. 720 720 add_action( 'init', 'wp_create_initial_post_meta' ); 721 721 722 // Including revisioned meta when considering whether a post revision has changed. 723 add_filter( 'wp_save_post_revision_post_has_changed', 'wp_check_revisioned_meta_fields_have_changed', 10, 3 ); 724 725 // Save revisioned post meta immediately after a revision is saved 726 add_action( '_wp_put_post_revision', 'wp_save_revisioned_meta_fields', 10, 2 ); 727 722 728 unset( $filter, $action ); -
src/wp-includes/meta.php
diff --git src/wp-includes/meta.php src/wp-includes/meta.php index 0b9f08544e..f4ea49aa4d 100644
function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = 1367 1367 * @since 4.9.8 The `$object_subtype` argument was added to the arguments array. 1368 1368 * @since 5.3.0 Valid meta types expanded to include "array" and "object". 1369 1369 * @since 5.5.0 The `$default` argument was added to the arguments array. 1370 * @since 6.4.0 The `$revisions_enabled` argument was added to the arguments array. 1370 1371 * 1371 1372 * @param string $object_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', 1372 1373 * or any other object type with an associated meta table. … … function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = 1392 1393 * support for custom fields for registered meta to be accessible via REST. 1393 1394 * When registering complex meta values this argument may optionally be an 1394 1395 * array with 'schema' or 'prepare_callback' keys instead of a boolean. 1396 * @type bool $revisions_enabled Whether to enable revisions support for this meta_key. 1395 1397 * } 1396 1398 * @param string|array $deprecated Deprecated. Use `$args` instead. 1397 1399 * @return bool True if the meta key was successfully registered in the global array, false if not. … … function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = 1400 1402 */ 1401 1403 function register_meta( $object_type, $meta_key, $args, $deprecated = null ) { 1402 1404 global $wp_meta_keys; 1405 global $wp_revisioned_meta_keys; 1403 1406 1404 1407 if ( ! is_array( $wp_meta_keys ) ) { 1405 1408 $wp_meta_keys = array(); 1406 1409 } 1407 1410 1411 if ( ! is_array( $wp_revisioned_meta_keys ) ) { 1412 $wp_revisioned_meta_keys = array(); 1413 } 1414 1408 1415 $defaults = array( 1409 1416 'object_subtype' => '', 1410 1417 'type' => 'string', … … function register_meta( $object_type, $meta_key, $args, $deprecated = null ) { 1414 1421 'sanitize_callback' => null, 1415 1422 'auth_callback' => null, 1416 1423 'show_in_rest' => false, 1424 'revisions_enabled' => false, 1417 1425 ); 1418 1426 1419 1427 // There used to be individual args for sanitize and auth callbacks. … … function register_meta( $object_type, $meta_key, $args, $deprecated = null ) { 1459 1467 } 1460 1468 } 1461 1469 1470 // Store the revisioned meta fields. 1471 if ( isset( $args['revisions_enabled'] ) && $args['revisions_enabled'] && ! in_array( $meta_key, $wp_revisioned_meta_keys ) ) { 1472 array_push( $wp_revisioned_meta_keys, $meta_key ); 1473 } 1474 1462 1475 $object_subtype = ! empty( $args['object_subtype'] ) ? $args['object_subtype'] : ''; 1463 1476 1464 1477 // If `auth_callback` is not provided, fall back to `is_protected_meta()`. -
src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
diff --git src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php index 4ec972347f..86a41b0e0d 100644
class WP_REST_Posts_Controller extends WP_REST_Controller { 673 673 ); 674 674 } 675 675 676 // Don't save the post meta revision because they aren't stored yet. 677 remove_action( '_wp_put_post_revision', 'wp_save_revisioned_meta_fields', 10, 2 ); 678 676 679 $post_id = wp_insert_post( wp_slash( (array) $prepared_post ), true, false ); 677 680 678 681 if ( is_wp_error( $post_id ) ) { … … class WP_REST_Posts_Controller extends WP_REST_Controller { 743 746 } 744 747 } 745 748 749 // Update any revisioned meta. 750 $revisions = wp_get_post_revisions( $post_id, array( 'posts_per_page' => 1 ) ); 751 if ( ! empty( $revisions ) ) { 752 $revision = array_shift( $revisions ); 753 wp_save_revisioned_meta_fields( $revision->ID, $post_id ); 754 } 755 746 756 $post = get_post( $post_id ); 747 757 $fields_update = $this->update_additional_fields_for_object( $post, $request ); 748 758 … … class WP_REST_Posts_Controller extends WP_REST_Controller { 876 886 ); 877 887 } 878 888 889 // Don't save the post meta revision because they aren't stored yet. 890 remove_action( '_wp_put_post_revision', 'wp_save_revisioned_meta_fields', 10, 2 ); 891 879 892 // Convert the post object to an array, otherwise wp_update_post() will expect non-escaped input. 880 893 $post_id = wp_update_post( wp_slash( (array) $post ), true, false ); 881 894 … … class WP_REST_Posts_Controller extends WP_REST_Controller { 928 941 return $meta_update; 929 942 } 930 943 } 944 // Update any revisioned meta. 945 $revisions = wp_get_post_revisions( $post_id, array( 'posts_per_page' => 1 ) ); 946 if ( ! empty( $revisions ) ) { 947 $revision = array_shift( $revisions ); 948 wp_save_revisioned_meta_fields( $revision->ID, $post_id ); 949 } 931 950 932 951 $post = get_post( $post_id ); 933 952 $fields_update = $this->update_additional_fields_for_object( $post, $request ); -
src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
diff --git src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php index 6fde5f13f5..31e3d506ea 100644
class WP_REST_Revisions_Controller extends WP_REST_Controller { 24 24 */ 25 25 private $parent_post_type; 26 26 27 /** 28 * Instance of a revision meta fields object. 29 * 30 * @since 4.7.0 31 * @var WP_REST_Revision_Meta_Fields 32 */ 33 protected $meta; 34 27 35 /** 28 36 * Parent controller. 29 37 * … … class WP_REST_Revisions_Controller extends WP_REST_Controller { 60 68 $this->rest_base = 'revisions'; 61 69 $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; 62 70 $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; 71 $this->meta = new WP_REST_Revision_Meta_Fields( 'revision' ); 63 72 } 64 73 65 74 /** … … class WP_REST_Revisions_Controller extends WP_REST_Controller { 619 628 ); 620 629 } 621 630 631 if ( rest_is_field_included( 'meta', $fields ) ) { 632 $data['meta'] = $this->meta->get_value( $post->ID, $request ); 633 } 634 622 635 $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; 623 636 $data = $this->add_additional_fields_to_object( $data, $request ); 624 637 $data = $this->filter_response_by_context( $data, $context ); … … class WP_REST_Revisions_Controller extends WP_REST_Controller { 752 765 $schema['properties']['guid'] = $parent_schema['properties']['guid']; 753 766 } 754 767 768 $schema['properties']['meta'] = $this->meta->get_field_schema(); 769 755 770 $this->schema = $schema; 756 771 757 772 return $this->add_additional_fields_schema( $this->schema ); -
new file src/wp-includes/rest-api/fields/class-wp-rest-revision-meta-fields.php
diff --git src/wp-includes/rest-api/fields/class-wp-rest-revision-meta-fields.php src/wp-includes/rest-api/fields/class-wp-rest-revision-meta-fields.php new file mode 100644 index 0000000000..248e06e79b
- + 1 <?php 2 /** 3 * REST API: WP_REST_Revision_Meta_Fields class 4 * 5 * @package WordPress 6 * @subpackage REST_API 7 * @since 6.4.0 8 */ 9 10 /** 11 * Core class used to manage meta values for revisions via the REST API. 12 * 13 * @since 6.4.0 14 * 15 * @see WP_REST_Meta_Fields 16 */ 17 class WP_REST_Revision_Meta_Fields extends WP_REST_Meta_Fields { 18 19 /** 20 * Revision type to register fields for. 21 * 22 * @since 6.4.0 23 * @var string 24 */ 25 protected $post_type; 26 27 /** 28 * Constructor. 29 * 30 * @since 6.4.0 31 * 32 * @param string $post_type Revision type to register fields for. 33 */ 34 public function __construct( $post_type ) { 35 $this->post_type = $post_type; 36 } 37 38 /** 39 * Retrieves the post meta type. 40 * 41 * @since 6.4.0 42 * 43 * @return string The meta type. 44 */ 45 protected function get_meta_type() { 46 return 'revision'; 47 } 48 49 /** 50 * Retrieves the post meta subtype. 51 * 52 * @since 6.4.0 53 * 54 * @return string Subtype for the meta type, or empty string if no specific subtype. 55 */ 56 protected function get_meta_subtype() { 57 return $this->post_type; 58 } 59 60 /** 61 * Retrieves the type for register_rest_field(). 62 * 63 * @since 6.4.0 64 * 65 * @see register_rest_field() 66 * 67 * @return string The REST field type. 68 */ 69 public function get_rest_field_type() { 70 return $this->post_type; 71 } 72 73 /** 74 * Retrieves the meta field value. 75 * 76 * @since 4.7.0 77 * 78 * @param int $object_id Object ID to fetch meta for. 79 * @param WP_REST_Request $request Full details about the request. 80 * @return array Array containing the meta values keyed by name. 81 */ 82 public function get_value( $object_id, $request ) { 83 $data = get_post_meta( $object_id ); 84 return $data; 85 } 86 87 /** 88 * Retrieves raw metadata value for the specified object. 89 * 90 * @since 5.5.0 91 * 92 * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', 93 * or any other object type with an associated meta table. 94 * @param int $object_id ID of the object metadata is for. 95 * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for 96 * the specified object. Default empty string. 97 * @param bool $single Optional. If true, return only the first value of the specified `$meta_key`. 98 * This parameter has no effect if `$meta_key` is not specified. Default false. 99 * @return mixed An array of values if `$single` is false. 100 * The value of the meta field if `$single` is true. 101 * False for an invalid `$object_id` (non-numeric, zero, or negative value), 102 * or if `$meta_type` is not specified. 103 * Null if the value does not exist. 104 */ 105 function get_metadata_raw( $meta_type, $object_id, $meta_key = '', $single = false ) { 106 $data = get_post_meta( $object_id, $request ); 107 return $data; 108 } 109 110 111 } -
src/wp-includes/revision.php
diff --git src/wp-includes/revision.php src/wp-includes/revision.php index e8bbcdbce4..a5fe608bf6 100644
function _wp_put_post_revision( $post = null, $autosave = false ) { 361 361 * Fires once a revision has been saved. 362 362 * 363 363 * @since 2.6.0 364 * @since 6.4.0 The post_id parameter was added. 364 365 * 365 366 * @param int $revision_id Post revision ID. 367 * @param int $post_id Post ID. 366 368 */ 367 do_action( '_wp_put_post_revision', $revision_id );369 do_action( '_wp_put_post_revision', $revision_id, $post['post_parent'] ); 368 370 } 369 371 370 372 return $revision_id; 371 373 } 372 374 375 376 /** 377 * Save the revisioned meta fields. 378 * 379 * @param int $revision_id The ID of the revision to save the meta to. 380 * @param int $post_id The ID of the post the revision is associated with. 381 * 382 * @since 6.4.0 383 */ 384 function wp_save_revisioned_meta_fields( $revision_id, $post_id ) { 385 386 // Save revisioned meta fields. 387 foreach ( wp_post_revision_meta_keys() as $meta_key ) { 388 if ( metadata_exists( 'post', $post_id, $meta_key ) ) { 389 _wp_copy_post_meta( $post_id, $revision_id, $meta_key ); 390 } 391 } 392 } 393 373 394 /** 374 395 * Gets a post revision. 375 396 * … … function wp_restore_post_revision( $revision, $fields = null ) { 450 471 // Update last edit user. 451 472 update_post_meta( $post_id, '_edit_last', get_current_user_id() ); 452 473 474 // Restore any revisioned meta fields. 475 wp_restore_post_revision_meta( $post_id, $revision['ID'] ); 476 453 477 /** 454 478 * Fires after a post revision has been restored. 455 479 * … … function wp_restore_post_revision( $revision, $fields = null ) { 463 487 return $post_id; 464 488 } 465 489 490 /** 491 * Restore the revisioned meta values for a post. 492 * 493 * @param int $post_id The ID of the post to restore the meta to. 494 * @param int $revision_id The ID of the revision to restore the meta from. 495 * 496 * @since 6.4.0 497 */ 498 function wp_restore_post_revision_meta( $post_id, $revision_id ) { 499 500 // Restore revisioned meta fields. 501 foreach ( (array) wp_post_revision_meta_keys() as $meta_key ) { 502 503 // Clear any existing meta. 504 delete_post_meta( $post_id, $meta_key ); 505 506 _wp_copy_post_meta( $revision_id, $post_id, $meta_key ); 507 } 508 } 509 510 /** 511 * Copy post meta for the given key from one post to another. 512 * 513 * @param int $source_post_id Post ID to copy meta value(s) from. 514 * @param int $target_post_id Post ID to copy meta value(s) to. 515 * @param string $meta_key Meta key to copy. 516 * 517 * @since 6.4.0 518 */ 519 function _wp_copy_post_meta( $source_post_id, $target_post_id, $meta_key ) { 520 521 foreach ( get_post_meta( $source_post_id, $meta_key ) as $meta_value ) { 522 /** 523 * We use add_metadata() function vs add_post_meta() here 524 * to allow for a revision post target OR regular post. 525 */ 526 add_metadata( 'post', $target_post_id, $meta_key, wp_slash( $meta_value ) ); 527 } 528 } 529 530 /** 531 * Determine which post meta fields should be revisioned. 532 * 533 * @since 6.4.0 534 * 535 * @return array An array of meta keys to be revisioned. 536 */ 537 function wp_post_revision_meta_keys() { 538 global $wp_revisioned_meta_keys; 539 540 /** 541 * Filter the list of post meta keys to be revisioned. 542 * 543 * @since 6.4.0 544 * 545 * @param array $keys An array of meta fields to be revisioned. 546 */ 547 return apply_filters( 'wp_post_revision_meta_keys', $wp_revisioned_meta_keys ); 548 } 549 550 /** 551 * Check whether revisioned post meta fields have changed. 552 * 553 * @param bool $post_has_changed Whether the post has changed. 554 * @param WP_Post $last_revision The last revision post object. 555 * @param WP_Post $post The post object. 556 * 557 * @since 6.4.0 558 */ 559 function wp_check_revisioned_meta_fields_have_changed( $post_has_changed, WP_Post $last_revision, WP_Post $post ) { 560 foreach ( wp_post_revision_meta_keys() as $meta_key ) { 561 if ( get_post_meta( $post->ID, $meta_key ) !== get_post_meta( $last_revision->ID, $meta_key ) ) { 562 $post_has_changed = true; 563 break; 564 } 565 } 566 return $post_has_changed; 567 } 568 466 569 /** 467 570 * Deletes a revision. 468 571 * … … function _set_preview( $post ) { 728 831 729 832 add_filter( 'get_the_terms', '_wp_preview_terms_filter', 10, 3 ); 730 833 add_filter( 'get_post_metadata', '_wp_preview_post_thumbnail_filter', 10, 3 ); 834 add_filter( 'get_post_metadata', '_wp_preview_meta_filter', 10, 4 ); 731 835 732 836 return $post; 733 837 } … … function _wp_upgrade_revisions_of_post( $post, $revisions ) { 948 1052 949 1053 return true; 950 1054 } 1055 1056 /** 1057 * Filters preview post meta retrieval to get values from the autosave. 1058 * 1059 * Filters revisioned meta keys only. 1060 * 1061 * @since 6.4.0 1062 * 1063 * @param mixed $value Meta value to filter. 1064 * @param int $object_id Object ID. 1065 * @param string $meta_key Meta key to filter a value for. 1066 * @param bool $single Whether to return a single value. Default false. 1067 * @return mixed Original meta value if the meta key isn't revisioned, the object doesn't exist, 1068 * the post type is a revision or the post ID doesn't match the object ID. 1069 * Otherwise, the revisioned meta value is returned for the preview. 1070 */ 1071 function _wp_preview_meta_filter( $value, $object_id, $meta_key, $single ) { 1072 1073 $post = get_post(); 1074 if ( 1075 empty( $post ) || 1076 $post->ID !== $object_id || 1077 ! in_array( $meta_key, wp_post_revision_meta_keys(), true ) || 1078 'revision' === $post->post_type 1079 ) { 1080 return $value; 1081 } 1082 1083 $preview = wp_get_post_autosave( $post->ID ); 1084 if ( ! is_object( $preview ) ) { 1085 return $value; 1086 } 1087 1088 return get_post_meta( $preview->ID, $meta_key, $single ); 1089 } -
src/wp-settings.php
diff --git src/wp-settings.php src/wp-settings.php index 2479420742..aec891e6b2 100644
require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-comment-meta-fields.ph 306 306 require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-post-meta-fields.php'; 307 307 require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-term-meta-fields.php'; 308 308 require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-user-meta-fields.php'; 309 require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-revision-meta-fields.php'; 309 310 require ABSPATH . WPINC . '/rest-api/search/class-wp-rest-search-handler.php'; 310 311 require ABSPATH . WPINC . '/rest-api/search/class-wp-rest-post-search-handler.php'; 311 312 require ABSPATH . WPINC . '/rest-api/search/class-wp-rest-term-search-handler.php'; -
tests/phpunit/tests/meta/registerMeta.php
diff --git tests/phpunit/tests/meta/registerMeta.php tests/phpunit/tests/meta/registerMeta.php index ae2c1d6e63..9a127295b0 100644
class Tests_Meta_Register_Meta extends WP_UnitTestCase { 97 97 'sanitize_callback' => null, 98 98 'auth_callback' => '__return_true', 99 99 'show_in_rest' => false, 100 'revisions_enabled' => false, 100 101 ), 101 102 ), 102 103 ), … … class Tests_Meta_Register_Meta extends WP_UnitTestCase { 121 122 'sanitize_callback' => null, 122 123 'auth_callback' => '__return_true', 123 124 'show_in_rest' => false, 125 'revisions_enabled' => false, 124 126 ), 125 127 ), 126 128 ), … … class Tests_Meta_Register_Meta extends WP_UnitTestCase { 175 177 'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ), 176 178 'auth_callback' => '__return_true', 177 179 'show_in_rest' => false, 180 'revisions_enabled' => false, 178 181 ), 179 182 ), 180 183 ), … … class Tests_Meta_Register_Meta extends WP_UnitTestCase { 342 345 'sanitize_callback' => null, 343 346 'auth_callback' => '__return_true', 344 347 'show_in_rest' => false, 348 'revisions_enabled' => false, 345 349 ), 346 350 ), 347 351 ), … … class Tests_Meta_Register_Meta extends WP_UnitTestCase { 395 399 'sanitize_callback' => null, 396 400 'auth_callback' => '__return_true', 397 401 'show_in_rest' => false, 402 'revisions_enabled' => false, 398 403 ), 399 404 ), 400 405 ), -
new file tests/phpunit/tests/post/metaRevisions.php
diff --git tests/phpunit/tests/post/metaRevisions.php tests/phpunit/tests/post/metaRevisions.php new file mode 100644 index 0000000000..c132f01e40
- + 1 <?php 2 3 /** 4 * 5 * Tests for post meta revisioning. 6 * 7 * @group post 8 * @group revision 9 * @group meta 10 * @group meta-revisions 11 */ 12 class MetaRevisionTests extends WP_UnitTestCase { 13 14 /** 15 * Callback function to add the revisioned keys. 16 * 17 * @param array $keys The array of revisioned keys. 18 * 19 * @return array 20 */ 21 public function add_revisioned_keys( $keys ) { 22 $keys[] = 'meta_revision_test'; 23 $keys[] = 'meta_multiples_test'; 24 return $keys; 25 } 26 27 /** 28 * Test the revisions system for storage of meta values with slashes. 29 * 30 * @param string $passed The passed data for testing. 31 * 32 * @param string $expected The expected value after storing & retrieving. 33 * 34 * @group revision 35 * @group slashed 36 * @dataProvider slashed_data_provider 37 */ 38 public function test_revisions_stores_meta_values_with_slashes( $passed, $expected ) { 39 // Set up a new post. 40 $post_id = $this->factory->post->create(); 41 42 // And update to store an initial revision. 43 wp_update_post( 44 array( 45 'post_content' => 'some initial content', 46 'ID' => $post_id, 47 ) 48 ); 49 add_filter( 'wp_post_revision_meta_keys', array( $this, 'add_revisioned_keys' ) ); 50 51 // Store a custom meta value, which is not revisioned by default. 52 update_post_meta( $post_id, 'meta_revision_test', wp_slash( $passed ) ); 53 $this->assertEquals( $expected, get_post_meta( $post_id, 'meta_revision_test', true ) ); 54 55 // Update the post, storing a revision. 56 wp_update_post( 57 array( 58 'post_content' => 'some more content', 59 'ID' => $post_id, 60 ) 61 ); 62 63 // Overwrite. 64 update_post_meta( $post_id, 'meta_revision_test', 'original' ); 65 // Update the post, storing a revision. 66 wp_update_post( 67 array( 68 'post_content' => 'some more content again', 69 'ID' => $post_id, 70 ) 71 ); 72 73 // Restore the previous revision. 74 $revisions = (array) wp_get_post_revisions( $post_id ); 75 76 // Go back two to load the previous revision. 77 array_shift( $revisions ); 78 $last_revision = array_shift( $revisions ); 79 80 // Restore! 81 wp_restore_post_revision( $last_revision->ID ); 82 83 $this->assertEquals( $expected, get_post_meta( $post_id, 'meta_revision_test', true ) ); 84 remove_filter( 'wp_post_revision_meta_keys', array( $this, 'add_revisioned_keys' ) ); 85 } 86 87 /** 88 * Provide data for the slashed data tests. 89 */ 90 public function slashed_data_provider() { 91 return array( 92 array( 93 'some\text', 94 'some\text', 95 ), 96 array( 97 'test some\ \\extra \\\slashed \\\\text ', 98 'test some\ \\extra \\\slashed \\\\text ', 99 ), 100 array( 101 "This \'is\' an example \n of a \"quoted\" string", 102 "This \'is\' an example \n of a \"quoted\" string", 103 ), 104 array( 105 'some unslashed text just to test! % & * ( ) #', 106 'some unslashed text just to test! % & * ( ) #', 107 ), 108 ); 109 } 110 111 /** 112 * Test the revisions system for storage of meta values. 113 * 114 * @group revision 115 */ 116 public function test_revisions_stores_meta_values() { 117 /* 118 * Set Up. 119 */ 120 121 // Set up a new post. 122 $post_id = $this->factory->post->create(); 123 $original_post_id = $post_id; 124 125 // And update to store an initial revision. 126 wp_update_post( 127 array( 128 'post_content' => 'some initial content', 129 'ID' => $post_id, 130 ) 131 ); 132 133 // One revision so far. 134 $revisions = wp_get_post_revisions( $post_id ); 135 $this->assertCount( 1, $revisions ); 136 137 /* 138 * First set up a meta value. 139 */ 140 141 // Store a custom meta value, which is not revisioned by default. 142 update_post_meta( $post_id, 'meta_revision_test', 'original' ); 143 144 // Update the post, storing a revision. 145 wp_update_post( 146 array( 147 'post_content' => 'some more content', 148 'ID' => $post_id, 149 ) 150 ); 151 152 $revisions = wp_get_post_revisions( $post_id ); 153 $this->assertCount( 2, $revisions ); 154 155 // Next, store some updated meta values for the same key. 156 update_post_meta( $post_id, 'meta_revision_test', 'update1' ); 157 158 // Save the post, changing content to force a revision. 159 wp_update_post( 160 array( 161 'post_content' => 'some updated content', 162 'ID' => $post_id, 163 ) 164 ); 165 166 $revisions = wp_get_post_revisions( $post_id ); 167 $this->assertCount( 3, $revisions ); 168 169 /* 170 * Now restore the original revision. 171 */ 172 173 // Restore the previous revision. 174 $revisions = (array) wp_get_post_revisions( $post_id ); 175 176 // Go back two to load the previous revision. 177 array_shift( $revisions ); 178 $last_revision = array_shift( $revisions ); 179 180 // Restore! 181 wp_restore_post_revision( $last_revision->ID ); 182 183 wp_update_post( array( 'ID' => $post_id ) ); 184 $revisions = wp_get_post_revisions( $post_id ); 185 $this->assertCount( 4, $revisions ); 186 187 /* 188 * Check the meta values to verify they are NOT revisioned - they are not revisioned by default. 189 */ 190 191 // Custom post meta should NOT be restored, orignal value should not be restored, value still 'update1'. 192 $this->assertEquals( 'update1', get_post_meta( $post_id, 'meta_revision_test', true ) ); 193 194 update_post_meta( $post_id, 'meta_revision_test', 'update2' ); 195 196 /* 197 * Test the revisioning of custom meta when enabled by the wp_post_revision_meta_keys filter. 198 */ 199 200 // Add the custom field to be revised via the wp_post_revision_meta_keys filter. 201 add_filter( 'wp_post_revision_meta_keys', array( $this, 'add_revisioned_keys' ) ); 202 203 // Save the post, changing content to force a revision. 204 wp_update_post( 205 array( 206 'post_content' => 'more updated content', 207 'ID' => $post_id, 208 ) 209 ); 210 211 $revisions = array_values( wp_get_post_revisions( $post_id ) ); 212 $this->assertCount( 5, $revisions ); 213 $this->assertEquals( 'update2', get_post_meta( $revisions[0]->ID, 'meta_revision_test', true ) ); 214 215 // Store custom meta values, which should now be revisioned. 216 update_post_meta( $post_id, 'meta_revision_test', 'update3' ); 217 218 /* 219 * Save the post again, custom meta should now be revisioned. 220 * 221 * Note that a revision is saved even though there is no change 222 * in post content, because the revisioned post_meta has changed. 223 */ 224 wp_update_post( 225 array( 226 'ID' => $post_id, 227 ) 228 ); 229 230 // This revision contains the existing post meta ('update3'). 231 $revisions = wp_get_post_revisions( $post_id ); 232 $this->assertCount( 6, $revisions ); 233 234 // Verify that previous post meta is set. 235 $this->assertEquals( 'update3', get_post_meta( $post_id, 'meta_revision_test', true ) ); 236 237 // Restore the previous revision. 238 $revisions = wp_get_post_revisions( $post_id ); 239 240 // Go back two to load the previous revision. 241 array_shift( $revisions ); 242 $last_revision = array_shift( $revisions ); 243 wp_restore_post_revision( $last_revision->ID ); 244 245 /* 246 * Verify that previous post meta is restored. 247 */ 248 $this->assertEquals( 'update2', get_post_meta( $post_id, 'meta_revision_test', true ) ); 249 250 // Try storing a blank meta. 251 update_post_meta( $post_id, 'meta_revision_test', '' ); 252 wp_update_post( 253 array( 254 'ID' => $post_id, 255 ) 256 ); 257 258 update_post_meta( $post_id, 'meta_revision_test', 'update 4' ); 259 wp_update_post( 260 array( 261 'ID' => $post_id, 262 ) 263 ); 264 265 // Restore the previous revision. 266 $revisions = wp_get_post_revisions( $post_id ); 267 array_shift( $revisions ); 268 $last_revision = array_shift( $revisions ); 269 wp_restore_post_revision( $last_revision->ID ); 270 271 /* 272 * Verify that previous blank post meta is restored. 273 */ 274 $this->assertEquals( '', get_post_meta( $post_id, 'meta_revision_test', true ) ); 275 276 /* 277 * Test not tracking a key - remove the key from the revisioned meta. 278 */ 279 remove_all_filters( 'wp_post_revision_meta_keys' ); 280 281 // Meta should no longer be revisioned. 282 update_post_meta( $post_id, 'meta_revision_test', 'update 5' ); 283 wp_update_post( 284 array( 285 'ID' => $post_id, 286 'post_content' => 'changed content', 287 ) 288 ); 289 update_post_meta( $post_id, 'meta_revision_test', 'update 6' ); 290 wp_update_post( 291 array( 292 'ID' => $post_id, 293 'post_content' => 'go updated content', 294 ) 295 ); 296 297 // Restore the previous revision. 298 $revisions = wp_get_post_revisions( $post_id ); 299 array_shift( $revisions ); 300 $last_revision = array_shift( $revisions ); 301 wp_restore_post_revision( $last_revision->ID ); 302 303 /* 304 * Verify that previous post meta is NOT restored. 305 */ 306 $this->assertEquals( 'update 6', get_post_meta( $post_id, 'meta_revision_test', true ) ); 307 308 // Add the custom field to be revised via the wp_post_revision_meta_keys filter. 309 add_filter( 'wp_post_revision_meta_keys', array( $this, 'add_revisioned_keys' ) ); 310 311 /* 312 * Test the revisioning of multiple meta keys. 313 */ 314 315 // Add three values for meta. 316 update_post_meta( $post_id, 'meta_revision_test', 'update 7' ); 317 add_post_meta( $post_id, 'meta_revision_test', 'update 7 number 2' ); 318 add_post_meta( $post_id, 'meta_revision_test', 'update 7 number 3' ); 319 wp_update_post( array( 'ID' => $post_id ) ); 320 321 // Update all three values. 322 update_post_meta( $post_id, 'meta_revision_test', 'update 8', 'update 7' ); 323 update_post_meta( $post_id, 'meta_revision_test', 'update 8 number 2', 'update 7 number 2' ); 324 update_post_meta( $post_id, 'meta_revision_test', 'update 8 number 3', 'update 7 number 3' ); 325 326 // Restore the previous revision. 327 $revisions = wp_get_post_revisions( $post_id ); 328 $last_revision = array_shift( $revisions ); 329 wp_restore_post_revision( $last_revision->ID ); 330 331 /* 332 * Verify that multiple metas stored correctly. 333 */ 334 $this->assertEquals( array( 'update 7', 'update 7 number 2', 'update 7 number 3' ), get_post_meta( $post_id, 'meta_revision_test' ) ); 335 336 /* 337 * Test the revisioning of a multidimensional array. 338 */ 339 $test_array = array( 340 'a' => array( 341 '1', 342 '2', 343 '3', 344 ), 345 'b' => 'ok', 346 'c' => array( 347 'multi' => array( 348 'a', 349 'b', 350 'c', 351 ), 352 'not' => 'ok', 353 ), 354 ); 355 356 // Clear any old value. 357 delete_post_meta( $post_id, 'meta_revision_test' ); 358 359 // Set the test meta to the array. 360 update_post_meta( $post_id, 'meta_revision_test', $test_array ); 361 362 // Update to save. 363 wp_update_post( array( 'ID' => $post_id ) ); 364 365 // Set the test meta blank. 366 update_post_meta( $post_id, 'meta_revision_test', '' ); 367 368 // Restore the previous revision. 369 $revisions = wp_get_post_revisions( $post_id ); 370 $last_revision = array_shift( $revisions ); 371 wp_restore_post_revision( $last_revision->ID ); 372 373 /* 374 * Verify multidimensional array stored correctly. 375 */ 376 $stored_array = get_post_meta( $post_id, 'meta_revision_test' ); 377 $this->assertEquals( $test_array, $stored_array[0] ); 378 /* 379 380 * Test multiple revisions on the same key. 381 */ 382 383 // Set the test meta to the array. 384 add_post_meta( $post_id, 'meta_multiples_test', 'test1' ); 385 add_post_meta( $post_id, 'meta_multiples_test', 'test2' ); 386 add_post_meta( $post_id, 'meta_multiples_test', 'test3' ); 387 388 // Update to save. 389 wp_update_post( array( 'ID' => $post_id ) ); 390 391 $stored_array = get_post_meta( $post_id, 'meta_multiples_test' ); 392 $expect = array( 'test1', 'test2', 'test3' ); 393 394 $this->assertEquals( $expect, $stored_array ); 395 396 // Restore the previous revision. 397 $revisions = wp_get_post_revisions( $post_id ); 398 $last_revision = array_shift( $revisions ); 399 wp_restore_post_revision( $last_revision->ID ); 400 401 $stored_array = get_post_meta( $post_id, 'meta_multiples_test' ); 402 $expect = array( 'test1', 'test2', 'test3' ); 403 404 $this->assertEquals( $expect, $stored_array ); 405 406 // Cleanup! 407 wp_delete_post( $original_post_id ); 408 } 409 410 /** 411 * Verify that only existing meta is revisioned. 412 */ 413 public function only_existing_meta_is_revisioned() { 414 add_filter( 'wp_post_revision_meta_keys', array( $this, 'add_revisioned_keys' ) ); 415 416 // Set up a new post. 417 $post_id = $this->factory->post->create( 418 array( 419 'post_content' => 'initial content', 420 ) 421 ); 422 423 // Revision v1. 424 wp_update_post( 425 array( 426 'ID' => $post_id, 427 'post_content' => 'updated content v1', 428 ) 429 ); 430 431 $this->assertPostNotHasMetaKey( $post_id, 'foo' ); 432 $this->assertPostNotHasMetaKey( $post_id, 'bar' ); 433 434 $revisions = wp_get_post_revisions( $post_id ); 435 $revision = array_shift( $revisions ); 436 $this->assertEmpty( get_metadata( 'post', $revision->ID ) ); 437 438 // Revision v2. 439 wp_update_post( 440 array( 441 'ID' => $post_id, 442 'post_content' => 'updated content v2', 443 'meta_input' => array( 444 'foo' => 'foo v2', 445 ), 446 ) 447 ); 448 449 $this->assertPostHasMetaKey( $post_id, 'foo' ); 450 $this->assertPostNotHasMetaKey( $post_id, 'bar' ); 451 $this->assertPostNotHasMetaKey( $post_id, 'meta_revision_test' ); 452 453 $revisions = wp_get_post_revisions( $post_id ); 454 $revision = array_shift( $revisions ); 455 $this->assertPostHasMetaKey( $revision->ID, 'foo' ); 456 $this->assertPostNotHasMetaKey( $revision->ID, 'bar' ); 457 $this->assertPostNotHasMetaKey( $revision->ID, 'meta_revision_test' ); 458 } 459 460 /** 461 * Verify that blank strings are revisioned correctly. 462 */ 463 public function blank_meta_is_revisioned() { 464 465 add_filter( 'wp_post_revision_meta_keys', array( $this, 'add_revisioned_keys' ) ); 466 467 // Set up a new post. 468 $post_id = $this->factory->post->create( 469 array( 470 'post_content' => 'initial content', 471 'meta_input' => array( 472 'foo' => 'foo', 473 ), 474 ) 475 ); 476 477 // Set the test meta to an empty string. 478 update_post_meta( $post_id, 'foo', '' ); 479 480 // Update to save. 481 wp_update_post( array( 'ID' => $post_id ) ); 482 483 $stored_array = get_post_meta( $post_id, 'meta_multiples_test' ); 484 $expect = array( 'test1', 'test2', 'test3' ); 485 486 $this->assertEquals( $expect, $stored_array ); 487 488 // Restore the previous revision. 489 $revisions = wp_get_post_revisions( $post_id ); 490 $last_revision = array_shift( $revisions ); 491 wp_restore_post_revision( $last_revision->ID ); 492 $stored_data = get_post_meta( $post_id, 'foo' ); 493 $this->assertEquals( '', $stored_data[0] ); 494 } 495 496 497 /** 498 * @dataProvider data_register_post_meta_supports_revisions 499 */ 500 public function test_register_post_meta_supports_revisions( $post_type, $meta_key, $args, $expected_is_revisioned ) { 501 register_post_meta( $post_type, $meta_key, $args ); 502 503 // Set up a new post. 504 $post_id = $this->factory->post->create( 505 array( 506 'post_content' => 'initial content', 507 'post_type' => $post_type, 508 'meta_input' => array( 509 $meta_key => 'foo', 510 ), 511 ) 512 ); 513 514 // Update the post meta and post to save. 515 update_post_meta( $post_id, $meta_key, 'bar' ); 516 wp_update_post( 517 array( 518 'ID' => $post_id, 519 'post_title' => 'updated title', 520 ) 521 ); 522 523 // Check the last revision for the post to see if the meta key was revisioned 524 $revisions = wp_get_post_revisions( $post_id ); 525 $revision = array_shift( $revisions ); 526 $revisioned_meta = get_post_meta( $revision->ID, $meta_key, true ); 527 $this->assertEquals( $expected_is_revisioned, 'bar' === $revisioned_meta ); 528 529 // Reset global so subsequent data tests do not get polluted. 530 $GLOBALS['wp_meta_keys'] = array(); 531 } 532 533 public function data_register_post_meta_supports_revisions() { 534 return array( 535 array( 'post', 'registered_key1', array( 'single' => true ), false ), 536 array( 537 'post', 538 'registered_key1', 539 array( 540 'single' => true, 541 'revisions_enabled' => true, 542 ), 543 true, 544 ), 545 array( 'page', 'registered_key2', array( 'revisions_enabled' => false ), false ), 546 array( 'page', 'registered_key2', array( 'revisions_enabled' => true ), true ), 547 array( '', 'registered_key3', array( 'revisions_enabled' => false ), false ), 548 array( '', 'registered_key3', array( 'revisions_enabled' => true ), true ), 549 ); 550 } 551 552 /** 553 * Assert the a post has a meta key. 554 * 555 * @param int $post_id The ID of the post to check. 556 * @param string $meta_key The meta key to check for. 557 */ 558 protected function assertPostHasMetaKey( $post_id, $meta_key ) { 559 $this->assertEquals( $expect, $stored_array ); 560 } 561 562 /** 563 * Assert that post does not have a meta key. 564 * 565 * @param int $post_id The ID of the post to check. 566 * @param string $meta_key The meta key to check for. 567 */ 568 protected function assertPostNotHasMetaKey( $post_id, $meta_key ) { 569 $this->assertArrayNotHasKey( $meta_key, get_metadata( 'post', $post_id ) ); 570 } 571 } -
tests/phpunit/tests/rest-api/rest-post-meta-fields.php
diff --git tests/phpunit/tests/rest-api/rest-post-meta-fields.php tests/phpunit/tests/rest-api/rest-post-meta-fields.php index 2142e80582..a184ba2022 100644
class WP_Test_REST_Post_Meta_Fields extends WP_Test_REST_TestCase { 3112 3112 } 3113 3113 return $query; 3114 3114 } 3115 3116 3117 /** 3118 * Test that post meta is revisioned when saving to the posts REST API endpoint. 3119 * 3120 * @ticket 20564 3121 */ 3122 public function test_revisioned_post_meta_with_posts_endpoint() { 3123 $this->grant_write_permission(); 3124 3125 register_post_meta( 3126 'post', 3127 'foo', 3128 array( 3129 'single' => true, 3130 'show_in_rest' => true, 3131 'revisions_enabled' => true, 3132 ) 3133 ); 3134 3135 $post_id = self::$post_id; 3136 3137 // Update the post, saving the meta. 3138 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', $post_id ) ); 3139 $request->set_body_params( 3140 array( 3141 'title' => 'Revision 1', 3142 'meta' => array( 3143 'foo' => 'bar', 3144 ), 3145 ) 3146 ); 3147 $response = rest_get_server()->dispatch( $request ); 3148 $this->assertSame( 200, $response->get_status() ); 3149 3150 // Get the last revision. 3151 $revisions = wp_get_post_revisions( $post_id, array( 'posts_per_page' => 1 ) ); 3152 $revision_id = array_shift( $revisions )->ID; 3153 3154 // @todo Ensure the revisions endpoint returns the correct meta values 3155 // Check that the revisions endpoint returns the correct meta value. 3156 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d/revisions/%d', $post_id, $revision_id ) ); 3157 $response = rest_get_server()->dispatch( $request ); 3158 $this->assertSame( 200, $response->get_status() ); 3159 $data = $response->get_data(); 3160 $this->assertSame( array( 'bar' ), $response->get_data()['meta']['foo'] ); 3161 3162 // Check that the post meta is set correctly. 3163 $this->assertSame( 'bar', get_post_meta( $revision_id, 'foo', true ) ); 3164 3165 // Create two more revisions with different meta values for the foo key. 3166 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', $post_id ) ); 3167 $request->set_body_params( 3168 array( 3169 'title' => 'Revision 2', 3170 'meta' => array( 3171 'foo' => 'baz', 3172 ), 3173 ) 3174 ); 3175 $response = rest_get_server()->dispatch( $request ); 3176 $this->assertSame( 200, $response->get_status() ); 3177 3178 // Get the last revision. 3179 $revisions = wp_get_post_revisions( $post_id, array( 'posts_per_page' => 1 ) ); 3180 $revision_id_2 = array_shift( $revisions )->ID; 3181 3182 // Check that the revision has the correct meta value. 3183 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d/revisions/%d', $post_id, $revision_id_2 ) ); 3184 $response = rest_get_server()->dispatch( $request ); 3185 $this->assertSame( 200, $response->get_status() ); 3186 $this->assertSame( array( 'baz' ), $response->get_data()['meta']['foo'] ); 3187 3188 // Check that the post meta is set correctly. 3189 $this->assertSame( 'baz', get_post_meta( $revision_id_2, 'foo', true ) ); 3190 3191 // One more revision! 3192 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', $post_id ) ); 3193 $request->set_body_params( 3194 array( 3195 'title' => 'Revision 3', 3196 'meta' => array( 3197 'foo' => 'qux', 3198 ), 3199 ) 3200 ); 3201 $response = rest_get_server()->dispatch( $request ); 3202 $this->assertSame( 200, $response->get_status() ); 3203 3204 // Get the last revision. 3205 $revisions = wp_get_post_revisions( $post_id, array( 'posts_per_page' => 1 ) ); 3206 $revision_id_3 = array_shift( $revisions )->ID; 3207 3208 // Check that the revision has the correct meta value. 3209 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d/revisions/%d', $post_id, $revision_id_3 ) ); 3210 $response = rest_get_server()->dispatch( $request ); 3211 $this->assertSame( 200, $response->get_status() ); 3212 $this->assertSame( array( 'qux' ), $response->get_data()['meta']['foo'] ); 3213 3214 // Check that the post meta is set correctly. 3215 $this->assertSame( 'qux', get_post_meta( $revision_id_3, 'foo', true ) ); 3216 3217 // Restore Revision 3 and verify the post gets the correct meta value. 3218 wp_restore_post_revision( $revision_id_3 ); 3219 $this->assertSame( 'qux', get_post_meta( $post_id, 'foo', true ) ); 3220 3221 // Restore Revision 2 and verify the post gets the correct meta value. 3222 wp_restore_post_revision( $revision_id_2 ); 3223 $this->assertSame( 'baz', get_post_meta( $post_id, 'foo', true ) ); 3224 3225 // Test with multiple meta values. Note that the posts endpoint doesn't accept multiple meta values, so we'll add those manually. 3226 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', $post_id ) ); 3227 $request->set_body_params( 3228 array( 3229 'title' => 'Revision 4', 3230 'meta' => array( 3231 'foo' => 'bar', 3232 ), 3233 ) 3234 ); 3235 $response = rest_get_server()->dispatch( $request ); 3236 $this->assertSame( 200, $response->get_status() ); 3237 3238 // Add additional meta values. 3239 add_post_meta( $post_id, 'foo', 'bat' ); 3240 add_post_meta( $post_id, 'foo', 'baz' ); 3241 3242 // Log the current post meta. 3243 $meta = get_post_meta( $post_id ); 3244 3245 // Update the post. 3246 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', $post_id ) ); 3247 $request->set_body_params( 3248 array( 3249 'title' => 'Revision 4 update', 3250 ) 3251 ); 3252 $response = rest_get_server()->dispatch( $request ); 3253 $this->assertSame( 200, $response->get_status() ); 3254 3255 // Get the last revision. 3256 $revisions = wp_get_post_revisions( $post_id, array( 'posts_per_page' => 1 ) ); 3257 $revision_id_4 = array_shift( $revisions )->ID; 3258 3259 // Check that the revision has the correct meta value. 3260 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d/revisions/%d', $post_id, $revision_id_4 ) ); 3261 $response = rest_get_server()->dispatch( $request ); 3262 $this->assertSame( 200, $response->get_status() ); 3263 3264 $this->assertSame( 3265 array( 'bar', 'bat', 'baz' ), 3266 $response->get_data()['meta']['foo'] 3267 ); 3268 3269 } 3115 3270 } -
tests/phpunit/tests/user/wpRegisterPersistedPreferencesMeta.php
diff --git tests/phpunit/tests/user/wpRegisterPersistedPreferencesMeta.php tests/phpunit/tests/user/wpRegisterPersistedPreferencesMeta.php index c3c4bd7a09..68b3c86742 100644
class Tests_User_WpRegisterPersistedPreferencesMeta extends WP_UnitTestCase { 52 52 'additionalProperties' => true, 53 53 ), 54 54 ), 55 'revisions_enabled' => false, 55 56 ), 56 57 $wp_meta_keys['user'][''][ $meta_key ], 57 58 'The registered metadata did not have the expected structure'