Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
b8bf5ef
Add revisioning of post meta, including ‘footnotes’ by default
adamsilverstein Jul 17, 2023
6667610
correct typo in `src/wp-includes/default-filters.php`
adamsilverstein Jul 17, 2023
15e9e4e
add tests for meta revisioning
adamsilverstein Jul 17, 2023
b892323
Try: revisioning in the rest endpoint directly, after meta is saved
adamsilverstein Jul 17, 2023
6235af5
Add _wp_save_post_revision_meta helper that copies revisioned meta to…
adamsilverstein Jul 18, 2023
3a87749
remove direct REST API integration, move save to wp_after_insert_post
adamsilverstein Jul 18, 2023
05d0f86
Clean up revisions save
adamsilverstein Jul 18, 2023
19e1f8a
phpcbf
adamsilverstein Jul 18, 2023
0b86da9
Ensure `$revisions[0]->post_id ` is set before using
adamsilverstein Jul 18, 2023
52dd943
Test work
adamsilverstein Jul 18, 2023
ef14c11
Expected revision count is 6
adamsilverstein Jul 19, 2023
31a6d61
Merge branch 'trunk' into ticket/20564
adamsilverstein Jul 21, 2023
da8abe6
Add REST API tests for revisioning of post meta.
adamsilverstein Jul 25, 2023
d2f0db1
Merge branch 'trunk' into ticket/20564
adamsilverstein Jul 25, 2023
6c9bece
Remove footnote specific revisioning of meta
adamsilverstein Jul 25, 2023
2e74964
phpcbf
adamsilverstein Jul 25, 2023
268385f
Fix test setup
adamsilverstein Jul 25, 2023
4fd4302
Save revisioned meta in `_wp_put_post_revision`
adamsilverstein Jul 25, 2023
3722d1e
Enable setting revisioning in register_meta
adamsilverstein Jul 25, 2023
b26a695
phpcs
adamsilverstein Jul 26, 2023
5d6e5b9
remove unused $revisioned_keys
adamsilverstein Jul 26, 2023
b4fa33f
Add testing for enabling revisions in `register_meta`
adamsilverstein Jul 26, 2023
1603c55
phpcbf
adamsilverstein Jul 26, 2023
d244a39
Use a separate global for revisioned keys `$wp_revisioned_meta_keys`
adamsilverstein Jul 26, 2023
d86ec77
Merge branch 'trunk' into ticket/20564
adamsilverstein Jul 26, 2023
a80620a
Meta test cleanup to match new defaults
adamsilverstein Jul 26, 2023
885640d
Adjust expected for `test_should_register_persisted_preferences_meta`
adamsilverstein Jul 26, 2023
ea4f181
Refine REST tests for meta revisioning
adamsilverstein Jul 26, 2023
e63334b
Avoid duplicate keys in `wp_revisioned_meta_keys`
adamsilverstein Jul 26, 2023
f4234f8
remove unused `original_post_id`
adamsilverstein Jul 26, 2023
1f1e5a0
REST posts endpoint: update revision meta when saving meta
adamsilverstein Jul 26, 2023
6c5061b
test work
adamsilverstein Jul 26, 2023
5bd7e7b
Hook `wp_save_revisioned_meta_fields` on `_wp_put_post_revision` so i…
adamsilverstein Jul 27, 2023
65bfe81
Test cleanup
adamsilverstein Jul 27, 2023
7254e3a
Improve footnote display, show number and content
adamsilverstein Jul 27, 2023
8c3fba2
Save the revisioned meta directly in the REST endpoint
adamsilverstein Jul 27, 2023
26a9d0b
spacing
adamsilverstein Jul 27, 2023
210573b
Merge branch 'trunk' into ticket/20564
adamsilverstein Jul 27, 2023
485f20b
add meta to revisions endpoint
adamsilverstein Jul 31, 2023
167261e
test revisions endpoint returns meta
adamsilverstein Jul 31, 2023
5b5dc0d
new revision meta fields class
adamsilverstein Jul 31, 2023
f8d0d30
INCLUDE class-wp-rest-revision-meta-fields
adamsilverstein Aug 1, 2023
ea9b8ce
Revision existing meta even when update/insert lacks meta
adamsilverstein Aug 1, 2023
15e8bbd
Test that the revisions endpoint includes meta
adamsilverstein Aug 1, 2023
1e54aa3
Merge branch 'trunk' into ticket/20564
adamsilverstein Aug 1, 2023
a3fa561
phpcbf
adamsilverstein Aug 1, 2023
877420e
Merge branch 'trunk' into ticket/20564
adamsilverstein Aug 17, 2023
f57b79b
Update REST tests to reflect changed schema
adamsilverstein Aug 17, 2023
cad9272
phpcbf
adamsilverstein Aug 18, 2023
57c872a
Improve tests
adamsilverstein Aug 18, 2023
ca01058
Finetune tests based on git action failures
adamsilverstein Aug 18, 2023
92590aa
test
adamsilverstein Aug 18, 2023
6fd9a9e
restore footnotes.php from trunk
adamsilverstein Aug 24, 2023
f83d353
Merge branch 'trunk' into ticket/20564
adamsilverstein Aug 24, 2023
7f70990
Update wp-api-generated fixtures
adamsilverstein Aug 24, 2023
432a810
fix generated
adamsilverstein Aug 24, 2023
d80b7b4
Try: move hooking of revisions
adamsilverstein Aug 24, 2023
7160abb
fire after hooks in revisions controller test
adamsilverstein Aug 24, 2023
96301da
Try only adding revision on update.
TimothyBJacobs Aug 24, 2023
e2d0cc7
Use actions properly
TimothyBJacobs Aug 24, 2023
5f07145
Revert "Try only adding revision on update."
TimothyBJacobs Aug 24, 2023
afc1109
Don't rewrite everything
TimothyBJacobs Aug 24, 2023
ac279e3
Correct logic
TimothyBJacobs Aug 24, 2023
4205d65
Check if the legacy hook is being used
TimothyBJacobs Aug 24, 2023
e7b4495
Separate single and multi meta tests. Use native meta fields handler.
TimothyBJacobs Aug 24, 2023
68f6410
Regenerate fixtures
TimothyBJacobs Aug 24, 2023
ee35085
Use post meta fields directly
TimothyBJacobs Aug 24, 2023
61bfafc
Respect the object subtype.
TimothyBJacobs Aug 24, 2023
c27258a
Always pass a post array
TimothyBJacobs Aug 24, 2023
20874e3
Remove manually revisioning meta. This happens automatically now.
TimothyBJacobs Aug 24, 2023
68a419b
Correct has meta key assertion
TimothyBJacobs Aug 24, 2023
3ee633f
Add clarifying comment and some more fail safes
TimothyBJacobs Aug 24, 2023
1e17f5b
Merge branch 'trunk' into ticket/20564
adamsilverstein Aug 27, 2023
982c553
Merge branch 'trunk' into ticket/20564
adamsilverstein Aug 28, 2023
d04574a
Test cleanup, add page and cpt tests
adamsilverstein Aug 29, 2023
3a8f6fc
omyac
adamsilverstein Aug 29, 2023
192e7c0
Merge branch 'trunk' into ticket/20564
adamsilverstein Sep 8, 2023
225a91b
Clean up default filters after trunk merge
adamsilverstein Sep 8, 2023
c2482fd
Avoid duplicate revisions since hook change
adamsilverstein Sep 9, 2023
2331d36
Merge branch 'trunk' into ticket/20564
adamsilverstein Sep 11, 2023
5c48c7a
Restore hooks on wp_insert_post for revision - issue was plugin related
adamsilverstein Sep 11, 2023
e211ca1
Ensure meta data is revisioned with autosaves
adamsilverstein Sep 12, 2023
7247e93
Cleanup, only check meta when passed
adamsilverstein Sep 12, 2023
891a0e4
Merge branch 'trunk' into ticket/20564
adamsilverstein Sep 19, 2023
c35cc5f
Merge branch 'trunk' into ticket/20564
adamsilverstein Sep 22, 2023
826bebb
Merge branch 'trunk' into ticket/20564
adamsilverstein Sep 25, 2023
750dcdc
Hook wp_autosave_post_revisioned_meta_fields on wp_creating_autosave
adamsilverstein Sep 25, 2023
0b88e50
Improve error checking
adamsilverstein Sep 25, 2023
2c02dbc
Update src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-con…
adamsilverstein Sep 25, 2023
b5ba2d3
Update src/wp-includes/revision.php
adamsilverstein Sep 25, 2023
95508d9
Hook revision restore on action
adamsilverstein Sep 25, 2023
b0b880b
Test revisioning of meta with a default value
adamsilverstein Sep 25, 2023
f04a319
phpcs
adamsilverstein Sep 25, 2023
e231886
phpcbf
adamsilverstein Sep 25, 2023
e1950b0
Autosaves controller - get_metadata_raw is used to avoid retrieving t…
adamsilverstein Sep 25, 2023
6f6e3ce
Update src/wp-includes/revision.php
adamsilverstein Sep 25, 2023
b77bf22
Check post_type available in wp_save_revisioned_meta_fields
adamsilverstein Sep 25, 2023
b6e221a
Ensure post_type available in wp_restore_post_revision_meta
adamsilverstein Sep 25, 2023
40febf2
typo - missing closing parenthesis
adamsilverstein Sep 25, 2023
69c6107
phpcbf
adamsilverstein Sep 25, 2023
f9b760b
If the object_type is set, require a type that supports revisions wh…
adamsilverstein Sep 25, 2023
8360faa
Test enabling revisions for meta when object type doesn’t support rev…
adamsilverstein Sep 25, 2023
a1971f7
phpcbf
adamsilverstein Sep 25, 2023
99b2aa8
Update src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-con…
adamsilverstein Sep 26, 2023
b94e1a6
Update src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-con…
adamsilverstein Sep 26, 2023
e09f011
Update src/wp-admin/includes/post.php
adamsilverstein Sep 26, 2023
01a4788
Update src/wp-admin/includes/post.php
adamsilverstein Sep 26, 2023
8e7b72a
spacing
adamsilverstein Sep 26, 2023
d6c6ca2
Guard against _wp_put_post_revision returning 0
adamsilverstein Sep 26, 2023
73f6a23
Update src/wp-includes/meta.php
adamsilverstein Sep 26, 2023
3db644c
tabs vs spaces
adamsilverstein Sep 26, 2023
95c9e9d
Update src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-con…
adamsilverstein Sep 26, 2023
9bab9a9
Improve error message
adamsilverstein Sep 26, 2023
dc0b907
Merge branch 'trunk' into ticket/20564
adamsilverstein Sep 26, 2023
ab2d500
Merge branch 'trunk' into ticket/20564
adamsilverstein Sep 26, 2023
8bf1727
phpcbf
adamsilverstein Sep 26, 2023
c7904ce
phpcbf pt 2
adamsilverstein Sep 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add revisioning of post meta, including ‘footnotes’ by default
  • Loading branch information
adamsilverstein committed Jul 17, 2023
commit b8bf5efda6d93a3587237f744cc0bd37f0d6ec36
62 changes: 60 additions & 2 deletions src/wp-admin/includes/post.php
Original file line number Diff line number Diff line change
Expand Up @@ -1961,15 +1961,73 @@ function wp_create_post_autosave( $post_data ) {
* @param array $new_autosave Post array - the autosave that is about to be saved.
*/
do_action( 'wp_creating_autosave', $new_autosave );

wp_autosave_post_revisioned_meta_fields( $new_autosave );
return wp_update_post( $new_autosave );
}

// _wp_put_post_revision() expects unescaped.
$post_data = wp_unslash( $post_data );

// Otherwise create the new autosave as a special post revision.
return _wp_put_post_revision( $post_data, true );
$revision = _wp_put_post_revision( $post_data, true );

// Update the revisioned meta data as well.
wp_autosave_post_revisioned_meta_fields( $revision );
return $revision;
}

/**
* Autosave the revisioned meta fields.
*
* Iterates thru the revisioned meta fields and checks each to see if they are set,
* and have a changed value. If so, the meta value is saved and attached to the autosave.
*
* @since 6.4.0
*
* @param Post object $new_autosave The new post being autosaved.
*/
function wp_autosave_post_revisioned_meta_fields( $new_autosave ) {
/*
* The post data arrives as either $_POST['data']['wp_autosave'] or the $_POST
* itself. This sets $posted_data to the correct variable.
*
* Ignoring sanitization to avoid altering meta. Ignoring the nonce check because
* this is hooked on inner core hooks where a valid nonce was already checked.
*
* @phpcs:disable WordPress.Security
*/
$posted_data = isset( $_POST['data']['wp_autosave'] ) ? $_POST['data']['wp_autosave'] : $_POST;
// phpcs:enable

/*
* Go thru the revisioned meta keys and save them as part of the autosave, if
* the meta key is part of the posted data, the meta value is not blank and
* the the meta value has changes from the last autosaved value.
*/
foreach ( wp_post_revision_meta_keys() as $meta_key ) {

if (
isset( $posted_data[ $meta_key ] ) &&
get_post_meta( $new_autosave['ID'], $meta_key, true ) !== wp_unslash( $posted_data[ $meta_key ] )
) {
/*
* Use the underlying delete_metadata() and add_metadata() functions
* vs delete_post_meta() and add_post_meta() to make sure we're working
* with the actual revision meta.
*/
delete_metadata( 'post', $new_autosave['ID'], $meta_key );

/*
* One last check to ensure meta value not empty().
*/
if ( ! empty( $posted_data[ $meta_key ] ) ) {
/*
* Add the revisions meta data to the autosave.
*/
add_metadata( 'post', $new_autosave['ID'], $meta_key, $posted_data[ $meta_key ] );
}
}
}
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/wp-includes/default-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -719,4 +719,7 @@
// CPT wp_block custom postmeta field.
add_action( 'init', 'wp_create_initial_post_meta' );

// Including revisioned meta when considering whether a post revision has changed.
add_filter( 'wp_save_post_revision_post_has_changed', 'wp_check_revisioned_meta_fields_have_changed' ), 10, 3 );

unset( $filter, $action );
139 changes: 139 additions & 0 deletions src/wp-includes/revision.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,34 @@ function _wp_put_post_revision( $post = null, $autosave = false ) {
* @param int $revision_id Post revision ID.
*/
do_action( '_wp_put_post_revision', $revision_id );

// Save any revisioned meta fields.
wp_save_revisioned_meta_fields( $revision_id );
}

return $revision_id;
}


/**
* Save the revisioned meta fields.
*
* @param int $revision_id The ID of the revision to save the meta to.
*
* @since 6.4.0
*/
function wp_save_revisioned_meta_fields( $revision_id ) {
$revision = get_post( $revision_id );
$post_id = $revision->post_parent;

// Save revisioned meta fields.
foreach ( wp_post_revision_meta_keys() as $meta_key ) {
if ( metadata_exists( 'post', $post_id, $meta_key ) ) {
_wp_copy_post_meta( $post_id, $revision_id, $meta_key );
}
}
}

/**
* Gets a post revision.
*
Expand Down Expand Up @@ -450,6 +473,9 @@ function wp_restore_post_revision( $revision, $fields = null ) {
// Update last edit user.
update_post_meta( $post_id, '_edit_last', get_current_user_id() );

// Restore any revisioned meta fields.
wp_restore_post_revision_meta( $post_id, $revision['ID'] );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we do this

add_action( 'wp_restore_post_revision', 'wp_restore_post_revision_meta', 10, 2 );

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea, let me check.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Added in 95508d9 (#4859)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamsilverstein Has this been addressed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this is added

Comment on lines +503 to +504
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Restore any revisioned meta fields.
wp_restore_post_revision_meta( $post_id, $revision['ID'] );

@adamsilverstein This is not need anymore, as it hooked in the next line.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏼 will commit in a follow up


/**
* Fires after a post revision has been restored.
*
Expand All @@ -463,6 +489,83 @@ function wp_restore_post_revision( $revision, $fields = null ) {
return $post_id;
}

/**
* Restore the revisioned meta values for a post.
*
* @param int $post_id The ID of the post to restore the meta to.
* @param int $revision_id The ID of the revision to restore the meta from.
*
* @since 6.4.0
*/
function wp_restore_post_revision_meta( $post_id, $revision_id ) {

// Restore revisioned meta fields.
foreach ( (array) wp_post_revision_meta_keys() as $meta_key ) {

// Clear any existing meta.
delete_post_meta( $post_id, $meta_key );

_wp_copy_post_meta( $revision_id, $post_id, $meta_key );
}
}

/**
* Copy post meta for the given key from one post to another.
*
* @param int $source_post_id Post ID to copy meta value(s) from.
* @param int $target_post_id Post ID to copy meta value(s) to.
* @param string $meta_key Meta key to copy.
*
* @since 6.4.0
*/
function _wp_copy_post_meta( $source_post_id, $target_post_id, $meta_key ) {

foreach ( get_post_meta( $source_post_id, $meta_key ) as $meta_value ) {
Copy link
Member Author

@adamsilverstein adamsilverstein Sep 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spacedmonkey - I think the same issue for defaults applies here. If a default is set for a meta field, this code will copy the default value over instead of the actual (missing) value, which is unintentional. switching is to get_metadata_raw as well (although may have been prefented by check for existence of meta in calling function)

Copy link
Member Author

@adamsilverstein adamsilverstein Sep 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing this to get_metadata_raw( 'post', $source_post_id, $meta_key = '' ) broke numerous revision group tests so leaving as is. Could use more investigation, in any case this function is not called when the meta value is not set.

/**
* We use add_metadata() function vs add_post_meta() here
* to allow for a revision post target OR regular post.
*/
add_metadata( 'post', $target_post_id, $meta_key, wp_slash( $meta_value ) );
}
}

/**
* Determine which post meta fields should be revisioned.
*
* @since 6.4.0
*
* @return array An array of meta keys to be revisioned.
*/
function wp_post_revision_meta_keys() {
/**
* Filter the list of post meta keys to be revisioned.
*
* @since 6.4.0
*
* @param array $keys An array of default meta fields to be revisioned.
*/
return apply_filters( 'wp_post_revision_meta_keys', array( 'footnotes' ) ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
}

/**
* Check whether revisioned post meta fields have changed.
*
* @param bool $post_has_changed Whether the post has changed.
* @param WP_Post $last_revision The last revision post object.
* @param WP_Post $post The post object.
*
* @since 6.4.0
*/
function wp_check_revisioned_meta_fields_have_changed( $post_has_changed, WP_Post $last_revision, WP_Post $post ) {
foreach ( wp_post_revision_meta_keys() as $meta_key ) {
if ( get_post_meta( $post->ID, $meta_key ) !== get_post_meta( $last_revision->ID, $meta_key ) ) {
$post_has_changed = true;
break;
}
}
return $post_has_changed;
}

/**
* Deletes a revision.
*
Expand Down Expand Up @@ -728,6 +831,7 @@ function _set_preview( $post ) {

add_filter( 'get_the_terms', '_wp_preview_terms_filter', 10, 3 );
add_filter( 'get_post_metadata', '_wp_preview_post_thumbnail_filter', 10, 3 );
add_filter( 'get_post_metadata', '_wp_preview_meta_filter', 10, 4 );

return $post;
}
Expand Down Expand Up @@ -948,3 +1052,38 @@ function _wp_upgrade_revisions_of_post( $post, $revisions ) {

return true;
}

/**
* Filters preview post meta retrieval to get values from the autosave.
*
* Filters revisioned meta keys only.
*
* @since 6.4.0
*
* @param mixed $value Meta value to filter.
* @param int $object_id Object ID.
* @param string $meta_key Meta key to filter a value for.
* @param bool $single Whether to return a single value. Default false.
* @return mixed Original meta value if the meta key isn't revisioned, the object doesn't exist,
* the post type is a revision or the post ID doesn't match the object ID.
* Otherwise, the revisioned meta value is returned for the preview.
*/
function _wp_preview_meta_filter( $value, $object_id, $meta_key, $single ) {

$post = get_post();
if (
empty( $post ) ||
$post->ID !== $object_id ||
! in_array( $meta_key, wp_post_revision_meta_keys(), true ) ||
'revision' === $post->post_type
) {
return $value;
}

$preview = wp_get_post_autosave( $post->ID );
if ( ! is_object( $preview ) ) {
return $value;
}

return get_post_meta( $preview->ID, $meta_key, $single );
}