Make WordPress Core

Changeset 49125


Ignore:
Timestamp:
10/11/2020 01:37:04 PM (4 years ago)
Author:
johnbillion
Message:

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

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/edit.php

    r48352 r49125  
    135135        case 'untrash':
    136136            $untrashed = 0;
     137
     138            if ( isset( $_GET['doaction'] ) && ( 'undo' === $_GET['doaction'] ) ) {
     139                add_filter( 'wp_untrash_post_status', 'wp_untrash_post_set_previous_status', 10, 3 );
     140            }
     141
    137142            foreach ( (array) $post_ids as $post_id ) {
    138143                if ( ! current_user_can( 'delete_post', $post_id ) ) {
     
    147152            }
    148153            $sendback = add_query_arg( 'untrashed', $untrashed, $sendback );
     154
     155            remove_filter( 'wp_untrash_post_status', 'wp_untrash_post_set_previous_status', 10, 3 );
     156
    149157            break;
    150158        case 'delete':
     
    420428        $messages[] = '<a href="' . esc_url( wp_nonce_url( "edit.php?post_type=$post_type&doaction=undo&action=untrash&ids=$ids", 'bulk-posts' ) ) . '">' . __( 'Undo' ) . '</a>';
    421429    }
     430
     431    if ( 'untrashed' === $message && isset( $_REQUEST['ids'] ) ) {
     432        $ids = explode( ',', $_REQUEST['ids'] );
     433
     434        if ( 1 === count( $ids ) && current_user_can( 'edit_post', $ids[0] ) ) {
     435            $messages[] = sprintf(
     436                '<a href="%1$s">%2$s</a>',
     437                esc_url( get_edit_post_link( $ids[0] ) ),
     438                esc_html( get_post_type_object( get_post_type( $ids[0] ) )->labels->edit_item )
     439            );
     440        }
     441    }
    422442}
    423443
  • trunk/src/wp-admin/post.php

    r48312 r49125  
    292292        }
    293293
    294         wp_redirect( add_query_arg( 'untrashed', 1, $sendback ) );
     294        $sendback = add_query_arg(
     295            array(
     296                'untrashed' => 1,
     297                'ids'       => $post_id,
     298            ),
     299            $sendback
     300        );
     301        wp_redirect( $sendback );
    295302        exit;
    296303
  • trunk/src/wp-includes/functions.php

    r49108 r49125  
    11941194        'hotkeys_highlight_first',
    11951195        'hotkeys_highlight_last',
     1196        'ids',
    11961197        'locked',
    11971198        'message',
  • trunk/src/wp-includes/post.php

    r49108 r49125  
    32343234
    32353235/**
    3236  * Restore a post or page from the Trash.
     3236 * Restores a post from the Trash.
    32373237 *
    32383238 * @since 2.9.0
    3239  *
    3240  * @param int $post_id Optional. Post ID. Default is ID of the global $post.
     3239 * @since 5.6.0 An untrashed post is now returned to 'draft' status by default, except for
     3240 *              attachments which are returned to their original 'inherit' status.
     3241 *
     3242 * @param int $post_id Optional. Post ID. Default is ID of the global `$post`.
    32413243 * @return WP_Post|false|null Post data on success, false or null on failure.
    32423244 */
     
    32483250    }
    32493251
     3252    $post_id = $post->ID;
     3253
    32503254    if ( 'trash' !== $post->post_status ) {
    32513255        return false;
    32523256    }
    32533257
     3258    $previous_status = get_post_meta( $post_id, '_wp_trash_meta_status', true );
     3259
    32543260    /**
    32553261     * Filters whether a post untrashing should take place.
    32563262     *
    32573263     * @since 4.9.0
    3258      *
    3259      * @param bool|null $untrash Whether to go forward with untrashing.
    3260      * @param WP_Post   $post    Post object.
     3264     * @since 5.6.0 The `$previous_status` parameter was added.
     3265     *
     3266     * @param bool|null $untrash         Whether to go forward with untrashing.
     3267     * @param WP_Post   $post            Post object.
     3268     * @param string    $previous_status The status of the post at the point where it was trashed.
    32613269     */
    3262     $check = apply_filters( 'pre_untrash_post', null, $post );
     3270    $check = apply_filters( 'pre_untrash_post', null, $post, $previous_status );
    32633271    if ( null !== $check ) {
    32643272        return $check;
     
    32693277     *
    32703278     * @since 2.9.0
    3271      *
    3272      * @param int $post_id Post ID.
     3279     * @since 5.6.0 The `$previous_status` parameter was added.
     3280     *
     3281     * @param int    $post_id         Post ID.
     3282     * @param string $previous_status The status of the post at the point where it was trashed.
    32733283     */
    3274     do_action( 'untrash_post', $post_id );
    3275 
    3276     $post_status = get_post_meta( $post_id, '_wp_trash_meta_status', true );
     3284    do_action( 'untrash_post', $post_id, $previous_status );
     3285
     3286    $new_status = ( 'attachment' === $post->post_type ) ? 'inherit' : 'draft';
     3287
     3288    /**
     3289     * Filters the status that a post gets assigned when it is restored from the trash (untrashed).
     3290     *
     3291     * By default posts that are restored will be assigned a status of 'draft'. Return the value of `$previous_status`
     3292     * in order to assign the status that the post had before it was trashed. The `wp_untrash_post_set_previous_status()`
     3293     * function is available for this.
     3294     *
     3295     * Prior to WordPress 5.6.0, restored posts were always assigned their original status.
     3296     *
     3297     * @since 5.6.0
     3298     *
     3299     * @param string $new_status      The new status of the post being restored.
     3300     * @param int    $post_id         The ID of the post being restored.
     3301     * @param string $previous_status The status of the post at the point where it was trashed.
     3302     */
     3303    $post_status = apply_filters( 'wp_untrash_post_status', $new_status, $post_id, $previous_status );
    32773304
    32783305    delete_post_meta( $post_id, '_wp_trash_meta_status' );
     
    32963323     *
    32973324     * @since 2.9.0
    3298      *
    3299      * @param int $post_id Post ID.
     3325     * @since 5.6.0 The `$previous_status` parameter was added.
     3326     *
     3327     * @param int    $post_id         Post ID.
     3328     * @param string $previous_status The status of the post at the point where it was trashed.
    33003329     */
    3301     do_action( 'untrashed_post', $post_id );
     3330    do_action( 'untrashed_post', $post_id, $previous_status );
    33023331
    33033332    return $post;
     
    75147543    return apply_filters( 'wp_get_original_image_url', $original_image_url, $attachment_id );
    75157544}
     7545
     7546/**
     7547 * Filter callback which sets the status of an untrashed post to its previous status.
     7548 *
     7549 * This can be used as a callback on the `wp_untrash_post_status` filter.
     7550 *
     7551 * @since 5.6.0
     7552 *
     7553 * @param string $new_status      The new status of the post being restored.
     7554 * @param int    $post_id         The ID of the post being restored.
     7555 * @param string $previous_status The status of the post at the point where it was trashed.
     7556 * @return string The new status of the post.
     7557 */
     7558function wp_untrash_post_set_previous_status( $new_status, $post_id, $previous_status ) {
     7559    return $previous_status;
     7560}
  • trunk/tests/phpunit/tests/post/wpInsertPost.php

    r48937 r49125  
    160160
    161161        wp_untrash_post( $about_page_id );
     162        wp_update_post(
     163            array(
     164                'ID'          => $about_page_id,
     165                'post_status' => 'publish',
     166            )
     167        );
    162168
    163169        $this->assertSame( 'about', get_post( $another_about_page_id )->post_name );
     
    166172
    167173    /**
     174     * @ticket 23022
     175     * @dataProvider data_various_post_statuses
     176     */
     177    function test_untrashing_a_post_should_always_restore_it_to_draft_status( $post_status ) {
     178        $page_id = self::factory()->post->create(
     179            array(
     180                'post_type'   => 'page',
     181                'post_status' => $post_status,
     182            )
     183        );
     184
     185        wp_trash_post( $page_id );
     186        wp_untrash_post( $page_id );
     187
     188        $this->assertSame( 'draft', get_post( $page_id )->post_status );
     189    }
     190
     191    /**
     192     * @ticket 23022
     193     * @dataProvider data_various_post_statuses
     194     */
     195    function test_wp_untrash_post_status_filter_restores_post_to_correct_status( $post_status ) {
     196        add_filter( 'wp_untrash_post_status', 'wp_untrash_post_set_previous_status', 10, 3 );
     197
     198        $page_id = self::factory()->post->create(
     199            array(
     200                'post_type'   => 'page',
     201                'post_status' => $post_status,
     202            )
     203        );
     204
     205        wp_trash_post( $page_id );
     206        wp_untrash_post( $page_id );
     207
     208        remove_filter( 'wp_untrash_post_status', 'wp_untrash_post_set_previous_status', 10, 3 );
     209
     210        $this->assertSame( $post_status, get_post( $page_id )->post_status );
     211    }
     212
     213    /**
    168214     * Data for testing the ability for users to set the post slug.
    169215     *
     
    180226            array(
    181227                'post',
     228            ),
     229        );
     230    }
     231
     232    /**
     233     * Data for testing post statuses.
     234     *
     235     * @return array Array of test arguments.
     236     */
     237    function data_various_post_statuses() {
     238        return array(
     239            array(
     240                'draft',
     241            ),
     242            array(
     243                'pending',
     244            ),
     245            array(
     246                'private',
     247            ),
     248            array(
     249                'publish',
    182250            ),
    183251        );
Note: See TracChangeset for help on using the changeset viewer.