-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Footnotes: use core’s meta revisioning if available #52988
Merged
adamsilverstein
merged 29 commits into
WordPress:trunk
from
adamsilverstein:redo-footnote-revisioning
Sep 29, 2023
Merged
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
8a169de
Footnotes: use core’s meta revisioning if available
adamsilverstein f8c55c2
Merge branch 'trunk' into redo-footnote-revisioning
adamsilverstein 59bc54f
Ensure preview menu is closed after opening preview
adamsilverstein fd9d4a0
Improve docs and add some new conditionals
adamsilverstein c18cae0
Add test to verify published post meta is unchanged when previewing m…
adamsilverstein 7d944d2
Correct overwriting of live published post meta when previewing
adamsilverstein fb6d61e
Comment out tests that require core changes to pass
adamsilverstein c91b95b
Merge branch 'trunk' into redo-footnote-revisioning
adamsilverstein d7a96e1
Include test to verify published post uneffected when previewing meta…
adamsilverstein a67bc45
Global styles tests: fire hooks when updating post
adamsilverstein 9b1115d
Improve published post navigation in test
adamsilverstein 037eb5a
Comment out failing test for published post
adamsilverstein 766a777
Remove incorrect comment line
adamsilverstein cb37c48
Try: remove filters present in core already
adamsilverstein 10edd9c
Merge branch 'trunk' into redo-footnote-revisioning
adamsilverstein c580c79
Move footnote filter shim to an external compat file
adamsilverstein 82ad972
phpcbf
adamsilverstein 9d2f120
Remove remaining hooks from footnotes that are causing issues
adamsilverstein 1109df2
Revert "Remove remaining hooks from footnotes that are causing issues"
adamsilverstein 7fee4f5
Temporarily disable slashing test
adamsilverstein 2a55084
Restore test to verify that the published post is unchanged after pre…
adamsilverstein 352bba5
Move the meta revision compat code to the footnotes shim file
adamsilverstein de6882c
remove hooks from footnotes file
adamsilverstein 95f6b42
Ensure functions are guarded against redeclaration.
adamsilverstein a8e98f6
phpcbf
adamsilverstein 90057fc
phpcbf2
adamsilverstein c614958
restore typing “3”
adamsilverstein 90d7472
remove extra space
adamsilverstein 6a4f28b
Restore slashed data test
adamsilverstein File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
<?php | ||
/** | ||
* Compatibility shim for the footnotes bloct to enable test passing while awaiting the tested code to be merged to core. | ||
* | ||
* See https://github.com/WordPress/gutenberg/pull/52988. | ||
* | ||
* Once merged, this shim can be removed. | ||
* | ||
* @package gutenberg | ||
*/ | ||
|
||
/** | ||
* Remove footnote revision hooks when plugin is running on a version of core that already supports meta revisions. | ||
*/ | ||
if ( function_exists( 'wp_post_revision_meta_keys' ) ) { | ||
if ( has_action( 'rest_after_insert_post', 'wp_add_footnotes_revisions_to_post_meta' ) ) { | ||
remove_action( 'rest_after_insert_post', 'wp_add_footnotes_revisions_to_post_meta' ); | ||
} | ||
if ( has_action( 'rest_after_insert_page', 'wp_add_footnotes_revisions_to_post_meta' ) ) { | ||
remove_action( 'rest_after_insert_page', 'wp_add_footnotes_revisions_to_post_meta' ); | ||
} | ||
if ( has_action( 'wp_after_insert_post', 'wp_save_footnotes_meta' ) ) { | ||
remove_action( 'wp_after_insert_post', 'wp_save_footnotes_meta' ); | ||
} | ||
if ( has_action( '_wp_put_post_revision', 'wp_keep_footnotes_revision_id' ) ) { | ||
remove_action( '_wp_put_post_revision', 'wp_keep_footnotes_revision_id' ); | ||
} | ||
if ( has_action( 'wp_restore_post_revision', 'wp_restore_footnotes_from_revision' ) ) { | ||
remove_action( 'wp_restore_post_revision', 'wp_restore_footnotes_from_revision' ); | ||
} | ||
if ( has_action( 'wp_creating_autosave', '_wp_rest_api_autosave_meta' ) ) { | ||
remove_action( 'wp_creating_autosave', '_wp_rest_api_autosave_meta' ); | ||
} | ||
if ( has_action( '_wp_put_post_revision', '_wp_rest_api_autosave_meta' ) ) { | ||
remove_action( '_wp_put_post_revision', '_wp_rest_api_autosave_meta' ); | ||
} | ||
if ( has_filter( 'rest_pre_insert_post', '_wp_rest_api_force_autosave_difference' ) ) { | ||
remove_filter( 'rest_pre_insert_post', '_wp_rest_api_force_autosave_difference' ); | ||
} | ||
} else { | ||
/** | ||
* For versions of core that don't support meta revisions, use hooks to add. | ||
*/ | ||
if ( ! function_exists( 'wp_save_footnotes_meta' ) ) { | ||
/** | ||
* Saves the footnotes meta value to the revision. | ||
* | ||
* @since 6.3.0 | ||
* @since 6.4.0 Core added post meta revisions, so this is no longer needed. | ||
* | ||
* @param int $revision_id The revision ID. | ||
*/ | ||
function wp_save_footnotes_meta( $revision_id ) { | ||
$post_id = wp_is_post_revision( $revision_id ); | ||
|
||
if ( $post_id ) { | ||
$footnotes = get_post_meta( $post_id, 'footnotes', true ); | ||
|
||
if ( $footnotes ) { | ||
// Can't use update_post_meta() because it doesn't allow revisions. | ||
update_metadata( 'post', $revision_id, 'footnotes', wp_slash( $footnotes ) ); | ||
} | ||
} | ||
} | ||
if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) { | ||
add_action( 'wp_after_insert_post', 'wp_save_footnotes_meta' ); | ||
} | ||
} | ||
|
||
if ( ! function_exists( 'wp_keep_footnotes_revision_id' ) ) { | ||
/** | ||
* Keeps track of the revision ID for "rest_after_insert_{$post_type}". | ||
* | ||
* @since 6.3.0 | ||
* @since 6.4.0 Core added post meta revisions, so this is no longer needed. | ||
* | ||
* @global int $wp_temporary_footnote_revision_id The footnote revision ID. | ||
* | ||
* @param int $revision_id The revision ID. | ||
*/ | ||
function wp_keep_footnotes_revision_id( $revision_id ) { | ||
global $wp_temporary_footnote_revision_id; | ||
$wp_temporary_footnote_revision_id = $revision_id; | ||
} | ||
if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) { | ||
add_action( '_wp_put_post_revision', 'wp_keep_footnotes_revision_id' ); | ||
} | ||
} | ||
|
||
if ( ! function_exists( 'wp_add_footnotes_revisions_to_post_meta' ) ) { | ||
|
||
/** | ||
* This is a specific fix for the REST API. The REST API doesn't update | ||
* the post and post meta in one go (through `meta_input`). While it | ||
* does fix the `wp_after_insert_post` hook to be called correctly after | ||
* updating meta, it does NOT fix hooks such as post_updated and | ||
* save_post, which are normally also fired after post meta is updated | ||
* in `wp_insert_post()`. Unfortunately, `wp_save_post_revision` is | ||
* added to the `post_updated` action, which means the meta is not | ||
* available at the time, so we have to add it afterwards through the | ||
* `"rest_after_insert_{$post_type}"` action. | ||
* | ||
* @since 6.3.0 | ||
* @since 6.4.0 Core added post meta revisions, so this is no longer needed. | ||
* | ||
* @global int $wp_temporary_footnote_revision_id The footnote revision ID. | ||
* | ||
* @param WP_Post $post The post object. | ||
*/ | ||
function wp_add_footnotes_revisions_to_post_meta( $post ) { | ||
global $wp_temporary_footnote_revision_id; | ||
|
||
if ( $wp_temporary_footnote_revision_id ) { | ||
$revision = get_post( $wp_temporary_footnote_revision_id ); | ||
|
||
if ( ! $revision ) { | ||
return; | ||
} | ||
|
||
$post_id = $revision->post_parent; | ||
|
||
// Just making sure we're updating the right revision. | ||
if ( $post->ID === $post_id ) { | ||
$footnotes = get_post_meta( $post_id, 'footnotes', true ); | ||
|
||
if ( $footnotes ) { | ||
// Can't use update_post_meta() because it doesn't allow revisions. | ||
update_metadata( 'post', $wp_temporary_footnote_revision_id, 'footnotes', wp_slash( $footnotes ) ); | ||
} | ||
} | ||
} | ||
} | ||
|
||
if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) { | ||
add_action( 'rest_after_insert_post', 'wp_add_footnotes_revisions_to_post_meta' ); | ||
add_action( 'rest_after_insert_page', 'wp_add_footnotes_revisions_to_post_meta' ); | ||
} | ||
} | ||
|
||
if ( ! function_exists( 'wp_restore_footnotes_from_revision' ) ) { | ||
|
||
/** | ||
* Restores the footnotes meta value from the revision. | ||
* | ||
* @since 6.3.0 | ||
* @since 6.4.0 Core added post meta revisions, so this is no longer needed. | ||
* | ||
* @param int $post_id The post ID. | ||
* @param int $revision_id The revision ID. | ||
*/ | ||
function wp_restore_footnotes_from_revision( $post_id, $revision_id ) { | ||
$footnotes = get_post_meta( $revision_id, 'footnotes', true ); | ||
|
||
if ( $footnotes ) { | ||
update_post_meta( $post_id, 'footnotes', wp_slash( $footnotes ) ); | ||
} else { | ||
delete_post_meta( $post_id, 'footnotes' ); | ||
} | ||
} | ||
if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) { | ||
add_action( 'wp_restore_post_revision', 'wp_restore_footnotes_from_revision', 10, 2 ); | ||
} | ||
} | ||
|
||
if ( ! function_exists( '_wp_rest_api_autosave_meta' ) ) { | ||
|
||
/** | ||
* The REST API autosave endpoint doesn't save meta, so we can use the | ||
* `wp_creating_autosave` when it updates an exiting autosave, and | ||
* `_wp_put_post_revision` when it creates a new autosave. | ||
* | ||
* @since 6.3.0 | ||
* @since 6.4.0 Core added post meta revisions, so this is no longer needed. | ||
* | ||
* @param int|array $autosave The autosave ID or array. | ||
*/ | ||
function _wp_rest_api_autosave_meta( $autosave ) { | ||
// Ensure it's a REST API request. | ||
if ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) { | ||
return; | ||
} | ||
|
||
$body = rest_get_server()->get_raw_data(); | ||
$body = json_decode( $body, true ); | ||
|
||
if ( ! isset( $body['meta']['footnotes'] ) ) { | ||
return; | ||
} | ||
|
||
// `wp_creating_autosave` passes the array, | ||
// `_wp_put_post_revision` passes the ID. | ||
$id = is_int( $autosave ) ? $autosave : $autosave['ID']; | ||
|
||
if ( ! $id ) { | ||
return; | ||
} | ||
|
||
// Can't use update_post_meta() because it doesn't allow revisions. | ||
update_metadata( 'post', $id, 'footnotes', wp_slash( $body['meta']['footnotes'] ) ); | ||
} | ||
|
||
if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) { | ||
// See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L391C1-L391C1. | ||
add_action( 'wp_creating_autosave', '_wp_rest_api_autosave_meta' ); | ||
// See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L398. | ||
// Then https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/revision.php#L367. | ||
add_action( '_wp_put_post_revision', '_wp_rest_api_autosave_meta' ); | ||
} | ||
} | ||
|
||
if ( ! function_exists( '_wp_rest_api_force_autosave_difference' ) ) { | ||
|
||
/** | ||
* This is a workaround for the autosave endpoint returning early if the | ||
* revision field are equal. The problem is that "footnotes" is not real | ||
* revision post field, so there's nothing to compare against. | ||
* | ||
* This trick sets the "footnotes" field (value doesn't matter), which will | ||
* cause the autosave endpoint to always update the latest revision. That should | ||
* be fine, it should be ok to update the revision even if nothing changed. Of | ||
* course, this is temporary fix. | ||
* | ||
* @since 6.3.0 | ||
* @since 6.4.0 Core added post meta revisions, so this is no longer needed. | ||
* | ||
* @param WP_Post $prepared_post The prepared post object. | ||
* @param WP_REST_Request $request The request object. | ||
* | ||
* See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L365-L384. | ||
* See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L219. | ||
*/ | ||
function _wp_rest_api_force_autosave_difference( $prepared_post, $request ) { | ||
// We only want to be altering POST requests. | ||
if ( $request->get_method() !== 'POST' ) { | ||
return $prepared_post; | ||
} | ||
|
||
// Only alter requests for the '/autosaves' route. | ||
if ( substr( $request->get_route(), -strlen( '/autosaves' ) ) !== '/autosaves' ) { | ||
return $prepared_post; | ||
} | ||
|
||
$prepared_post->footnotes = '[]'; | ||
return $prepared_post; | ||
} | ||
if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) { | ||
add_filter( 'rest_pre_insert_post', '_wp_rest_api_force_autosave_difference', 10, 2 ); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ellatrix If I'm not wrong this file should be moved to
lib/compat/wordpress-6.4
because it's just here to support versions priori to 6.4 right?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, although maybe I don't think these make sense anymore after the revision support was added. Cc @adamsilverstein