From 328be3ddf5c9e6e093486952306f5bc15426b639 Mon Sep 17 00:00:00 2001 From: ArkaPrabhaChowdhury Date: Fri, 17 Jul 2026 17:43:08 +0530 Subject: [PATCH] Permalinks: Preserve post status in sample permalink filters --- src/wp-admin/includes/post.php | 22 +++++----- src/wp-includes/link-template.php | 4 +- tests/phpunit/tests/admin/includesPost.php | 47 ++++++++++++++++++++++ 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/src/wp-admin/includes/post.php b/src/wp-admin/includes/post.php index 39d267b623037..a4e007f82f267 100644 --- a/src/wp-admin/includes/post.php +++ b/src/wp-admin/includes/post.php @@ -1471,15 +1471,15 @@ function get_sample_permalink( $post, $title = null, $name = null ) { $ptype = get_post_type_object( $post->post_type ); - $original_status = $post->post_status; $original_date = $post->post_date; $original_name = $post->post_name; $original_filter = $post->filter; + $post_status = $post->post_status; - // Hack: get_permalink() would return plain permalink for drafts, so we will fake that our post is published. + // Drafts do not have unique slugs, so use a published status when determining the sample slug. if ( in_array( $post->post_status, array( 'auto-draft', 'draft', 'pending', 'future' ), true ) ) { - $post->post_status = 'publish'; - $post->post_name = sanitize_title( $post->post_name ? $post->post_name : $post->post_title, $post->ID ); + $post_status = 'publish'; + $post->post_name = sanitize_title( $post->post_name ? $post->post_name : $post->post_title, $post->ID ); } /* @@ -1490,9 +1490,8 @@ function get_sample_permalink( $post, $title = null, $name = null ) { $post->post_name = sanitize_title( $name ? $name : $title, $post->ID ); } - $post->post_name = wp_unique_post_slug( $post->post_name, $post->ID, $post->post_status, $post->post_type, $post->post_parent ); - - $post->filter = 'sample'; + $post->post_name = wp_unique_post_slug( $post->post_name, $post->ID, $post_status, $post->post_type, $post->post_parent ); + $post->filter = 'sample'; $permalink = get_permalink( $post, true ); @@ -1517,11 +1516,10 @@ function get_sample_permalink( $post, $title = null, $name = null ) { } /** This filter is documented in wp-admin/edit-tag-form.php */ - $permalink = array( $permalink, apply_filters( 'editable_slug', $post->post_name, $post ) ); - $post->post_status = $original_status; - $post->post_date = $original_date; - $post->post_name = $original_name; - $post->filter = $original_filter; + $permalink = array( $permalink, apply_filters( 'editable_slug', $post->post_name, $post ) ); + $post->post_date = $original_date; + $post->post_name = $original_name; + $post->filter = $original_filter; /** * Filters the sample permalink. diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index 223d6b5548fc6..7455c38499d57 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -132,8 +132,8 @@ function wp_force_plain_post_permalink( $post = null, $sample = null ) { $post_status_obj->private && current_user_can( 'read_post', $post->ID ) ) || - // Protected posts don't have plain links if getting a sample URL. - ( $post_status_obj->protected && $sample ) + // Protected posts and auto-drafts don't have plain links if getting a sample URL. + ( $sample && ( $post_status_obj->protected || 'auto-draft' === $post->post_status ) ) ) { return false; } diff --git a/tests/phpunit/tests/admin/includesPost.php b/tests/phpunit/tests/admin/includesPost.php index d9d39d8da727d..077ac69c0e1f0 100644 --- a/tests/phpunit/tests/admin/includesPost.php +++ b/tests/phpunit/tests/admin/includesPost.php @@ -948,6 +948,53 @@ public function test_get_sample_permalink_should_respect_hierarchy_of_draft_page $this->assertSame( 'child-page', $actual[1] ); } + /** + * Tests that get_sample_permalink() passes the original post status to permalink filters. + * + * @ticket 50002 + * + * @covers ::get_sample_permalink + */ + public function test_get_sample_permalink_should_pass_original_post_status_to_permalink_filters() { + $this->set_permalink_structure( '/%postname%/' ); + + $post = self::factory()->post->create_and_get( + array( + 'post_status' => 'draft', + 'post_title' => 'A Draft Post', + ) + ); + + $pre_post_link_status = null; + $post_link_status = null; + + add_filter( + 'pre_post_link', + function ( $permalink, $filtered_post ) use ( &$pre_post_link_status ) { + $pre_post_link_status = $filtered_post->post_status; + return $permalink; + }, + 10, + 2 + ); + add_filter( + 'post_link', + function ( $permalink, $filtered_post ) use ( &$post_link_status ) { + $post_link_status = $filtered_post->post_status; + return $permalink; + }, + 10, + 2 + ); + + $actual = get_sample_permalink( $post ); + + $this->assertSame( 'draft', $pre_post_link_status ); + $this->assertSame( 'draft', $post_link_status ); + $this->assertSame( home_url( '/%postname%/' ), $actual[0] ); + $this->assertSame( 'a-draft-post', $actual[1] ); + } + /** * Tests that get_sample_permalink() preserves the original WP_Post properties. *