Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Posts: Prevent duplicate slugs between posts and pages when using /%postname%/ permalinks #8257

Open
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/wp-includes/post.php
Original file line number Diff line number Diff line change
Expand Up @@ -5447,7 +5447,11 @@ 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 ) {
$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";
}
$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_id, $post_parent ) );

/**
Expand Down Expand Up @@ -5477,7 +5481,11 @@ 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 ) {
$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN( %s, 'page' ) 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 );
Expand Down
124 changes: 124 additions & 0 deletions tests/phpunit/tests/post/wpUniquePostSlug.php
Original file line number Diff line number Diff line change
Expand Up @@ -380,4 +380,128 @@ 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 a post cannot use an existing page's slug.
*
* @ticket 13459
*/
public function test_unique_slug_page_before_post() {
$this->set_permalink_structure( '/%postname%/' );

$page = self::factory()->post->create(
array(
'post_type' => 'page',
'post_title' => 'Test Page',
'post_name' => 'test-slug',
)
);

$post = self::factory()->post->create(
array(
'post_type' => 'post',
'post_title' => 'Test Post',
'post_name' => 'test-slug',
)
);

$page_obj = get_post( $page );
$post_obj = get_post( $post );

$this->assertSame( 'test-slug', $page_obj->post_name );
$this->assertSame( 'test-slug-2', $post_obj->post_name );
}

/**
* Test that a page cannot use an existing post's slug.
*
* @ticket 13459
*/
public function test_unique_slug_post_before_page() {
$this->set_permalink_structure( '/%postname%/' );

$post = self::factory()->post->create(
array(
'post_type' => 'post',
'post_title' => 'Test Post',
'post_name' => 'test-slug',
)
);

$page = self::factory()->post->create(
array(
'post_type' => 'page',
'post_title' => 'Test Page',
'post_name' => 'test-slug',
)
);

$post_obj = get_post( $post );
$page_obj = get_post( $page );

$this->assertSame( 'test-slug', $post_obj->post_name );
$this->assertSame( 'test-slug-2', $page_obj->post_name );
}

/**
* Test that two posts cannot share the same slug.
*
* @ticket 13459
*/
public function test_unique_slug_post_before_post() {
$this->set_permalink_structure( '/%postname%/' );

$post1 = self::factory()->post->create(
array(
'post_type' => 'post',
'post_title' => 'First Post',
'post_name' => 'test-slug',
)
);

$post2 = self::factory()->post->create(
array(
'post_type' => 'post',
'post_title' => 'Second Post',
'post_name' => 'test-slug',
)
);

$post1_obj = get_post( $post1 );
$post2_obj = get_post( $post2 );

$this->assertSame( 'test-slug', $post1_obj->post_name );
$this->assertSame( 'test-slug-2', $post2_obj->post_name );
}

/**
* Test that two pages cannot share the same slug.
*
* @ticket 13459
*/
public function test_unique_slug_page_before_page() {
$this->set_permalink_structure( '/%postname%/' );

$page1 = self::factory()->post->create(
array(
'post_type' => 'page',
'post_title' => 'First Page',
'post_name' => 'test-slug',
)
);

$page2 = self::factory()->post->create(
array(
'post_type' => 'page',
'post_title' => 'Second Page',
'post_name' => 'test-slug',
)
);

$page1_obj = get_post( $page1 );
$page2_obj = get_post( $page2 );

$this->assertSame( 'test-slug', $page1_obj->post_name );
$this->assertSame( 'test-slug-2', $page2_obj->post_name );
}
}
Loading