Skip to content
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: store in revisions #52686

Merged
merged 9 commits into from
Jul 19, 2023
Merged
Changes from 6 commits
Commits
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
111 changes: 111 additions & 0 deletions packages/block-library/src/footnotes/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,114 @@ function register_block_core_footnotes() {
);
}
add_action( 'init', 'register_block_core_footnotes' );

/**
* Saves the footnotes meta value to the revision.
*
* @param int $revision_id The revision ID.
*/
function gutenberg_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', $footnotes );
}
}
}
add_action( 'wp_after_insert_post', 'gutenberg_save_footnotes_meta' );

/**
* Keeps track of the revision ID for "rest_after_insert_{$post_type}".
*
* @param int $revision_id The revision ID.
*/
function gutenberg_wp_put_post_revision( $revision_id ) {
global $_gutenberg_revision_id;
$_gutenberg_revision_id = $revision_id;
}

add_action( '_wp_put_post_revision', 'gutenberg_wp_put_post_revision' );

/**
* 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.
*
* @param WP_Post $post The post object.
*/
function gutenberg_save_footnotes_meta_rest_api( $post ) {
global $_gutenberg_revision_id;

if ( $_gutenberg_revision_id ) {
$revision = get_post( $_gutenberg_revision_id );
$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', $_gutenberg_revision_id, 'footnotes', $footnotes );
}
}
}
}

foreach ( array( 'post', 'page' ) as $post_type ) {
add_action( "rest_after_insert_{$post_type}", 'gutenberg_save_footnotes_meta_rest_api' );
}

/**
* Restores the footnotes meta value from the revision.
*
* @param int $post_id The post ID.
* @param int $revision_id The revision ID.
*/
function gutenberg_restore_footnotes_meta( $post_id, $revision_id ) {
$footnotes = get_post_meta( $revision_id, 'footnotes', true );

if ( $footnotes ) {
update_post_meta( $post_id, 'footnotes', $footnotes );
} else {
delete_post_meta( $post_id, 'footnotes' );
}
}
add_action( 'wp_restore_post_revision', 'gutenberg_restore_footnotes_meta', 10, 2 );

/**
* Adds the footnotes field to the revision.
*
* @param array $fields The revision fields.
*
* @return array The revision fields.
*/
function gutenberg_revision_fields( $fields ) {
$fields['footnotes'] = __( 'Footnotes' );
return $fields;
}
add_filter( '_wp_post_revision_fields', 'gutenberg_revision_fields' );

/**
* Gets the footnotes field from the revision.
*
* @param string $revision_field The field value, but $revision->$field
* (footnotes) does not exist.
* @param string $field The field name, in this case "footnotes".
* @param object $revision The revision object to compare against.
*
* @return string The field value.
*/
function gutenberg_revision_field_footnotes( $revision_field, $field, $revision ) {
return get_metadata( 'post', $revision->ID, $field, true );
}
add_filter( 'wp_post_revision_field_footnotes', 'gutenberg_revision_field_footnotes' );