Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
13 changes: 13 additions & 0 deletions src/wp-admin/edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@
++$deleted;
}
$sendback = add_query_arg( 'deleted', $deleted, $sendback );

if ( isset( $_REQUEST['post_status'] ) && 'trash' === $_REQUEST['post_status'] ) {
$post_counts = (array) wp_count_posts( $post_type, 'readable' );
if ( empty( $post_counts['trash'] ) ) {
$sendback = remove_query_arg( array( 'post_status', 'paged' ), $sendback );
}
}
break;
case 'edit':
if ( isset( $_REQUEST['bulk_edit'] ) ) {
Expand Down Expand Up @@ -234,6 +241,12 @@

$wp_list_table->prepare_items();

if ( ! $wp_list_table->has_items() && isset( $_REQUEST['post_status'] ) && 'trash' === $_REQUEST['post_status'] ) {
$sendback = remove_query_arg( array( 'post_status', 'paged' ), wp_unslash( $_SERVER['REQUEST_URI'] ) );
wp_redirect( $sendback );
exit;
}

wp_enqueue_script( 'inline-edit-post' );
wp_enqueue_script( 'heartbeat' );

Expand Down
96 changes: 96 additions & 0 deletions tests/phpunit/tests/admin/testTrashRedirect.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php
/**
* @group admin
*/
class Tests_Admin_TrashRedirect extends WP_UnitTestCase {
protected $admin_user_id;

public function set_up() {
parent::set_up();
$this->admin_user_id = self::factory()->user->create( array( 'role' => 'administrator' ) );
wp_set_current_user( $this->admin_user_id );

// Ensure we are in the admin context.
set_current_screen( 'edit-post' );

// Define ABSPATH if not defined (though it should be in tests).
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', dirname( __DIR__, 4 ) . '/src/' );
}

add_filter( 'wp_redirect', array( $this, 'catch_redirect' ), 1, 1 );
}

public function tear_down() {
remove_filter( 'wp_redirect', array( $this, 'catch_redirect' ), 1 );
parent::tear_down();
}

public function catch_redirect( $location ) {
throw new Tests_Admin_TrashRedirect_Exception( $location );
}

/**
* Test that visiting an empty trash view redirects to all posts view.
*/
public function test_empty_trash_view_redirects_to_all_posts() {
// Mock the request for empty trash.
$_GET['post_status'] = 'trash';
$_GET['post_type'] = 'post';
$_REQUEST['post_status'] = 'trash';
$_SERVER['REQUEST_URI'] = admin_url( 'edit.php?post_status=trash' );

try {
ob_start();
include ABSPATH . 'wp-admin/edit.php';
ob_end_clean();
} catch ( Tests_Admin_TrashRedirect_Exception $e ) {
ob_end_clean();
$this->assertStringNotContainsString( 'post_status=trash', $e->get_location() );
$this->assertStringContainsString( 'edit.php', $e->get_location() );
return;
}

$this->fail( 'Redirect expected when visiting empty trash view.' );
}

/**
* Test that emptying trash via 'delete_all' redirects to all posts view.
*/
public function test_empty_trash_action_redirects_to_all_posts() {
// Create a post in trash.
$post_id = self::factory()->post->create( array( 'post_status' => 'trash' ) );

$_REQUEST['post_status'] = 'trash';
$_REQUEST['post_type'] = 'post';
$_REQUEST['action'] = 'delete_all';
$_REQUEST['_wpnonce'] = wp_create_nonce( 'bulk-posts' );
$_SERVER['REQUEST_URI'] = admin_url( 'edit.php?post_status=trash' );
$_SERVER['HTTP_REFERER'] = admin_url( 'edit.php?post_status=trash' );

try {
ob_start();
include ABSPATH . 'wp-admin/edit.php';
ob_end_clean();
} catch ( Tests_Admin_TrashRedirect_Exception $e ) {
ob_end_clean();
$this->assertStringNotContainsString( 'post_status=trash', $e->get_location() );
$this->assertStringContainsString( 'edit.php', $e->get_location() );
// Check if post is actually deleted.
$this->assertNull( get_post( $post_id ) );
return;
}

$this->fail( 'Redirect expected after emptying trash.' );
}
}

class Tests_Admin_TrashRedirect_Exception extends Exception {
protected $location;
public function __construct( $location ) {
$this->location = $location;
}
public function get_location() {
return $this->location;
}
}
Loading