From 2174aacf654bbc0d1c1105aad2959be64ed143f1 Mon Sep 17 00:00:00 2001 From: dchiamp Date: Wed, 1 Jul 2026 11:03:09 -0700 Subject: [PATCH 1/2] Allow pending posts to be previewed, like drafts check_read_permission() and can_user_read_post() special-cased 'draft' but not 'pending', so authenticated preview of pending posts fell through to a publish-only check and was denied. Treat pending the same as draft in both places. --- includes/class-rest-post-controller.php | 2 +- includes/utils/class-post.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/includes/class-rest-post-controller.php b/includes/class-rest-post-controller.php index 6e6652b..fb6c065 100644 --- a/includes/class-rest-post-controller.php +++ b/includes/class-rest-post-controller.php @@ -513,7 +513,7 @@ public function check_read_permission( $post ) { return true; } - if ( 'draft' === $post->post_status ) { + if ( in_array( $post->post_status, array( 'draft', 'pending' ), true ) ) { $user_id = apply_filters( 'determine_current_user', false ); if ( ! empty( $user_id ) ) { return PostUtils::can_user_read_post( $user_id, $post->ID ); diff --git a/includes/utils/class-post.php b/includes/utils/class-post.php index 68b0d65..8c082a5 100644 --- a/includes/utils/class-post.php +++ b/includes/utils/class-post.php @@ -316,13 +316,13 @@ public static function can_user_read_post( $user_id, $post_id ) { return false; } - // Check if the post exists and is a draft - if ( $post->post_status === 'draft' ) { - // Check if the user is the author of the post or have permission. + // Draft and pending posts are previewable by their author, or by users + // who can read private posts (editors/admins). + if ( in_array( $post->post_status, array( 'draft', 'pending' ), true ) ) { return $post->post_author === $user_id || user_can( $user_id, 'read_private_posts' ); } - // Post is not a draft or doesn't exist + // Otherwise, only published posts are readable. return $post->post_status === 'publish'; } From a2ae3153da8585bc438d563ff97006e2ade80592 Mon Sep 17 00:00:00 2001 From: dchiamp Date: Wed, 1 Jul 2026 12:07:21 -0700 Subject: [PATCH 2/2] Resolve pending posts by URI (preview fix, part 2) url_to_postid() limited the resolving WP_Query to publish+draft, so pending posts were never found by URI and /post 404'd before the read check ran. Add 'pending' to the status list and to the verbose-page-rule exemption. --- includes/utils/class-post.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/utils/class-post.php b/includes/utils/class-post.php index 8c082a5..15fadaf 100644 --- a/includes/utils/class-post.php +++ b/includes/utils/class-post.php @@ -520,7 +520,7 @@ private static function url_to_postid( $url ) { } $post_status_obj = get_post_status_object( $page->post_status ); - if ( $page->post_status !== 'draft' && ! $post_status_obj->public && ! $post_status_obj->protected + if ( $page->post_status !== 'draft' && $page->post_status !== 'pending' && ! $post_status_obj->public && ! $post_status_obj->protected && ! $post_status_obj->private && $post_status_obj->exclude_from_search ) { continue; } @@ -555,6 +555,7 @@ private static function url_to_postid( $url ) { $query['post_status'] = array( 'publish', 'draft', + 'pending', ); // Do the query.