Changeset 39346
- Timestamp:
- 11/23/2016 09:52:27 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-content/themes/twentyseventeen/functions.php
r39317 r39346 124 124 'posts' => array( 125 125 'home', 126 'about', 127 'contact', 128 'blog', 129 'homepage-section', 126 'about' => array( 127 'thumbnail' => '{{image-sandwich}}', 128 ), 129 'contact' => array( 130 'thumbnail' => '{{image-espresso}}', 131 ), 132 'blog' => array( 133 'thumbnail' => '{{image-coffee}}', 134 ), 135 'homepage-section' => array( 136 'thumbnail' => '{{image-espresso}}', 137 ), 138 ), 139 140 'attachments' => array( 141 'image-espresso' => array( 142 'post_title' => _x( 'Espresso', 'Theme starter content' ), 143 'file' => 'assets/images/espresso.jpg', 144 ), 145 'image-sandwich' => array( 146 'post_title' => _x( 'Sandwich', 'Theme starter content' ), 147 'file' => 'assets/images/sandwich.jpg', 148 ), 149 'image-coffee' => array( 150 'post_title' => _x( 'Coffee', 'Theme starter content' ), 151 'file' => 'assets/images/coffee.jpg', 152 ), 130 153 ), 131 154 -
trunk/src/wp-includes/class-wp-customize-manager.php
r39345 r39346 917 917 918 918 $sidebars_widgets = isset( $starter_content['widgets'] ) && ! empty( $this->widgets ) ? $starter_content['widgets'] : array(); 919 $attachments = isset( $starter_content['attachments'] ) && ! empty( $this->nav_menus ) ? $starter_content['attachments'] : array(); 919 920 $posts = isset( $starter_content['posts'] ) && ! empty( $this->nav_menus ) ? $starter_content['posts'] : array(); 920 921 $options = isset( $starter_content['options'] ) ? $starter_content['options'] : array(); … … 966 967 } 967 968 969 $starter_content_auto_draft_post_ids = array(); 970 if ( ! empty( $changeset_data['nav_menus_created_posts']['value'] ) ) { 971 $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, $changeset_data['nav_menus_created_posts']['value'] ); 972 } 973 974 $existing_starter_content_posts = array(); 975 if ( ! empty( $starter_content_auto_draft_post_ids ) ) { 976 $existing_posts_query = new WP_Query( array( 977 'post__in' => $starter_content_auto_draft_post_ids, 978 'post_status' => 'auto-draft', 979 'post_type' => 'any', 980 'number' => -1, 981 ) ); 982 foreach ( $existing_posts_query->posts as $existing_post ) { 983 $existing_starter_content_posts[ $existing_post->post_type . ':' . $existing_post->post_name ] = $existing_post; 984 } 985 } 986 987 // Attachments are technically posts but handled differently. 988 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 994 $attachment_ids = array(); 995 996 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 1031 $attachment_id = null; 1032 $attached_file = null; 1033 if ( isset( $existing_starter_content_posts[ 'attachment:' . $attachment['post_name'] ] ) ) { 1034 $attachment_post = $existing_starter_content_posts[ 'attachment:' . $attachment['post_name'] ]; 1035 $attachment_id = $attachment_post->ID; 1036 $attached_file = get_attached_file( $attachment_id ); 1037 if ( empty( $attached_file ) || ! file_exists( $attached_file ) ) { 1038 $attachment_id = null; 1039 $attached_file = null; 1040 } elseif ( $this->get_stylesheet() !== get_post_meta( $attachment_post->ID, '_starter_content_theme', true ) ) { 1041 1042 // Re-generate attachment metadata since it was previously generated for a different theme. 1043 $metadata = wp_generate_attachment_metadata( $attachment_post->ID, $attached_file ); 1044 wp_update_attachment_metadata( $attachment_id, $metadata ); 1045 update_post_meta( $attachment_id, '_starter_content_theme', $this->get_stylesheet() ); 1046 } 1047 } 1048 1049 // Insert the attachment auto-draft because it doesn't yet exist or the attached file is gone. 1050 if ( ! $attachment_id ) { 1051 1052 // Copy file to temp location so that original file won't get deleted from theme after sideloading. 1053 $temp_file_name = wp_tempnam( basename( $file_path ) ); 1054 if ( $temp_file_name && copy( $file_path, $temp_file_name ) ) { 1055 $file_array['tmp_name'] = $temp_file_name; 1056 } 1057 if ( empty( $file_array['tmp_name'] ) ) { 1058 continue; 1059 } 1060 1061 $attachment_post_data = array_merge( 1062 wp_array_slice_assoc( $attachment, array( 'post_title', 'post_content', 'post_excerpt', 'post_name' ) ), 1063 array( 1064 'post_status' => 'auto-draft', // So attachment will be garbage collected in a week if changeset is never published. 1065 ) 1066 ); 1067 1068 // In PHP < 5.6 filesize() returns 0 for the temp files unless we clear the file status cache. 1069 // Technically, PHP < 5.6.0 || < 5.5.13 || < 5.4.29 but no need to be so targeted. 1070 // See https://bugs.php.net/bug.php?id=65701 1071 if ( version_compare( PHP_VERSION, '5.6', '<' ) ) { 1072 clearstatcache(); 1073 } 1074 1075 $attachment_id = media_handle_sideload( $file_array, 0, null, $attachment_post_data ); 1076 if ( is_wp_error( $attachment_id ) ) { 1077 continue; 1078 } 1079 update_post_meta( $attachment_id, '_starter_content_theme', $this->get_stylesheet() ); 1080 } 1081 1082 $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 } 1085 } 1086 968 1087 // Posts & pages. 969 1088 if ( ! empty( $posts ) ) { 970 $nav_menus_created_posts = array();971 if ( ! empty( $changeset_data['nav_menus_created_posts']['value'] ) ) {972 $nav_menus_created_posts = $changeset_data['nav_menus_created_posts']['value'];973 }974 975 $existing_posts = array();976 if ( ! empty( $nav_menus_created_posts ) ) {977 $existing_posts_query = new WP_Query( array(978 'post__in' => $nav_menus_created_posts,979 'post_status' => 'auto-draft',980 'post_type' => 'any',981 'number' => -1,982 ) );983 foreach ( $existing_posts_query->posts as $existing_post ) {984 $existing_posts[ $existing_post->post_type . ':' . $existing_post->post_name ] = $existing_post;985 }986 }987 988 1089 foreach ( array_keys( $posts ) as $post_symbol ) { 989 1090 if ( empty( $posts[ $post_symbol ]['post_type'] ) ) { … … 1000 1101 1001 1102 // Use existing auto-draft post if one already exists with the same type and name. 1002 if ( isset( $existing_ posts[ $post_type . ':' . $post_name ] ) ) {1003 $posts[ $post_symbol ]['ID'] = $existing_ posts[ $post_type . ':' . $post_name ]->ID;1103 if ( isset( $existing_starter_content_posts[ $post_type . ':' . $post_name ] ) ) { 1104 $posts[ $post_symbol ]['ID'] = $existing_starter_content_posts[ $post_type . ':' . $post_name ]->ID; 1004 1105 continue; 1106 } 1107 1108 // Translate the featured image symbol. 1109 if ( ! empty( $posts[ $post_symbol ]['thumbnail'] ) 1110 && preg_match( '/^{{(?P<symbol>.+)}}$/', $posts[ $post_symbol ]['thumbnail'], $matches ) 1111 && isset( $attachment_ids[ $matches['symbol'] ] ) ) { 1112 $posts[ $post_symbol ]['meta_input']['_thumbnail_id'] = $attachment_ids[ $matches['symbol'] ]; 1113 } 1114 1115 if ( ! empty( $posts[ $post_symbol ]['template'] ) ) { 1116 $posts[ $post_symbol ]['meta_input']['_wp_page_template'] = $posts[ $post_symbol ]['template']; 1005 1117 } 1006 1118 … … 1011 1123 } 1012 1124 1013 // The nav_menus_created_posts setting is why nav_menus component is dependency for adding posts. 1125 $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, wp_list_pluck( $posts, 'ID' ) ); 1126 } 1127 1128 // The nav_menus_created_posts setting is why nav_menus component is dependency for adding posts. 1129 if ( ! empty( $this->nav_menus ) && ! empty( $starter_content_auto_draft_post_ids ) ) { 1014 1130 $setting_id = 'nav_menus_created_posts'; 1015 if ( empty( $changeset_data[ $setting_id ] ) || ! empty( $changeset_data[ $setting_id ]['starter_content'] ) ) { 1016 $nav_menus_created_posts = array_unique( array_merge( $nav_menus_created_posts, wp_list_pluck( $posts, 'ID' ) ) ); 1017 $this->set_post_value( $setting_id, array_values( $nav_menus_created_posts ) ); 1018 $this->pending_starter_content_settings_ids[] = $setting_id; 1019 } 1131 $this->set_post_value( $setting_id, array_unique( array_values( $starter_content_auto_draft_post_ids ) ) ); 1132 $this->pending_starter_content_settings_ids[] = $setting_id; 1020 1133 } 1021 1134 -
trunk/src/wp-includes/class-wp-customize-nav-menus.php
r39241 r39346 1192 1192 if ( ! empty( $post_ids ) ) { 1193 1193 foreach ( $post_ids as $post_id ) { 1194 $target_status = 'attachment' === get_post_type( $post_id ) ? 'inherit' : 'publish'; 1195 1194 1196 // Note that wp_publish_post() cannot be used because unique slugs need to be assigned. 1195 wp_update_post( array( 'ID' => $post_id, 'post_status' => 'publish') );1197 wp_update_post( array( 'ID' => $post_id, 'post_status' => $target_status ) ); 1196 1198 } 1197 1199 } -
trunk/src/wp-includes/post.php
r39278 r39346 3059 3059 3060 3060 $post_status = empty( $postarr['post_status'] ) ? 'draft' : $postarr['post_status']; 3061 if ( 'attachment' === $post_type && ! in_array( $post_status, array( 'inherit', 'private', 'trash' )) ) {3061 if ( 'attachment' === $post_type && ! in_array( $post_status, array( 'inherit', 'private', 'trash', 'auto-draft' ), true ) ) { 3062 3062 $post_status = 'inherit'; 3063 3063 } -
trunk/src/wp-includes/theme.php
r39338 r39346 1987 1987 case 'widgets' : 1988 1988 foreach ( $config[ $type ] as $sidebar_id => $widgets ) { 1989 foreach ( $widgets as $ widget ) {1989 foreach ( $widgets as $id => $widget ) { 1990 1990 if ( is_array( $widget ) ) { 1991 1992 // Item extends core content. 1993 if ( ! empty( $core_content[ $type ][ $id ] ) ) { 1994 $widget = array( 1995 $core_content[ $type ][ $id ][0], 1996 array_merge( $core_content[ $type ][ $id ][1], $widget ), 1997 ); 1998 } 1999 1991 2000 $content[ $type ][ $sidebar_id ][] = $widget; 1992 2001 } elseif ( is_string( $widget ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $widget ] ) ) { … … 2008 2017 $content[ $type ][ $nav_menu_location ]['name'] = $nav_menu['name']; 2009 2018 2010 foreach ( $nav_menu['items'] as $ nav_menu_item ) {2019 foreach ( $nav_menu['items'] as $id => $nav_menu_item ) { 2011 2020 if ( is_array( $nav_menu_item ) ) { 2021 2022 // Item extends core content. 2023 if ( ! empty( $core_content[ $type ][ $id ] ) ) { 2024 $nav_menu_item = array_merge( $core_content[ $type ][ $id ], $nav_menu_item ); 2025 } 2026 2012 2027 $content[ $type ][ $nav_menu_location ]['items'][] = $nav_menu_item; 2013 2028 } elseif ( is_string( $nav_menu_item ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $nav_menu_item ] ) ) { … … 2018 2033 break; 2019 2034 2020 // Everything else should map at the next level. 2021 default : 2022 foreach( $config[ $type ] as $i => $item ) { 2035 // Attachments are posts but have special treatment. 2036 case 'attachments' : 2037 foreach ( $config[ $type ] as $id => $item ) { 2038 if ( ! empty( $item['file'] ) ) { 2039 $content[ $type ][ $id ] = $item; 2040 } 2041 } 2042 break; 2043 2044 // All that's left now are posts (besides attachments). Not a default case for the sake of clarity and future work. 2045 case 'posts' : 2046 foreach ( $config[ $type ] as $id => $item ) { 2023 2047 if ( is_array( $item ) ) { 2024 $content[ $type ][ $i ] = $item; 2025 } elseif ( is_string( $item ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $item ] ) ) { 2048 2049 // Item extends core content. 2050 if ( ! empty( $core_content[ $type ][ $id ] ) ) { 2051 $item = array_merge( $core_content[ $type ][ $id ], $item ); 2052 } 2053 2054 // Enforce a subset of fields. 2055 $content[ $type ][ $id ] = wp_array_slice_assoc( 2056 $item, 2057 array( 2058 'post_type', 2059 'post_title', 2060 'post_excerpt', 2061 'post_name', 2062 'post_content', 2063 'menu_order', 2064 'comment_status', 2065 'thumbnail', 2066 'template', 2067 ) 2068 ); 2069 } elseif ( is_string( $item ) && ! empty( $core_content[ $type ][ $item ] ) ) { 2026 2070 $content[ $type ][ $item ] = $core_content[ $type ][ $item ]; 2027 2071 } -
trunk/tests/phpunit/tests/customize/manager.php
r39332 r39346 314 314 function test_import_theme_starter_content() { 315 315 wp_set_current_user( self::$admin_user_id ); 316 register_nav_menu( 'top', 'Top' ); 316 317 317 318 global $wp_customize; … … 344 345 'posts' => array( 345 346 'home', 346 'about', 347 'about' => array( 348 'template' => 'sample-page-template.php', 349 ), 347 350 'blog', 348 351 'custom' => array( 349 352 'post_type' => 'post', 350 353 'post_title' => 'Custom', 354 'thumbnail' => '{{featured-image-logo}}', 355 ), 356 ), 357 'attachments' => array( 358 'featured-image-logo' => array( 359 'post_title' => 'Featured Image', 360 'post_content' => 'Attachment Description', 361 'post_excerpt' => 'Attachment Caption', 362 'file' => DIR_TESTDATA . '/images/waffles.jpg', 351 363 ), 352 364 ), … … 395 407 396 408 $posts_by_name = array(); 409 $this->assertCount( 5, $changeset_values['nav_menus_created_posts'] ); 397 410 foreach ( $changeset_values['nav_menus_created_posts'] as $post_id ) { 398 411 $post = get_post( $post_id ); … … 400 413 $posts_by_name[ $post->post_name ] = $post->ID; 401 414 } 415 $this->assertEquals( array( 'featured-image', 'home', 'about', 'blog', 'custom' ), array_keys( $posts_by_name ) ); 416 $this->assertEquals( 'Custom', get_post( $posts_by_name['custom'] )->post_title ); 417 $this->assertEquals( 'sample-page-template.php', get_page_template_slug( $posts_by_name['about'] ) ); 418 $this->assertEquals( '', get_page_template_slug( $posts_by_name['blog'] ) ); 419 $this->assertEquals( $posts_by_name['featured-image'], get_post_thumbnail_id( $posts_by_name['custom'] ) ); 420 $this->assertEquals( '', get_post_thumbnail_id( $posts_by_name['blog'] ) ); 421 $attachment_metadata = wp_get_attachment_metadata( $posts_by_name['featured-image'] ); 422 $this->assertEquals( 'Featured Image', get_post( $posts_by_name['featured-image'] )->post_title ); 423 $this->assertArrayHasKey( 'file', $attachment_metadata ); 424 $this->assertContains( 'waffles', $attachment_metadata['file'] ); 402 425 403 426 $this->assertEquals( 'page', $changeset_values['show_on_front'] ); … … 419 442 } 420 443 444 // Ensure that re-importing doesn't cause auto-drafts to balloon. 445 $wp_customize->import_theme_starter_content(); 446 $changeset_data = $wp_customize->changeset_data(); 447 $this->assertEqualSets( array_values( $posts_by_name ), $changeset_data['nav_menus_created_posts']['value'], 'Auto-drafts should not get re-created and amended with each import.' ); 448 421 449 // Test that saving non-starter content on top of the changeset clears the starter_content flag. 422 450 $wp_customize->save_changeset_post( array( … … 443 471 $this->assertNotEquals( $previous_blogdescription, $changeset_data['blogdescription']['value'] ); 444 472 $this->assertArrayHasKey( 'starter_content', $changeset_data['blogdescription'] ); 473 474 // Publish. 475 $this->assertEquals( 'auto-draft', get_post( $posts_by_name['about'] )->post_status ); 476 $this->assertEquals( 'auto-draft', get_post( $posts_by_name['featured-image'] )->post_status ); 477 $this->assertNotEquals( $changeset_data['blogname']['value'], get_option( 'blogname' ) ); 478 $r = $wp_customize->save_changeset_post( array( 'status' => 'publish' ) ); 479 $this->assertInternalType( 'array', $r ); 480 $this->assertEquals( 'publish', get_post( $posts_by_name['about'] )->post_status ); 481 $this->assertEquals( 'inherit', get_post( $posts_by_name['featured-image'] )->post_status ); 482 $this->assertEquals( $changeset_data['blogname']['value'], get_option( 'blogname' ) ); 445 483 } 446 484 -
trunk/tests/phpunit/tests/theme/getThemeStarterContent.php
r39276 r39346 42 42 'sidebar-1' => array( 43 43 'text_business_info', 44 'text_about', 44 'text_about' => array( 45 'title' => 'Our Story', 46 ), 45 47 'archives', 46 48 'calendar', … … 64 66 'page_blog', 65 67 'page_news', 66 'page_contact', 68 'page_contact' => array( 69 'title' => 'Email Us', 70 ), 67 71 'link_email', 68 72 'link_facebook', … … 87 91 'about', 88 92 'contact', 89 'blog', 93 'blog' => array( 94 'template' => 'blog.php', 95 'post_excerpt' => 'Extended', 96 ), 90 97 'news', 91 98 'homepage-section', … … 94 101 'post_type' => 'post', 95 102 'post_title' => 'Custom', 103 'thumbnail' => '{{featured-image-logo}}', 104 ), 105 ), 106 'attachments' => array( 107 'featured-image-logo' => array( 108 'post_title' => 'Title', 109 'post_content' => 'Description', 110 'post_excerpt' => 'Caption', 111 'file' => DIR_TESTDATA . '/images/waffles.jpg', 112 ), 113 'featured-image-skipped' => array( 114 'post_title' => 'Skipped', 96 115 ), 97 116 ), … … 116 135 $this->assertCount( 16, $hydrated_starter_content['nav_menus']['top']['items'], 'Unknown should be dropped, custom should be present.' ); 117 136 $this->assertCount( 10, $hydrated_starter_content['widgets']['sidebar-1'], 'Unknown should be dropped.' ); 137 $this->assertCount( 1, $hydrated_starter_content['attachments'], 'Attachment with missing file is filtered out.' ); 138 $this->assertArrayHasKey( 'featured-image-logo', $hydrated_starter_content['attachments'] ); 139 $this->assertSame( $dehydrated_starter_content['attachments']['featured-image-logo'], $hydrated_starter_content['attachments']['featured-image-logo'] ); 118 140 119 141 foreach ( $hydrated_starter_content['widgets']['sidebar-1'] as $widget ) { … … 124 146 $this->assertArrayHasKey( 'title', $widget[1] ); 125 147 } 148 $this->assertEquals( 'text', $hydrated_starter_content['widgets']['sidebar-1'][1][0], 'Core content extended' ); 149 $this->assertEquals( 'Our Story', $hydrated_starter_content['widgets']['sidebar-1'][1][1]['title'], 'Core content extended' ); 126 150 127 151 foreach ( $hydrated_starter_content['nav_menus']['top']['items'] as $nav_menu_item ) { … … 129 153 $this->assertTrue( ! empty( $nav_menu_item['object_id'] ) || ! empty( $nav_menu_item['url'] ) ); 130 154 } 155 $this->assertEquals( 'Email Us', $hydrated_starter_content['nav_menus']['top']['items'][4]['title'], 'Core content extended' ); 131 156 132 157 foreach ( $hydrated_starter_content['posts'] as $key => $post ) { … … 137 162 $this->assertArrayHasKey( 'post_title', $post ); 138 163 } 164 $this->assertEquals( 'Extended', $hydrated_starter_content['posts']['blog']['post_excerpt'], 'Core content extended' ); 165 $this->assertEquals( 'blog.php', $hydrated_starter_content['posts']['blog']['template'], 'Core content extended' ); 166 $this->assertEquals( '{{featured-image-logo}}', $hydrated_starter_content['posts']['custom']['thumbnail'], 'Core content extended' ); 139 167 } 140 168
Note: See TracChangeset
for help on using the changeset viewer.