Posts, Post Types: Force unique slugs for draft posts.

This fixes a behavior where a draft created with the same slug as an existing post would set the existing post to a 404.

`wp_unique_post_slug()` returns the same slug for 'draft' or 'pending' posts, so to ensure that a unique slug is generated, this changeset adds the post data with the 'publish' status to `wp_unique_post_slug()`.

Props Toro_Unit, h2ham, peterwilsoncc, costdev, antonvlasenko, azaozz, ironprogrammer, audrasjb, hellofromTonya.
Fixes #52422.

Built from https://develop.svn.wordpress.org/trunk@53813


git-svn-id: http://core.svn.wordpress.org/trunk@53372 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
audrasjb 2022-08-03 09:03:14 +00:00
parent d7d371b840
commit 2692f4a0be
2 changed files with 39 additions and 1 deletions

View File

@ -653,6 +653,26 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
$prepared_post->post_type = $this->post_type; $prepared_post->post_type = $this->post_type;
if ( ! empty( $prepared_post->post_name )
&& ! empty( $prepared_post->post_status )
&& in_array( $prepared_post->post_status, array( 'draft', 'pending' ), true )
) {
/*
* `wp_unique_post_slug()` returns the same
* slug for 'draft' or 'pending' posts.
*
* To ensure that a unique slug is generated,
* pass the post data with the 'publish' status.
*/
$prepared_post->post_name = wp_unique_post_slug(
$prepared_post->post_name,
$prepared_post->id,
'publish',
$prepared_post->post_type,
$prepared_post->post_parent
);
}
$post_id = wp_insert_post( wp_slash( (array) $prepared_post ), true, false ); $post_id = wp_insert_post( wp_slash( (array) $prepared_post ), true, false );
if ( is_wp_error( $post_id ) ) { if ( is_wp_error( $post_id ) ) {
@ -834,6 +854,24 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
return $post; return $post;
} }
if ( ! empty( $post->post_status ) ) {
$post_status = $post->post_status;
} else {
$post_status = $post_before->post_status;
}
/*
* `wp_unique_post_slug()` returns the same
* slug for 'draft' or 'pending' posts.
*
* To ensure that a unique slug is generated,
* pass the post data with the 'publish' status.
*/
if ( ! empty( $post->post_name ) && in_array( $post_status, array( 'draft', 'pending' ), true ) ) {
$post_parent = ! empty( $post->post_parent ) ? $post->post_parent : 0;
$post->post_name = wp_unique_post_slug( $post->post_name, $post->ID, 'publish', $post->post_type, $post_parent );
}
// Convert the post object to an array, otherwise wp_update_post() will expect non-escaped input. // Convert the post object to an array, otherwise wp_update_post() will expect non-escaped input.
$post_id = wp_update_post( wp_slash( (array) $post ), true, false ); $post_id = wp_update_post( wp_slash( (array) $post ), true, false );

View File

@ -16,7 +16,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '6.1-alpha-53812'; $wp_version = '6.1-alpha-53813';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.