mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2025-10-16 12:05:38 +00:00
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. git-svn-id: https://develop.svn.wordpress.org/trunk@53813 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
86fd171713
commit
5dff1e8503
@ -653,6 +653,26 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
|
||||
$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 );
|
||||
|
||||
if ( is_wp_error( $post_id ) ) {
|
||||
@ -834,6 +854,24 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
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.
|
||||
$post_id = wp_update_post( wp_slash( (array) $post ), true, false );
|
||||
|
||||
|
||||
@ -5236,6 +5236,47 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
||||
$GLOBALS['wp_rest_server']->override_by_default = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 52422
|
||||
*
|
||||
* @covers WP_REST_Request::create_item
|
||||
*/
|
||||
public function test_draft_post_do_not_have_the_same_slug_as_existing_post() {
|
||||
wp_set_current_user( self::$editor_id );
|
||||
$this->factory()->post->create( array( 'post_name' => 'sample-slug' ) );
|
||||
|
||||
$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
|
||||
$params = $this->set_post_data(
|
||||
array(
|
||||
'status' => 'draft',
|
||||
'slug' => 'sample-slug',
|
||||
)
|
||||
);
|
||||
$request->set_body_params( $params );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
|
||||
$new_data = $response->get_data();
|
||||
$this->assertSame(
|
||||
'sample-slug-2',
|
||||
$new_data['slug'],
|
||||
'The slug from the REST response did not match'
|
||||
);
|
||||
|
||||
$post = get_post( $new_data['id'] );
|
||||
|
||||
$this->assertSame(
|
||||
'draft',
|
||||
$post->post_status,
|
||||
'The post status is not draft'
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
'sample-slug-2',
|
||||
$post->post_name,
|
||||
'The post slug was not set to "sample-slug-2"'
|
||||
);
|
||||
}
|
||||
|
||||
public function tear_down() {
|
||||
if ( isset( $this->attachment_id ) ) {
|
||||
$this->remove_added_uploads();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user