Ticket #38928: 38928.4.diff
File 38928.4.diff, 12.0 KB (added by , 8 years ago) |
---|
-
src/wp-includes/class-wp-customize-manager.php
diff --git src/wp-includes/class-wp-customize-manager.php src/wp-includes/class-wp-customize-manager.php index 1f5da60..e4e7d9f 100644
final class WP_Customize_Manager { 971 971 $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, $changeset_data['nav_menus_created_posts']['value'] ); 972 972 } 973 973 974 // Make an index of all the posts needed and what their slugs are. 975 $needed_posts = array(); 976 $attachments = $this->prepare_starter_content_attachments( $attachments ); 977 foreach ( $attachments as $attachment ) { 978 $key = 'attachment:' . $attachment['post_name']; 979 $needed_posts[ $key ] = true; 980 } 981 foreach ( array_keys( $posts ) as $post_symbol ) { 982 if ( empty( $posts[ $post_symbol ]['post_name'] ) && empty( $posts[ $post_symbol ]['post_title'] ) ) { 983 unset( $posts[ $post_symbol ] ); 984 continue; 985 } 986 if ( empty( $posts[ $post_symbol ]['post_name'] ) ) { 987 $posts[ $post_symbol ]['post_name'] = sanitize_title( $posts[ $post_symbol ]['post_title'] ); 988 } 989 if ( empty( $posts[ $post_symbol ]['post_type'] ) ) { 990 $posts[ $post_symbol ]['post_type'] = 'post'; 991 } 992 $needed_posts[ $posts[ $post_symbol ]['post_type'] . ':' . $posts[ $post_symbol ]['post_name'] ] = true; 993 } 994 $all_post_slugs = array_merge( 995 wp_list_pluck( $attachments, 'post_name' ), 996 wp_list_pluck( $posts, 'post_name' ) 997 ); 998 999 // Re-use auto-draft starter content posts referenced in the current customized state. 974 1000 $existing_starter_content_posts = array(); 975 1001 if ( ! empty( $starter_content_auto_draft_post_ids ) ) { 976 1002 $existing_posts_query = new WP_Query( array( … … final class WP_Customize_Manager { 984 1010 } 985 1011 } 986 1012 1013 // Re-use non-auto-draft posts. 1014 if ( ! empty( $all_post_slugs ) ) { 1015 $existing_posts_query = new WP_Query( array( 1016 'post_name__in' => $all_post_slugs, 1017 'post_status' => array_diff( get_post_stati(), array( 'auto-draft' ) ), 1018 'post_type' => 'any', 1019 'number' => -1, 1020 ) ); 1021 foreach ( $existing_posts_query->posts as $existing_post ) { 1022 $key = $existing_post->post_type . ':' . $existing_post->post_name; 1023 if ( isset( $needed_posts[ $key ] ) && ! isset( $existing_starter_content_posts[ $key ] ) ) { 1024 $existing_starter_content_posts[ $key ] = $existing_post; 1025 } 1026 } 1027 } 1028 987 1029 // Attachments are technically posts but handled differently. 988 1030 if ( ! empty( $attachments ) ) { 989 // Such is The WordPress Way.990 require_once( ABSPATH . 'wp-admin/includes/file.php' );991 require_once( ABSPATH . 'wp-admin/includes/media.php' );992 require_once( ABSPATH . 'wp-admin/includes/image.php' );993 1031 994 1032 $attachment_ids = array(); 995 1033 996 1034 foreach ( $attachments as $symbol => $attachment ) { 997 998 // A file is required and URLs to files are not currently allowed. 999 if ( empty( $attachment['file'] ) || preg_match( '#^https?://$#', $attachment['file'] ) ) { 1000 continue; 1001 } 1002 1003 $file_array = array(); 1004 $file_path = null; 1005 if ( file_exists( $attachment['file'] ) ) { 1006 $file_path = $attachment['file']; // Could be absolute path to file in plugin. 1007 } elseif ( is_child_theme() && file_exists( get_stylesheet_directory() . '/' . $attachment['file'] ) ) { 1008 $file_path = get_stylesheet_directory() . '/' . $attachment['file']; 1009 } elseif ( file_exists( get_template_directory() . '/' . $attachment['file'] ) ) { 1010 $file_path = get_template_directory() . '/' . $attachment['file']; 1011 } else { 1012 continue; 1013 } 1014 $file_array['name'] = basename( $attachment['file'] ); 1015 1016 // Skip file types that are not recognized. 1017 $checked_filetype = wp_check_filetype( $file_array['name'] ); 1018 if ( empty( $checked_filetype['type'] ) ) { 1019 continue; 1020 } 1021 1022 // Ensure post_name is set since not automatically derived from post_title for new auto-draft posts. 1023 if ( empty( $attachment['post_name'] ) ) { 1024 if ( ! empty( $attachment['post_title'] ) ) { 1025 $attachment['post_name'] = sanitize_title( $attachment['post_title'] ); 1026 } else { 1027 $attachment['post_name'] = sanitize_title( preg_replace( '/\.\w+$/', '', $file_array['name'] ) ); 1028 } 1029 } 1030 1035 $file_array = array( 1036 'name' => $attachment['file_name'], 1037 ); 1038 $file_path = $attachment['file_path']; 1031 1039 $attachment_id = null; 1032 1040 $attached_file = null; 1033 1041 if ( isset( $existing_starter_content_posts[ 'attachment:' . $attachment['post_name'] ] ) ) { … … final class WP_Customize_Manager { 1080 1088 } 1081 1089 1082 1090 $attachment_ids[ $symbol ] = $attachment_id; 1083 $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, array_values( $attachment_ids ) );1084 1091 } 1092 $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, array_values( $attachment_ids ) ); 1085 1093 } 1086 1094 1087 1095 // Posts & pages. 1088 1096 if ( ! empty( $posts ) ) { 1089 1097 foreach ( array_keys( $posts ) as $post_symbol ) { 1090 if ( empty( $posts[ $post_symbol ]['post_type'] ) ) {1098 if ( empty( $posts[ $post_symbol ]['post_type'] ) || empty( $posts[ $post_symbol ]['post_name'] ) ) { 1091 1099 continue; 1092 1100 } 1093 1101 $post_type = $posts[ $post_symbol ]['post_type']; … … final class WP_Customize_Manager { 1241 1249 } 1242 1250 1243 1251 /** 1252 * Prepare starter content attachments. 1253 * 1254 * Ensure that the attachments are valid and that they have slugs and file name/path. 1255 * 1256 * @since 4.7.0 1257 * @access private 1258 * 1259 * @param array $attachments Attachments. 1260 * @return array Prepared attachments. 1261 */ 1262 protected function prepare_starter_content_attachments( $attachments ) { 1263 $prepared_attachments = array(); 1264 if ( empty( $attachments ) ) { 1265 return $prepared_attachments; 1266 } 1267 1268 // Such is The WordPress Way. 1269 require_once( ABSPATH . 'wp-admin/includes/file.php' ); 1270 require_once( ABSPATH . 'wp-admin/includes/media.php' ); 1271 require_once( ABSPATH . 'wp-admin/includes/image.php' ); 1272 1273 foreach ( $attachments as $symbol => $attachment ) { 1274 1275 // A file is required and URLs to files are not currently allowed. 1276 if ( empty( $attachment['file'] ) || preg_match( '#^https?://$#', $attachment['file'] ) ) { 1277 continue; 1278 } 1279 1280 $file_path = null; 1281 if ( file_exists( $attachment['file'] ) ) { 1282 $file_path = $attachment['file']; // Could be absolute path to file in plugin. 1283 } elseif ( is_child_theme() && file_exists( get_stylesheet_directory() . '/' . $attachment['file'] ) ) { 1284 $file_path = get_stylesheet_directory() . '/' . $attachment['file']; 1285 } elseif ( file_exists( get_template_directory() . '/' . $attachment['file'] ) ) { 1286 $file_path = get_template_directory() . '/' . $attachment['file']; 1287 } else { 1288 continue; 1289 } 1290 $file_name = basename( $attachment['file'] ); 1291 1292 // Skip file types that are not recognized. 1293 $checked_filetype = wp_check_filetype( $file_name ); 1294 if ( empty( $checked_filetype['type'] ) ) { 1295 continue; 1296 } 1297 1298 // Ensure post_name is set since not automatically derived from post_title for new auto-draft posts. 1299 if ( empty( $attachment['post_name'] ) ) { 1300 if ( ! empty( $attachment['post_title'] ) ) { 1301 $attachment['post_name'] = sanitize_title( $attachment['post_title'] ); 1302 } else { 1303 $attachment['post_name'] = sanitize_title( preg_replace( '/\.\w+$/', '', $file_name ) ); 1304 } 1305 } 1306 1307 $attachment['file_name'] = $file_name; 1308 $attachment['file_path'] = $file_path; 1309 $prepared_attachments[ $symbol ] = $attachment; 1310 } 1311 return $prepared_attachments; 1312 } 1313 1314 /** 1244 1315 * Save starter content changeset. 1245 1316 * 1246 1317 * @since 4.7.0 -
src/wp-includes/post.php
diff --git src/wp-includes/post.php src/wp-includes/post.php index 620d1e4..2c70fdd 100644
function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p 3673 3673 3674 3674 if ( 'attachment' == $post_type ) { 3675 3675 // Attachment slugs must be unique across all types. 3676 $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_ name = %s AND ID != %d LIMIT 1";3676 $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_status != 'auto-draft' AND post_name = %s AND ID != %d LIMIT 1"; 3677 3677 $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID ) ); 3678 3678 3679 3679 /** … … function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p 3701 3701 * Page slugs must be unique within their own trees. Pages are in a separate 3702 3702 * namespace than posts so page slugs are allowed to overlap post slugs. 3703 3703 */ 3704 $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";3704 $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"; 3705 3705 $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID, $post_parent ) ); 3706 3706 3707 3707 /** … … function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p 3725 3725 } 3726 3726 } else { 3727 3727 // Post slugs must be unique across all posts. 3728 $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_ name = %s AND post_type = %s AND ID != %d LIMIT 1";3728 $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"; 3729 3729 $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID ) ); 3730 3730 3731 3731 // Prevent new post slugs that could result in URLs that conflict with date archives. -
tests/phpunit/tests/post/wpUniquePostSlug.php
diff --git tests/phpunit/tests/post/wpUniquePostSlug.php tests/phpunit/tests/post/wpUniquePostSlug.php index 536017d..a728454 100644
class Tests_Post_WpUniquePostSlug extends WP_UnitTestCase { 347 347 $found = wp_unique_post_slug( 'embed', $p, 'publish', 'attachment', 0 ); 348 348 $this->assertSame( 'embed-2', $found ); 349 349 } 350 351 /** 352 * @ticket 38928 353 */ 354 public function test_non_unique_slugs_for_existing_auto_draft_posts() { 355 $auto_draft_post_id = self::factory()->post->create( array( 356 'post_type' => 'post', 357 'post_name' => 'existing-post', 358 'post_status' => 'auto-draft', 359 ) ); 360 $auto_draft_page_id = self::factory()->post->create( array( 361 'post_type' => 'page', 362 'post_name' => 'existing-page', 363 'post_status' => 'auto-draft', 364 ) ); 365 $auto_draft_attachment_id = self::factory()->attachment->create_object( 'image.jpg', $auto_draft_page_id, array( 366 'post_mime_type' => 'image/jpeg', 367 'post_type' => 'attachment', 368 'post_name' => 'existing-attachment', 369 'post_status' => 'auto-draft', 370 ) ); 371 372 $post_id = self::factory()->post->create( array( 'post_type' => 'post' ) ); 373 $page_id = self::factory()->post->create( array( 'post_type' => 'page' ) ); 374 $attachment_id = self::factory()->attachment->create_object( 'image2.jpg', $page_id, array( 375 'post_mime_type' => 'image/jpeg', 376 'post_type' => 'attachment', 377 'post_name' => 'existing-image', 378 ) ); 379 380 $this->assertEquals( 'existing-post', wp_unique_post_slug( 'existing-post', $post_id, 'publish', get_post_type( $post_id ), 0 ) ); 381 wp_publish_post( $auto_draft_post_id ); 382 $this->assertEquals( 'existing-post-2', wp_unique_post_slug( 'existing-post', $post_id, 'publish', get_post_type( $post_id ), 0 ) ); 383 384 $this->assertEquals( 'existing-page', wp_unique_post_slug( 'existing-page', $page_id, 'publish', get_post_type( $page_id ), 0 ) ); 385 wp_publish_post( $auto_draft_page_id ); 386 $this->assertEquals( 'existing-page-2', wp_unique_post_slug( 'existing-page', $page_id, 'publish', get_post_type( $page_id ), 0 ) ); 387 388 $this->assertEquals( 'existing-attachment', wp_unique_post_slug( 'existing-attachment', $attachment_id, 'publish', get_post_type( $attachment_id ), 0 ) ); 389 wp_publish_post( $auto_draft_attachment_id ); 390 $this->assertEquals( 'existing-attachment-2', wp_unique_post_slug( 'existing-attachment', $attachment_id, 'publish', get_post_type( $attachment_id ), 0 ) ); 391 } 350 392 }