From 9022bd7fd680d04b51d3e8641ded11a10561524b Mon Sep 17 00:00:00 2001 From: jesus Date: Mon, 19 Jan 2026 20:43:10 +0100 Subject: [PATCH] Query: Prefer published posts in singular slug queries --- src/wp-includes/class-wp-query.php | 8 +++++++ tests/phpunit/tests/post/query.php | 36 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php index 8edcf80b54400..a8aa57d60cded 100644 --- a/src/wp-includes/class-wp-query.php +++ b/src/wp-includes/class-wp-query.php @@ -2539,6 +2539,14 @@ public function get_posts() { } } + if ( '' !== $orderby + && empty( $query_vars['post_status'] ) + && ( '' !== $query_vars['name'] || '' !== $query_vars['pagename'] || '' !== $query_vars['attachment'] ) + ) { + // Prefer published posts for singular slug/path queries unless a post_status was requested. + $orderby = "{$wpdb->posts}.post_status = 'publish' DESC, $orderby"; + } + // Order search results by relevance only when another "orderby" is not specified in the query. if ( ! empty( $query_vars['s'] ) ) { $search_orderby = ''; diff --git a/tests/phpunit/tests/post/query.php b/tests/phpunit/tests/post/query.php index dece07fbd6b7f..3920fd1f07a13 100644 --- a/tests/phpunit/tests/post/query.php +++ b/tests/phpunit/tests/post/query.php @@ -327,6 +327,42 @@ public function test_post_name__in_ordering() { $this->assertSame( $ordered, wp_list_pluck( $q->posts, 'post_name' ) ); } + /** + * @ticket 47988 + */ + public function test_singular_name_query_prefers_published_post_over_draft_with_same_slug() { + $slug = 'shared-slug-47988'; + + $published_id = self::factory()->post->create( + array( + 'post_name' => $slug, + 'post_status' => 'publish', + 'post_date' => '2023-01-01 00:00:00', + 'post_date_gmt' => '2023-01-01 00:00:00', + ) + ); + + // Make the draft newer so post_date DESC would normally pick it first. + $draft_id = self::factory()->post->create( + array( + 'post_name' => $slug, + 'post_status' => 'draft', + 'post_date' => '2023-01-02 00:00:00', + 'post_date_gmt' => '2023-01-02 00:00:00', + ) + ); + + $query = new WP_Query( + array( + 'name' => $slug, + 'post_type' => 'post', + ) + ); + + $this->assertNotEmpty( $query->posts ); + $this->assertSame( array( $published_id, $draft_id ), wp_list_pluck( $query->posts, 'ID' ) ); + } + public function test_post_status() { $statuses1 = get_post_stati(); $this->assertContains( 'auto-draft', $statuses1 );