From 802f7aa0dbe4401b074e832f53d5e2bd9ca08a4d Mon Sep 17 00:00:00 2001 From: SirLouen Date: Sat, 17 May 2025 14:29:49 +0200 Subject: [PATCH] Improving Tests for #13459 --- src/wp-includes/post.php | 22 +++++- tests/phpunit/tests/post/wpUniquePostSlug.php | 77 +++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 19fada6383cfe..ad2c403f4d29c 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -5431,6 +5431,8 @@ function wp_unique_post_slug( $slug, $post_id, $post_status, $post_type, $post_p $feeds = array(); } + $permalink_structure = get_option( 'permalink_structure' ); + if ( 'attachment' === $post_type ) { // Attachment slugs must be unique across all types. $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1"; @@ -5467,7 +5469,15 @@ function wp_unique_post_slug( $slug, $post_id, $post_status, $post_type, $post_p * Page slugs must be unique within their own trees. Pages are in a separate * namespace than posts so page slugs are allowed to overlap post slugs. */ - $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1"; + if ( 'page' === $post_type ) { + if ( 0 === $post_parent && '/%postname%/' === $permalink_structure ) { + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( %s, 'post', 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1"; + } else { + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1"; + } + } else { + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1"; + } $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_id, $post_parent ) ); /** @@ -5497,7 +5507,15 @@ function wp_unique_post_slug( $slug, $post_id, $post_status, $post_type, $post_p } } else { // Post slugs must be unique across all posts. - $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1"; + if ( 'post' === $post_type ) { + if ( '/%postname%/' === $permalink_structure ) { + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ((post_type = %s) OR (post_type = 'page' AND post_parent = 0)) AND ID != %d LIMIT 1"; + } else { + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1"; + } + } else { + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1"; + } $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_id ) ); $post = get_post( $post_id ); diff --git a/tests/phpunit/tests/post/wpUniquePostSlug.php b/tests/phpunit/tests/post/wpUniquePostSlug.php index f242159987e3f..c286f9b54a64f 100644 --- a/tests/phpunit/tests/post/wpUniquePostSlug.php +++ b/tests/phpunit/tests/post/wpUniquePostSlug.php @@ -380,4 +380,81 @@ public function test_embed_slug_should_be_suffixed_for_attachments() { $found = wp_unique_post_slug( 'embed', $p, 'publish', 'attachment', 0 ); $this->assertSame( 'embed-2', $found ); } + + /** + * Test that posts and pages maintain unique slugs. + * + * @ticket 13459 + * + * @dataProvider data_unique_slugs + * + * @param array $first_item First post/page to create. + * @param array $second_item Second post/page to create. + * @param string $test_case Test case identifier. + */ + public function test_unique_slugs( $first_item, $second_item, $test_case ) { + $this->set_permalink_structure( '/%postname%/' ); + + self::factory()->post->create( + array( + 'post_type' => $first_item['type'], + 'post_title' => $first_item['title'], + 'post_name' => 'test-slug', + ) + ); + + $first = self::factory()->post->create( + array( + 'post_type' => $second_item['type'], + 'post_title' => $second_item['title'], + 'post_name' => 'test-slug', + ) + ); + + $first_obj = get_post( $first ); + $this->assertSame( 'test-slug-2', $first_obj->post_name, "Failed first slug check in '$test_case'" ); + + $second = self::factory()->post->create( + array( + 'post_type' => $second_item['type'], + 'post_title' => $second_item['title'], + 'post_name' => 'test-slug', + ) + ); + + $second_obj = get_post( $second ); + $this->assertSame( 'test-slug-3', $second_obj->post_name, "Failed second slug check in '$test_case'" ); + } + + /** + * Data provider for testing unique slug constraints. + * + * @return array[] Test data. + */ + public static function data_unique_slugs() { + return array( + 'page_before_post' => array( + 'first' => array( + 'type' => 'page', + 'title' => 'Test Page', + ), + 'second' => array( + 'type' => 'post', + 'title' => 'Test Post', + ), + 'test_case' => 'page_before_post', + ), + 'post_before_page' => array( + 'first' => array( + 'type' => 'post', + 'title' => 'Test Post', + ), + 'second' => array( + 'type' => 'page', + 'title' => 'Test Page', + ), + 'test_case' => 'post_before_page', + ), + ); + } }