From bd1fa2d998fc30228031222468ada7682f64ccb3 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 11 Oct 2020 13:39:07 +0000 Subject: [PATCH] Posts, Post Types: Switch to restoring posts to `draft` status by default when they are untrashed. This allows for edits to be made to a restored post before it goes live again. This also prevents scheduled posts being published unexpectedly if they are untrashed after their originally scheduled date. The old behaviour of restoring untrashed posts to their original status can be reinstated using the `wp_untrash_post_set_previous_status()` helper function. Also fixes an issue where the incorrect post ID gets passed to hooks if no post ID is passed to the function. Props harrym, bananastalktome, jaredcobb, chriscct7, melchoyce, johnbillion, pankajmohale Fixes #23022 Built from https://develop.svn.wordpress.org/trunk@49125 git-svn-id: http://core.svn.wordpress.org/trunk@48887 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/edit.php | 20 ++++++++++++ wp-admin/post.php | 9 +++++- wp-includes/functions.php | 1 + wp-includes/post.php | 65 +++++++++++++++++++++++++++++++++------ wp-includes/version.php | 2 +- 5 files changed, 85 insertions(+), 12 deletions(-) diff --git a/wp-admin/edit.php b/wp-admin/edit.php index 35aca175d4..68786f0f8c 100644 --- a/wp-admin/edit.php +++ b/wp-admin/edit.php @@ -134,6 +134,11 @@ if ( $doaction ) { break; case 'untrash': $untrashed = 0; + + if ( isset( $_GET['doaction'] ) && ( 'undo' === $_GET['doaction'] ) ) { + add_filter( 'wp_untrash_post_status', 'wp_untrash_post_set_previous_status', 10, 3 ); + } + foreach ( (array) $post_ids as $post_id ) { if ( ! current_user_can( 'delete_post', $post_id ) ) { wp_die( __( 'Sorry, you are not allowed to restore this item from the Trash.' ) ); @@ -146,6 +151,9 @@ if ( $doaction ) { $untrashed++; } $sendback = add_query_arg( 'untrashed', $untrashed, $sendback ); + + remove_filter( 'wp_untrash_post_status', 'wp_untrash_post_set_previous_status', 10, 3 ); + break; case 'delete': $deleted = 0; @@ -419,6 +427,18 @@ foreach ( $bulk_counts as $message => $count ) { $ids = preg_replace( '/[^0-9,]/', '', $_REQUEST['ids'] ); $messages[] = '' . __( 'Undo' ) . ''; } + + if ( 'untrashed' === $message && isset( $_REQUEST['ids'] ) ) { + $ids = explode( ',', $_REQUEST['ids'] ); + + if ( 1 === count( $ids ) && current_user_can( 'edit_post', $ids[0] ) ) { + $messages[] = sprintf( + '%2$s', + esc_url( get_edit_post_link( $ids[0] ) ), + esc_html( get_post_type_object( get_post_type( $ids[0] ) )->labels->edit_item ) + ); + } + } } if ( $messages ) { diff --git a/wp-admin/post.php b/wp-admin/post.php index 759e4b6b93..c4a0ab17e5 100644 --- a/wp-admin/post.php +++ b/wp-admin/post.php @@ -291,7 +291,14 @@ switch ( $action ) { wp_die( __( 'Error in restoring the item from Trash.' ) ); } - wp_redirect( add_query_arg( 'untrashed', 1, $sendback ) ); + $sendback = add_query_arg( + array( + 'untrashed' => 1, + 'ids' => $post_id, + ), + $sendback + ); + wp_redirect( $sendback ); exit; case 'delete': diff --git a/wp-includes/functions.php b/wp-includes/functions.php index 3f6864368c..f46fc6ea65 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -1193,6 +1193,7 @@ function wp_removable_query_args() { 'error', 'hotkeys_highlight_first', 'hotkeys_highlight_last', + 'ids', 'locked', 'message', 'same', diff --git a/wp-includes/post.php b/wp-includes/post.php index 293461e9ed..71161f4cab 100644 --- a/wp-includes/post.php +++ b/wp-includes/post.php @@ -3233,11 +3233,13 @@ function wp_trash_post( $post_id = 0 ) { } /** - * Restore a post or page from the Trash. + * Restores a post from the Trash. * * @since 2.9.0 + * @since 5.6.0 An untrashed post is now returned to 'draft' status by default, except for + * attachments which are returned to their original 'inherit' status. * - * @param int $post_id Optional. Post ID. Default is ID of the global $post. + * @param int $post_id Optional. Post ID. Default is ID of the global `$post`. * @return WP_Post|false|null Post data on success, false or null on failure. */ function wp_untrash_post( $post_id = 0 ) { @@ -3247,19 +3249,25 @@ function wp_untrash_post( $post_id = 0 ) { return $post; } + $post_id = $post->ID; + if ( 'trash' !== $post->post_status ) { return false; } + $previous_status = get_post_meta( $post_id, '_wp_trash_meta_status', true ); + /** * Filters whether a post untrashing should take place. * * @since 4.9.0 + * @since 5.6.0 The `$previous_status` parameter was added. * - * @param bool|null $untrash Whether to go forward with untrashing. - * @param WP_Post $post Post object. + * @param bool|null $untrash Whether to go forward with untrashing. + * @param WP_Post $post Post object. + * @param string $previous_status The status of the post at the point where it was trashed. */ - $check = apply_filters( 'pre_untrash_post', null, $post ); + $check = apply_filters( 'pre_untrash_post', null, $post, $previous_status ); if ( null !== $check ) { return $check; } @@ -3268,12 +3276,31 @@ function wp_untrash_post( $post_id = 0 ) { * Fires before a post is restored from the Trash. * * @since 2.9.0 + * @since 5.6.0 The `$previous_status` parameter was added. * - * @param int $post_id Post ID. + * @param int $post_id Post ID. + * @param string $previous_status The status of the post at the point where it was trashed. */ - do_action( 'untrash_post', $post_id ); + do_action( 'untrash_post', $post_id, $previous_status ); - $post_status = get_post_meta( $post_id, '_wp_trash_meta_status', true ); + $new_status = ( 'attachment' === $post->post_type ) ? 'inherit' : 'draft'; + + /** + * Filters the status that a post gets assigned when it is restored from the trash (untrashed). + * + * By default posts that are restored will be assigned a status of 'draft'. Return the value of `$previous_status` + * in order to assign the status that the post had before it was trashed. The `wp_untrash_post_set_previous_status()` + * function is available for this. + * + * Prior to WordPress 5.6.0, restored posts were always assigned their original status. + * + * @since 5.6.0 + * + * @param string $new_status The new status of the post being restored. + * @param int $post_id The ID of the post being restored. + * @param string $previous_status The status of the post at the point where it was trashed. + */ + $post_status = apply_filters( 'wp_untrash_post_status', $new_status, $post_id, $previous_status ); delete_post_meta( $post_id, '_wp_trash_meta_status' ); delete_post_meta( $post_id, '_wp_trash_meta_time' ); @@ -3295,10 +3322,12 @@ function wp_untrash_post( $post_id = 0 ) { * Fires after a post is restored from the Trash. * * @since 2.9.0 + * @since 5.6.0 The `$previous_status` parameter was added. * - * @param int $post_id Post ID. + * @param int $post_id Post ID. + * @param string $previous_status The status of the post at the point where it was trashed. */ - do_action( 'untrashed_post', $post_id ); + do_action( 'untrashed_post', $post_id, $previous_status ); return $post; } @@ -7513,3 +7542,19 @@ function wp_get_original_image_url( $attachment_id ) { */ return apply_filters( 'wp_get_original_image_url', $original_image_url, $attachment_id ); } + +/** + * Filter callback which sets the status of an untrashed post to its previous status. + * + * This can be used as a callback on the `wp_untrash_post_status` filter. + * + * @since 5.6.0 + * + * @param string $new_status The new status of the post being restored. + * @param int $post_id The ID of the post being restored. + * @param string $previous_status The status of the post at the point where it was trashed. + * @return string The new status of the post. + */ +function wp_untrash_post_set_previous_status( $new_status, $post_id, $previous_status ) { + return $previous_status; +} diff --git a/wp-includes/version.php b/wp-includes/version.php index 6a8aa2067c..ea33d2de3b 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.6-alpha-49124'; +$wp_version = '5.6-alpha-49125'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.