WordPress.org

Make WordPress Core

Opened 7 months ago

Last modified 7 months ago

#48903 new defect (bug)

Drafts or pending posts overwrites existing published post with same url

Reported by: uatania Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 5.3
Component: Permalinks Keywords:
Focuses: Cc:

Description

The creation of a draft with post_name set to as an existing post will prevent the reachability of the older until the pubblication of the new one. The cause of the issue is that the function wp_unique_post_slug only acts if the post isn't in the status of draft or pending so in the database will be stored two posts with the same post_name. In the frontend side (in a installation with permastruct set to /%postname%/) the executed query is

SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_name = 'example' AND wp_posts.post_type = 'post' ORDER BY wp_posts.post_date DESC

This query will return 2 posts and the wordpress considers the most recent (the draft) so the url returns 404.

Change History (1)

#1 @uatania
7 months ago

Waiting for a fix I added the code below for filter the posts returned by the main query and giving priority to the published (or older) one:

<?php

add_filter('posts_results', 'fixIfSingleHasMultiplePosts', 10, 2);
function fixIfSingleHasMultiplePosts($posts, $wp_query)
  {
    // check if main query in single page
    if(!$wp_query->is_main_query() || !$wp_query->is_single()) {
      return $posts;
    }

    // check bug
    $n_posts = count($posts);
    if($n_posts < 2) {
      return $posts;
    }

    $i = 1;
    while ($i < $n_posts && isset($posts[$i])) {

      if(($posts[$i]->post_status == 'publish' && $posts[($i - 1)]->post_status != 'publish') || $posts[$i]->post_date < $posts[($i - 1)]->post_date) {
        unset($posts[($i - 1)]);
      }

      $i++;
    }

    return array_values($posts);
  }
Note: See TracTickets for help on using tickets.