From b878b509ed151d5c03a06ec6d2e5519b8eacd862 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 2 Dec 2016 00:25:47 +0000 Subject: [PATCH] Customize: Reuse existing non-auto-draft posts and existing auto-draft posts in the customized state with matching slugs when applying starter content. * Updates `wp_unique_post_slug()` to ignore `auto-draft` posts. Prevents publishing multiple posts that have the same slugs from starter content. * Fixes fatal error when attempting to save an header_image setting from a non-admin context. * Fixes substituting attachment symbols in options and theme mods. * Fixes applying starter content for header images and background images. Merges [39411] to 4.7 branch. See #38114. Fixes #38928 for 4.7. git-svn-id: https://develop.svn.wordpress.org/branches/4.7@39412 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-customize-manager.php | 188 ++++++++++++++---- ...lass-wp-customize-header-image-setting.php | 9 + src/wp-includes/post.php | 6 +- tests/phpunit/tests/customize/manager.php | 84 ++++++-- tests/phpunit/tests/post/wpUniquePostSlug.php | 42 ++++ 5 files changed, 269 insertions(+), 60 deletions(-) diff --git a/src/wp-includes/class-wp-customize-manager.php b/src/wp-includes/class-wp-customize-manager.php index 694873f524..94150d64b3 100644 --- a/src/wp-includes/class-wp-customize-manager.php +++ b/src/wp-includes/class-wp-customize-manager.php @@ -971,6 +971,32 @@ final class WP_Customize_Manager { $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, $changeset_data['nav_menus_created_posts']['value'] ); } + // Make an index of all the posts needed and what their slugs are. + $needed_posts = array(); + $attachments = $this->prepare_starter_content_attachments( $attachments ); + foreach ( $attachments as $attachment ) { + $key = 'attachment:' . $attachment['post_name']; + $needed_posts[ $key ] = true; + } + foreach ( array_keys( $posts ) as $post_symbol ) { + if ( empty( $posts[ $post_symbol ]['post_name'] ) && empty( $posts[ $post_symbol ]['post_title'] ) ) { + unset( $posts[ $post_symbol ] ); + continue; + } + if ( empty( $posts[ $post_symbol ]['post_name'] ) ) { + $posts[ $post_symbol ]['post_name'] = sanitize_title( $posts[ $post_symbol ]['post_title'] ); + } + if ( empty( $posts[ $post_symbol ]['post_type'] ) ) { + $posts[ $post_symbol ]['post_type'] = 'post'; + } + $needed_posts[ $posts[ $post_symbol ]['post_type'] . ':' . $posts[ $post_symbol ]['post_name'] ] = true; + } + $all_post_slugs = array_merge( + wp_list_pluck( $attachments, 'post_name' ), + wp_list_pluck( $posts, 'post_name' ) + ); + + // Re-use auto-draft starter content posts referenced in the current customized state. $existing_starter_content_posts = array(); if ( ! empty( $starter_content_auto_draft_post_ids ) ) { $existing_posts_query = new WP_Query( array( @@ -984,50 +1010,32 @@ final class WP_Customize_Manager { } } + // Re-use non-auto-draft posts. + if ( ! empty( $all_post_slugs ) ) { + $existing_posts_query = new WP_Query( array( + 'post_name__in' => $all_post_slugs, + 'post_status' => array_diff( get_post_stati(), array( 'auto-draft' ) ), + 'post_type' => 'any', + 'number' => -1, + ) ); + foreach ( $existing_posts_query->posts as $existing_post ) { + $key = $existing_post->post_type . ':' . $existing_post->post_name; + if ( isset( $needed_posts[ $key ] ) && ! isset( $existing_starter_content_posts[ $key ] ) ) { + $existing_starter_content_posts[ $key ] = $existing_post; + } + } + } + // Attachments are technically posts but handled differently. if ( ! empty( $attachments ) ) { - // Such is The WordPress Way. - require_once( ABSPATH . 'wp-admin/includes/file.php' ); - require_once( ABSPATH . 'wp-admin/includes/media.php' ); - require_once( ABSPATH . 'wp-admin/includes/image.php' ); $attachment_ids = array(); foreach ( $attachments as $symbol => $attachment ) { - - // A file is required and URLs to files are not currently allowed. - if ( empty( $attachment['file'] ) || preg_match( '#^https?://$#', $attachment['file'] ) ) { - continue; - } - - $file_array = array(); - $file_path = null; - if ( file_exists( $attachment['file'] ) ) { - $file_path = $attachment['file']; // Could be absolute path to file in plugin. - } elseif ( is_child_theme() && file_exists( get_stylesheet_directory() . '/' . $attachment['file'] ) ) { - $file_path = get_stylesheet_directory() . '/' . $attachment['file']; - } elseif ( file_exists( get_template_directory() . '/' . $attachment['file'] ) ) { - $file_path = get_template_directory() . '/' . $attachment['file']; - } else { - continue; - } - $file_array['name'] = basename( $attachment['file'] ); - - // Skip file types that are not recognized. - $checked_filetype = wp_check_filetype( $file_array['name'] ); - if ( empty( $checked_filetype['type'] ) ) { - continue; - } - - // Ensure post_name is set since not automatically derived from post_title for new auto-draft posts. - if ( empty( $attachment['post_name'] ) ) { - if ( ! empty( $attachment['post_title'] ) ) { - $attachment['post_name'] = sanitize_title( $attachment['post_title'] ); - } else { - $attachment['post_name'] = sanitize_title( preg_replace( '/\.\w+$/', '', $file_array['name'] ) ); - } - } - + $file_array = array( + 'name' => $attachment['file_name'], + ); + $file_path = $attachment['file_path']; $attachment_id = null; $attached_file = null; if ( isset( $existing_starter_content_posts[ 'attachment:' . $attachment['post_name'] ] ) ) { @@ -1080,14 +1088,14 @@ final class WP_Customize_Manager { } $attachment_ids[ $symbol ] = $attachment_id; - $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, array_values( $attachment_ids ) ); } + $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, array_values( $attachment_ids ) ); } // Posts & pages. if ( ! empty( $posts ) ) { foreach ( array_keys( $posts ) as $post_symbol ) { - if ( empty( $posts[ $post_symbol ]['post_type'] ) ) { + if ( empty( $posts[ $post_symbol ]['post_type'] ) || empty( $posts[ $post_symbol ]['post_name'] ) ) { continue; } $post_type = $posts[ $post_symbol ]['post_type']; @@ -1209,8 +1217,14 @@ final class WP_Customize_Manager { // Options. foreach ( $options as $name => $value ) { - if ( preg_match( '/^{{(?P.+)}}$/', $value, $matches ) && isset( $posts[ $matches['symbol'] ] ) ) { - $value = $posts[ $matches['symbol'] ]['ID']; + if ( preg_match( '/^{{(?P.+)}}$/', $value, $matches ) ) { + if ( isset( $posts[ $matches['symbol'] ] ) ) { + $value = $posts[ $matches['symbol'] ]['ID']; + } elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) { + $value = $attachment_ids[ $matches['symbol'] ]; + } else { + continue; + } } if ( empty( $changeset_data[ $name ] ) || ! empty( $changeset_data[ $name ]['starter_content'] ) ) { @@ -1221,8 +1235,31 @@ final class WP_Customize_Manager { // Theme mods. foreach ( $theme_mods as $name => $value ) { - if ( preg_match( '/^{{(?P.+)}}$/', $value, $matches ) && isset( $posts[ $matches['symbol'] ] ) ) { - $value = $posts[ $matches['symbol'] ]['ID']; + if ( preg_match( '/^{{(?P.+)}}$/', $value, $matches ) ) { + if ( isset( $posts[ $matches['symbol'] ] ) ) { + $value = $posts[ $matches['symbol'] ]['ID']; + } elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) { + $value = $attachment_ids[ $matches['symbol'] ]; + } else { + continue; + } + } + + // Handle header image as special case since setting has a legacy format. + if ( 'header_image' === $name ) { + $name = 'header_image_data'; + $metadata = wp_get_attachment_metadata( $value ); + if ( empty( $metadata ) ) { + continue; + } + $value = array( + 'attachment_id' => $value, + 'url' => wp_get_attachment_url( $value ), + 'height' => $metadata['height'], + 'width' => $metadata['width'], + ); + } elseif ( 'background_image' === $name ) { + $value = wp_get_attachment_url( $value ); } if ( empty( $changeset_data[ $name ] ) || ! empty( $changeset_data[ $name ]['starter_content'] ) ) { @@ -1240,6 +1277,69 @@ final class WP_Customize_Manager { } } + /** + * Prepare starter content attachments. + * + * Ensure that the attachments are valid and that they have slugs and file name/path. + * + * @since 4.7.0 + * @access private + * + * @param array $attachments Attachments. + * @return array Prepared attachments. + */ + protected function prepare_starter_content_attachments( $attachments ) { + $prepared_attachments = array(); + if ( empty( $attachments ) ) { + return $prepared_attachments; + } + + // Such is The WordPress Way. + require_once( ABSPATH . 'wp-admin/includes/file.php' ); + require_once( ABSPATH . 'wp-admin/includes/media.php' ); + require_once( ABSPATH . 'wp-admin/includes/image.php' ); + + foreach ( $attachments as $symbol => $attachment ) { + + // A file is required and URLs to files are not currently allowed. + if ( empty( $attachment['file'] ) || preg_match( '#^https?://$#', $attachment['file'] ) ) { + continue; + } + + $file_path = null; + if ( file_exists( $attachment['file'] ) ) { + $file_path = $attachment['file']; // Could be absolute path to file in plugin. + } elseif ( is_child_theme() && file_exists( get_stylesheet_directory() . '/' . $attachment['file'] ) ) { + $file_path = get_stylesheet_directory() . '/' . $attachment['file']; + } elseif ( file_exists( get_template_directory() . '/' . $attachment['file'] ) ) { + $file_path = get_template_directory() . '/' . $attachment['file']; + } else { + continue; + } + $file_name = basename( $attachment['file'] ); + + // Skip file types that are not recognized. + $checked_filetype = wp_check_filetype( $file_name ); + if ( empty( $checked_filetype['type'] ) ) { + continue; + } + + // Ensure post_name is set since not automatically derived from post_title for new auto-draft posts. + if ( empty( $attachment['post_name'] ) ) { + if ( ! empty( $attachment['post_title'] ) ) { + $attachment['post_name'] = sanitize_title( $attachment['post_title'] ); + } else { + $attachment['post_name'] = sanitize_title( preg_replace( '/\.\w+$/', '', $file_name ) ); + } + } + + $attachment['file_name'] = $file_name; + $attachment['file_path'] = $file_path; + $prepared_attachments[ $symbol ] = $attachment; + } + return $prepared_attachments; + } + /** * Save starter content changeset. * diff --git a/src/wp-includes/customize/class-wp-customize-header-image-setting.php b/src/wp-includes/customize/class-wp-customize-header-image-setting.php index 98b79aed56..af5c516243 100644 --- a/src/wp-includes/customize/class-wp-customize-header-image-setting.php +++ b/src/wp-includes/customize/class-wp-customize-header-image-setting.php @@ -29,6 +29,15 @@ final class WP_Customize_Header_Image_Setting extends WP_Customize_Setting { public function update( $value ) { global $custom_image_header; + // If _custom_header_background_just_in_time() fails to initialize $custom_image_header when not is_admin(). + if ( empty( $custom_image_header ) ) { + require_once( ABSPATH . 'wp-admin/custom-header.php' ); + $args = get_theme_support( 'custom-header' ); + $admin_head_callback = isset( $args[0]['admin-head-callback'] ) ? $args[0]['admin-head-callback'] : null; + $admin_preview_callback = isset( $args[0]['admin-preview-callback'] ) ? $args[0]['admin-preview-callback'] : null; + $custom_image_header = new Custom_Image_Header( $admin_head_callback, $admin_preview_callback ); + } + // If the value doesn't exist (removed or random), // use the header_image value. if ( ! $value ) diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 620d1e4a8f..2c70fdd6ae 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -3673,7 +3673,7 @@ function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p if ( 'attachment' == $post_type ) { // Attachment slugs must be unique across all types. - $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1"; + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_status != 'auto-draft' AND post_name = %s AND ID != %d LIMIT 1"; $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID ) ); /** @@ -3701,7 +3701,7 @@ function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p * Page slugs must be unique within their own trees. Pages are in a separate * namespace than posts so page slugs are allowed to overlap post slugs. */ - $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1"; + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_status != 'auto-draft' AND post_name = %s AND post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1"; $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID, $post_parent ) ); /** @@ -3725,7 +3725,7 @@ function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p } } else { // Post slugs must be unique across all posts. - $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1"; + $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_status != 'auto-draft' AND post_name = %s AND post_type = %s AND ID != %d LIMIT 1"; $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID ) ); // Prevent new post slugs that could result in URLs that conflict with date archives. diff --git a/tests/phpunit/tests/customize/manager.php b/tests/phpunit/tests/customize/manager.php index 45931932f9..c179026b87 100644 --- a/tests/phpunit/tests/customize/manager.php +++ b/tests/phpunit/tests/customize/manager.php @@ -314,6 +314,26 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { function test_import_theme_starter_content() { wp_set_current_user( self::$admin_user_id ); register_nav_menu( 'top', 'Top' ); + add_theme_support( 'custom-logo' ); + add_theme_support( 'custom-header' ); + add_theme_support( 'custom-background' ); + + $canola_file = DIR_TESTDATA . '/images/canola.jpg'; + $existing_canola_attachment_id = self::factory()->attachment->create_object( $canola_file, 0, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment', + 'post_name' => 'canola', + ) ); + $existing_published_home_page_id = $this->factory()->post->create( array( + 'post_name' => 'home', + 'post_type' => 'page', + 'post_status' => 'publish' + ) ); + $existing_auto_draft_about_page_id = $this->factory()->post->create( array( + 'post_name' => 'about', + 'post_type' => 'page', + 'post_status' => 'auto-draft' + ) ); global $wp_customize; $wp_customize = new WP_Customize_Manager(); @@ -351,16 +371,22 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { 'custom' => array( 'post_type' => 'post', 'post_title' => 'Custom', - 'thumbnail' => '{{featured-image-logo}}', + 'thumbnail' => '{{waffles}}', ), ), 'attachments' => array( - 'featured-image-logo' => array( - 'post_title' => 'Featured Image', - 'post_content' => 'Attachment Description', - 'post_excerpt' => 'Attachment Caption', + 'waffles' => array( + 'post_title' => 'Waffles', + 'post_content' => 'Waffles Attachment Description', + 'post_excerpt' => 'Waffles Attachment Caption', 'file' => DIR_TESTDATA . '/images/waffles.jpg', ), + 'canola' => array( + 'post_title' => 'Canola', + 'post_content' => 'Canola Attachment Description', + 'post_excerpt' => 'Canola Attachment Caption', + 'file' => DIR_TESTDATA . '/images/canola.jpg', + ), ), 'options' => array( 'blogname' => 'Starter Content Title', @@ -369,6 +395,11 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { 'page_on_front' => '{{home}}', 'page_for_posts' => '{{blog}}', ), + 'theme_mods' => array( + 'custom_logo' => '{{canola}}', + 'header_image' => '{{waffles}}', + 'background_image' => '{{waffles}}', + ), ); add_theme_support( 'starter-content', $starter_content_config ); @@ -378,6 +409,9 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { $expected_setting_ids = array( 'blogname', 'blogdescription', + 'custom_logo', + 'header_image_data', + 'background_image', 'widget_text[2]', 'widget_meta[3]', 'sidebars_widgets[sidebar-1]', @@ -406,20 +440,29 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { $this->assertEquals( array( 'text-2', 'meta-3' ), $changeset_values['sidebars_widgets[sidebar-1]'] ); $posts_by_name = array(); - $this->assertCount( 5, $changeset_values['nav_menus_created_posts'] ); + $this->assertCount( 6, $changeset_values['nav_menus_created_posts'] ); + $this->assertContains( $existing_published_home_page_id, $changeset_values['nav_menus_created_posts'], 'Expected reuse of non-auto-draft posts.' ); + $this->assertContains( $existing_canola_attachment_id, $changeset_values['nav_menus_created_posts'], 'Expected reuse of non-auto-draft attachment.' ); + $this->assertNotContains( $existing_auto_draft_about_page_id, $changeset_values['nav_menus_created_posts'], 'Expected non-reuse of auto-draft posts.' ); foreach ( $changeset_values['nav_menus_created_posts'] as $post_id ) { $post = get_post( $post_id ); - $this->assertEquals( 'auto-draft', $post->post_status ); + if ( $post->ID === $existing_published_home_page_id ) { + $this->assertEquals( 'publish', $post->post_status ); + } elseif ( $post->ID === $existing_canola_attachment_id ) { + $this->assertEquals( 'inherit', $post->post_status ); + } else { + $this->assertEquals( 'auto-draft', $post->post_status ); + } $posts_by_name[ $post->post_name ] = $post->ID; } - $this->assertEquals( array( 'featured-image', 'home', 'about', 'blog', 'custom' ), array_keys( $posts_by_name ) ); + $this->assertEquals( array( 'waffles', 'canola', 'home', 'about', 'blog', 'custom' ), array_keys( $posts_by_name ) ); $this->assertEquals( 'Custom', get_post( $posts_by_name['custom'] )->post_title ); $this->assertEquals( 'sample-page-template.php', get_page_template_slug( $posts_by_name['about'] ) ); $this->assertEquals( '', get_page_template_slug( $posts_by_name['blog'] ) ); - $this->assertEquals( $posts_by_name['featured-image'], get_post_thumbnail_id( $posts_by_name['custom'] ) ); + $this->assertEquals( $posts_by_name['waffles'], get_post_thumbnail_id( $posts_by_name['custom'] ) ); $this->assertEquals( '', get_post_thumbnail_id( $posts_by_name['blog'] ) ); - $attachment_metadata = wp_get_attachment_metadata( $posts_by_name['featured-image'] ); - $this->assertEquals( 'Featured Image', get_post( $posts_by_name['featured-image'] )->post_title ); + $attachment_metadata = wp_get_attachment_metadata( $posts_by_name['waffles'] ); + $this->assertEquals( 'Waffles', get_post( $posts_by_name['waffles'] )->post_title ); $this->assertArrayHasKey( 'file', $attachment_metadata ); $this->assertContains( 'waffles', $attachment_metadata['file'] ); @@ -472,14 +515,29 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { $this->assertArrayHasKey( 'starter_content', $changeset_data['blogdescription'] ); // Publish. + $this->assertEmpty( get_custom_logo() ); + $this->assertEmpty( get_header_image() ); + $this->assertEmpty( get_background_image() ); + $this->assertEmpty( get_theme_mod( 'custom_logo' ) ); + $this->assertEmpty( get_theme_mod( 'header_image' ) ); + $this->assertEmpty( get_theme_mod( 'background_image' ) ); $this->assertEquals( 'auto-draft', get_post( $posts_by_name['about'] )->post_status ); - $this->assertEquals( 'auto-draft', get_post( $posts_by_name['featured-image'] )->post_status ); + $this->assertEquals( 'auto-draft', get_post( $posts_by_name['waffles'] )->post_status ); $this->assertNotEquals( $changeset_data['blogname']['value'], get_option( 'blogname' ) ); $r = $wp_customize->save_changeset_post( array( 'status' => 'publish' ) ); $this->assertInternalType( 'array', $r ); $this->assertEquals( 'publish', get_post( $posts_by_name['about'] )->post_status ); - $this->assertEquals( 'inherit', get_post( $posts_by_name['featured-image'] )->post_status ); + $this->assertEquals( 'inherit', get_post( $posts_by_name['waffles'] )->post_status ); $this->assertEquals( $changeset_data['blogname']['value'], get_option( 'blogname' ) ); + $this->assertNotEmpty( get_theme_mod( 'custom_logo' ) ); + $this->assertNotEmpty( get_theme_mod( 'header_image' ) ); + $this->assertNotEmpty( get_theme_mod( 'background_image' ) ); + $this->assertNotEmpty( get_custom_logo() ); + $this->assertNotEmpty( get_header_image() ); + $this->assertNotEmpty( get_background_image() ); + $this->assertContains( 'canola', get_custom_logo() ); + $this->assertContains( 'waffles', get_header_image() ); + $this->assertContains( 'waffles', get_background_image() ); } /** diff --git a/tests/phpunit/tests/post/wpUniquePostSlug.php b/tests/phpunit/tests/post/wpUniquePostSlug.php index 536017db31..a728454da6 100644 --- a/tests/phpunit/tests/post/wpUniquePostSlug.php +++ b/tests/phpunit/tests/post/wpUniquePostSlug.php @@ -347,4 +347,46 @@ class Tests_Post_WpUniquePostSlug extends WP_UnitTestCase { $found = wp_unique_post_slug( 'embed', $p, 'publish', 'attachment', 0 ); $this->assertSame( 'embed-2', $found ); } + + /** + * @ticket 38928 + */ + public function test_non_unique_slugs_for_existing_auto_draft_posts() { + $auto_draft_post_id = self::factory()->post->create( array( + 'post_type' => 'post', + 'post_name' => 'existing-post', + 'post_status' => 'auto-draft', + ) ); + $auto_draft_page_id = self::factory()->post->create( array( + 'post_type' => 'page', + 'post_name' => 'existing-page', + 'post_status' => 'auto-draft', + ) ); + $auto_draft_attachment_id = self::factory()->attachment->create_object( 'image.jpg', $auto_draft_page_id, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment', + 'post_name' => 'existing-attachment', + 'post_status' => 'auto-draft', + ) ); + + $post_id = self::factory()->post->create( array( 'post_type' => 'post' ) ); + $page_id = self::factory()->post->create( array( 'post_type' => 'page' ) ); + $attachment_id = self::factory()->attachment->create_object( 'image2.jpg', $page_id, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment', + 'post_name' => 'existing-image', + ) ); + + $this->assertEquals( 'existing-post', wp_unique_post_slug( 'existing-post', $post_id, 'publish', get_post_type( $post_id ), 0 ) ); + wp_publish_post( $auto_draft_post_id ); + $this->assertEquals( 'existing-post-2', wp_unique_post_slug( 'existing-post', $post_id, 'publish', get_post_type( $post_id ), 0 ) ); + + $this->assertEquals( 'existing-page', wp_unique_post_slug( 'existing-page', $page_id, 'publish', get_post_type( $page_id ), 0 ) ); + wp_publish_post( $auto_draft_page_id ); + $this->assertEquals( 'existing-page-2', wp_unique_post_slug( 'existing-page', $page_id, 'publish', get_post_type( $page_id ), 0 ) ); + + $this->assertEquals( 'existing-attachment', wp_unique_post_slug( 'existing-attachment', $attachment_id, 'publish', get_post_type( $attachment_id ), 0 ) ); + wp_publish_post( $auto_draft_attachment_id ); + $this->assertEquals( 'existing-attachment-2', wp_unique_post_slug( 'existing-attachment', $attachment_id, 'publish', get_post_type( $attachment_id ), 0 ) ); + } }