Posts, Post Types: Fail gracefully when checking whether a single post with an unregistered post status should be displayed in `WP_Query::get_posts()`.

If the post status is not registered, assume it's not public, but still allow access to users with edit permissions (same as for a protected post status, e.g. `draft`), so that they could recover orphaned content.

Add unit tests.

Follow-up to [47178].

Props roytanck, SergeyBiryukov.
Fixes #48653.
Built from https://develop.svn.wordpress.org/trunk@47181


git-svn-id: http://core.svn.wordpress.org/trunk@46981 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Sergey Biryukov 2020-02-05 01:33:05 +00:00
parent da6f24fba9
commit a16f3f8f13
2 changed files with 29 additions and 21 deletions

View File

@ -3066,35 +3066,43 @@ class WP_Query {
// Check post status to determine if post should be displayed. // Check post status to determine if post should be displayed.
if ( ! empty( $this->posts ) && ( $this->is_single || $this->is_page ) ) { if ( ! empty( $this->posts ) && ( $this->is_single || $this->is_page ) ) {
$status = get_post_status( $this->posts[0] ); $status = get_post_status( $this->posts[0] );
if ( 'attachment' === $this->posts[0]->post_type && 0 === (int) $this->posts[0]->post_parent ) { if ( 'attachment' === $this->posts[0]->post_type && 0 === (int) $this->posts[0]->post_parent ) {
$this->is_page = false; $this->is_page = false;
$this->is_single = true; $this->is_single = true;
$this->is_attachment = true; $this->is_attachment = true;
} }
$post_status_obj = get_post_status_object( $status );
// If the post_status was specifically requested, let it pass through. // If the post_status was specifically requested, let it pass through.
if ( ! $post_status_obj->public && ! in_array( $status, $q_status ) ) { if ( ! in_array( $status, $q_status ) ) {
$post_status_obj = get_post_status_object( $status );
if ( ! is_user_logged_in() ) { if ( $post_status_obj && ! $post_status_obj->public ) {
// User must be logged in to view unpublished posts. if ( ! is_user_logged_in() ) {
$this->posts = array(); // User must be logged in to view unpublished posts.
} else { $this->posts = array();
if ( $post_status_obj->protected ) {
// User must have edit permissions on the draft to preview.
if ( ! current_user_can( $edit_cap, $this->posts[0]->ID ) ) {
$this->posts = array();
} else {
$this->is_preview = true;
if ( 'future' != $status ) {
$this->posts[0]->post_date = current_time( 'mysql' );
}
}
} elseif ( $post_status_obj->private ) {
if ( ! current_user_can( $read_cap, $this->posts[0]->ID ) ) {
$this->posts = array();
}
} else { } else {
if ( $post_status_obj->protected ) {
// User must have edit permissions on the draft to preview.
if ( ! current_user_can( $edit_cap, $this->posts[0]->ID ) ) {
$this->posts = array();
} else {
$this->is_preview = true;
if ( 'future' != $status ) {
$this->posts[0]->post_date = current_time( 'mysql' );
}
}
} elseif ( $post_status_obj->private ) {
if ( ! current_user_can( $read_cap, $this->posts[0]->ID ) ) {
$this->posts = array();
}
} else {
$this->posts = array();
}
}
} elseif ( ! $post_status_obj ) {
// Post status is not registered, assume it's not public.
if ( ! current_user_can( $edit_cap, $this->posts[0]->ID ) ) {
$this->posts = array(); $this->posts = array();
} }
} }

View File

@ -13,7 +13,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '5.4-alpha-47180'; $wp_version = '5.4-alpha-47181';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.