Make WordPress Core


Ignore:
Timestamp:
08/03/2022 09:01:05 AM (2 years ago)
Author:
audrasjb
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    r53778 r53813  
    654654        $prepared_post->post_type = $this->post_type;
    655655
     656        if ( ! empty( $prepared_post->post_name )
     657            && ! empty( $prepared_post->post_status )
     658            && in_array( $prepared_post->post_status, array( 'draft', 'pending' ), true )
     659        ) {
     660            /*
     661             * `wp_unique_post_slug()` returns the same
     662             * slug for 'draft' or 'pending' posts.
     663             *
     664             * To ensure that a unique slug is generated,
     665             * pass the post data with the 'publish' status.
     666             */
     667            $prepared_post->post_name = wp_unique_post_slug(
     668                $prepared_post->post_name,
     669                $prepared_post->id,
     670                'publish',
     671                $prepared_post->post_type,
     672                $prepared_post->post_parent
     673            );
     674        }
     675
    656676        $post_id = wp_insert_post( wp_slash( (array) $prepared_post ), true, false );
    657677
     
    833853        if ( is_wp_error( $post ) ) {
    834854            return $post;
     855        }
     856
     857        if ( ! empty( $post->post_status ) ) {
     858            $post_status = $post->post_status;
     859        } else {
     860            $post_status = $post_before->post_status;
     861        }
     862
     863        /*
     864         * `wp_unique_post_slug()` returns the same
     865         * slug for 'draft' or 'pending' posts.
     866         *
     867         * To ensure that a unique slug is generated,
     868         * pass the post data with the 'publish' status.
     869         */
     870        if ( ! empty( $post->post_name ) && in_array( $post_status, array( 'draft', 'pending' ), true ) ) {
     871            $post_parent     = ! empty( $post->post_parent ) ? $post->post_parent : 0;
     872            $post->post_name = wp_unique_post_slug( $post->post_name, $post->ID, 'publish', $post->post_type, $post_parent );
    835873        }
    836874
Note: See TracChangeset for help on using the changeset viewer.