Skip to content
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
31 changes: 21 additions & 10 deletions src/wp-includes/post.php
Original file line number Diff line number Diff line change
Expand Up @@ -4779,17 +4779,19 @@ function wp_insert_post( $postarr, $wp_error = false, $fire_after_hooks = true )

/*
* If the post is being untrashed and it has a desired slug stored in post meta,
* reassign it.
* reassign it, unless a new slug was provided during the update.
*/
if ( 'trash' === $previous_status && 'trash' !== $post_status ) {
$desired_post_slug = get_post_meta( $post_id, '_wp_desired_post_slug', true );

if ( $desired_post_slug ) {
delete_post_meta( $post_id, '_wp_desired_post_slug' );
$post_name = $desired_post_slug;

if ( ! $post_before || $post_name === $post_before->post_name ) {
$post_name = $desired_post_slug;
}
}
}

// If a trashed post has the desired slug, change it and let this post have it.
if ( 'trash' !== $post_status && $post_name ) {
/**
Expand All @@ -4811,8 +4813,10 @@ function wp_insert_post( $postarr, $wp_error = false, $fire_after_hooks = true )
// When trashing an existing post, change its slug to allow non-trashed posts to use it.
if ( 'trash' === $post_status && 'trash' !== $previous_status && 'new' !== $previous_status ) {
$post_name = wp_add_trashed_suffix_to_post_name_for_post( $post_id );
// When changing the slug of a trashed post, keep the desired slug in post meta.
} elseif ( 'trash' === $post_status && 'trash' === $previous_status && isset( $postarr['post_name'] ) ) {
$post_name = wp_add_trashed_suffix_to_post_name_for_post( $post_id, $post_name );
}

$post_name = wp_unique_post_slug( $post_name, $post_id, $post_status, $post_type, $post_parent );

// Don't unslash.
Expand Down Expand Up @@ -8387,19 +8391,26 @@ function wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param WP_Post $post The post.
* @param WP_Post $post The post.
* @param string $post_name Optional. The desired post slug to preserve while the post remains
* trashed. Default empty string.
* @return string New slug for the post.
*/
function wp_add_trashed_suffix_to_post_name_for_post( $post ) {
function wp_add_trashed_suffix_to_post_name_for_post( $post, $post_name = '' ) {
global $wpdb;

$post = get_post( $post );

if ( str_ends_with( $post->post_name, '__trashed' ) ) {
return $post->post_name;
if ( empty( $post_name ) ) {
$post_name = $post->post_name;
}

if ( str_ends_with( $post_name, '__trashed' ) ) {
return $post_name;
}
add_post_meta( $post->ID, '_wp_desired_post_slug', $post->post_name );
$post_name = _truncate_post_slug( $post->post_name, 191 ) . '__trashed';

update_post_meta( $post->ID, '_wp_desired_post_slug', $post_name );
$post_name = _truncate_post_slug( $post_name, 191 ) . '__trashed';
$wpdb->update( $wpdb->posts, array( 'post_name' => $post_name ), array( 'ID' => $post->ID ) );
clean_post_cache( $post->ID );
return $post_name;
Expand Down
77 changes: 77 additions & 0 deletions tests/phpunit/tests/post/wpInsertPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,83 @@ public function test_untrashing_a_post_with_a_stored_desired_post_name_should_ge
$this->assertSame( 'about-2', get_post( $about_page_id )->post_name );
}

/**
* @ticket 44805
*/
public function test_updating_a_trashed_posts_slug_should_update_the_stored_desired_post_name() {
$post_id = self::factory()->post->create(
array(
'post_status' => 'publish',
'post_name' => 'a',
'post_title' => 'A',
)
);

wp_trash_post( $post_id );
wp_update_post(
array(
'ID' => $post_id,
'post_name' => 'foo',
)
);

$this->assertSame( 'foo__trashed', get_post( $post_id )->post_name );
$this->assertSame( 'foo', get_post_meta( $post_id, '_wp_desired_post_slug', true ) );
}

/**
* @ticket 44805
*/
public function test_publishing_a_trashed_post_should_keep_an_updated_slug() {
$post_id = self::factory()->post->create(
array(
'post_status' => 'publish',
'post_name' => 'a',
'post_title' => 'A',
)
);

wp_trash_post( $post_id );
wp_update_post(
array(
'ID' => $post_id,
'post_name' => 'foo',
)
);
wp_update_post(
array(
'ID' => $post_id,
'post_status' => 'publish',
)
);

$this->assertSame( 'foo', get_post( $post_id )->post_name );
}

/**
* @ticket 44805
*/
public function test_publishing_a_trashed_post_with_a_new_slug_in_the_same_update_should_keep_the_new_slug() {
$post_id = self::factory()->post->create(
array(
'post_status' => 'publish',
'post_name' => 'a',
'post_title' => 'A',
)
);

wp_trash_post( $post_id );
wp_update_post(
array(
'ID' => $post_id,
'post_name' => 'foo',
'post_status' => 'publish',
)
);

$this->assertSame( 'foo', get_post( $post_id )->post_name );
}

/**
* @ticket 23022
* @dataProvider data_various_post_statuses
Expand Down
Loading