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.