diff --git a/wp-admin/includes/schema.php b/wp-admin/includes/schema.php index 05e82cee21..4f49dc21e1 100644 --- a/wp-admin/includes/schema.php +++ b/wp-admin/includes/schema.php @@ -368,11 +368,18 @@ function populate_options() { $uploads_use_yearmonth_folders = 1; } - $template = WP_DEFAULT_THEME; - // If default theme is a child theme, we need to get its template - $theme = wp_get_theme( $template ); - if ( ! $theme->errors() ) - $template = $theme->get_template(); + // If WP_DEFAULT_THEME doesn't exist, fall back to the latest core default theme. + $stylesheet = $template = WP_DEFAULT_THEME; + $theme = wp_get_theme( WP_DEFAULT_THEME ); + if ( ! $theme->exists() ) { + $theme = WP_Theme::get_core_default_theme(); + } + + // If we can't find a core default theme, WP_DEFAULT_THEME is the best we can do. + if ( $theme ) { + $stylesheet = $theme->get_stylesheet(); + $template = $theme->get_template(); + } $timezone_string = ''; $gmt_offset = 0; @@ -433,7 +440,7 @@ function populate_options() { 'default_email_category' => 1, 'recently_edited' => '', 'template' => $template, - 'stylesheet' => WP_DEFAULT_THEME, + 'stylesheet' => $stylesheet, 'comment_whitelist' => 1, 'blacklist_keys' => '', 'comment_registration' => 0, @@ -914,10 +921,21 @@ function populate_network( $network_id = 1, $domain = '', $email = '', $site_nam $template = get_option( 'template' ); $stylesheet = get_option( 'stylesheet' ); $allowed_themes = array( $stylesheet => true ); - if ( $template != $stylesheet ) + + if ( $template != $stylesheet ) { $allowed_themes[ $template ] = true; - if ( WP_DEFAULT_THEME != $stylesheet && WP_DEFAULT_THEME != $template ) + } + + if ( WP_DEFAULT_THEME != $stylesheet && WP_DEFAULT_THEME != $template ) { $allowed_themes[ WP_DEFAULT_THEME ] = true; + } + + // If WP_DEFAULT_THEME doesn't exist, also whitelist the latest core default theme. + if ( ! wp_get_theme( WP_DEFAULT_THEME )->exists() ) { + if ( $core_default = WP_Theme::get_core_default_theme() ) { + $allowed_themes[ $core_default->get_stylesheet() ] = true; + } + } if ( 1 == $network_id ) { $wpdb->insert( $wpdb->site, array( 'domain' => $domain, 'path' => $path ) ); diff --git a/wp-admin/includes/update-core.php b/wp-admin/includes/update-core.php index a6015e1516..9f17a086d9 100644 --- a/wp-admin/includes/update-core.php +++ b/wp-admin/includes/update-core.php @@ -715,6 +715,9 @@ $_old_files = array( * Directories should be noted by suffixing it with a trailing slash (/) * * @since 3.2.0 + * @since 4.4.0 New themes are not automatically installed on upgrade. + * This can still be explicitly asked for by defining + * CORE_UPGRADE_SKIP_NEW_BUNDLED as false. * @global array $_new_bundled_files * @var array * @name $_new_bundled_files @@ -732,6 +735,11 @@ $_new_bundled_files = array( 'themes/twentysixteen/' => '4.4', ); +// If not explicitly defined as false, don't install new default themes. +if ( ! defined( 'CORE_UPGRADE_SKIP_NEW_BUNDLED' ) || CORE_UPGRADE_SKIP_NEW_BUNDLED ) { + $_new_bundled_files = array( 'plugins/akismet/' => '2.0' ); +} + /** * Upgrade the core of WordPress. * diff --git a/wp-includes/class-wp-theme.php b/wp-includes/class-wp-theme.php index e7e142d6fb..2128df230f 100644 --- a/wp-includes/class-wp-theme.php +++ b/wp-includes/class-wp-theme.php @@ -56,6 +56,7 @@ final class WP_Theme implements ArrayAccess { 'twentythirteen' => 'Twenty Thirteen', 'twentyfourteen' => 'Twenty Fourteen', 'twentyfifteen' => 'Twenty Fifteen', + 'twentysixteen' => 'Twenty Sixteen', ); /** @@ -1150,6 +1151,23 @@ final class WP_Theme implements ArrayAccess { return false; } + /** + * Determines the latest WordPress default theme that is installed. + * + * This hits the filesystem. + * + * @return WP_Theme|false Object, or false if no theme is installed, which would be bad. + */ + public static function get_core_default_theme() { + foreach ( array_reverse( self::$default_themes ) as $slug => $name ) { + $theme = wp_get_theme( $slug ); + if ( $theme->exists() ) { + return $theme; + } + } + return false; + } + /** * Returns array of stylesheet names of themes allowed on the site or network. * diff --git a/wp-includes/default-constants.php b/wp-includes/default-constants.php index 12d6123023..774446e9e4 100644 --- a/wp-includes/default-constants.php +++ b/wp-includes/default-constants.php @@ -348,8 +348,10 @@ function wp_templating_constants() { /** * Slug of the default theme for this install. * Used as the default theme when installing new sites. - * Will be used as the fallback if the current theme doesn't exist. + * It will be used as the fallback if the current theme doesn't exist. + * * @since 3.0.0 + * @see WP_Theme::get_core_default_theme() */ if ( !defined('WP_DEFAULT_THEME') ) define( 'WP_DEFAULT_THEME', 'twentyfifteen' ); diff --git a/wp-includes/theme.php b/wp-includes/theme.php index 395d42810a..47c9661778 100644 --- a/wp-includes/theme.php +++ b/wp-includes/theme.php @@ -753,8 +753,10 @@ function switch_theme( $stylesheet ) { /** * Checks that current theme files 'index.php' and 'style.css' exists. * - * Does not check the default theme, which is the fallback and should always exist. + * Does not initially check the default theme, which is the fallback and should always exist. + * But if it doesn't exist, it'll fall back to the latest core default theme that does exist. * Will switch theme to the fallback theme if current theme does not validate. + * * You can use the 'validate_current_theme' filter to return false to * disable this functionality. * @@ -774,22 +776,39 @@ function validate_current_theme() { if ( wp_installing() || ! apply_filters( 'validate_current_theme', true ) ) return true; - if ( get_template() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/index.php') ) { + if ( ! file_exists( get_template_directory() . '/index.php' ) ) { + // Invalid. + } elseif ( ! file_exists( get_template_directory() . '/style.css' ) ) { + // Invalid. + } elseif ( is_child_theme() && ! file_exists( get_stylesheet_directory() . '/style.css' ) ) { + // Invalid. + } else { + // Valid. + return true; + } + + $default = wp_get_theme( WP_DEFAULT_THEME ); + if ( $default->exists() ) { switch_theme( WP_DEFAULT_THEME ); return false; } - if ( get_stylesheet() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/style.css') ) { - switch_theme( WP_DEFAULT_THEME ); - return false; + /** + * If we're in an invalid state but WP_DEFAULT_THEME doesn't exist, + * switch to the latest core default theme that's installed. + * If it turns out that this latest core default theme is our current + * theme, then there's nothing we can do about that, so we have to bail, + * rather than going into an infinite loop. (This is why there are + * checks against WP_DEFAULT_THEME above, also.) We also can't do anything + * if it turns out there is no default theme installed. (That's `false`.) + */ + $default = WP_Theme::get_core_default_theme(); + if ( false === $default || get_stylesheet() == $default->get_stylesheet() ) { + return true; } - if ( is_child_theme() && ! file_exists( get_stylesheet_directory() . '/style.css' ) ) { - switch_theme( WP_DEFAULT_THEME ); - return false; - } - - return true; + switch_theme( $default->get_stylesheet() ); + return false; } /** diff --git a/wp-includes/version.php b/wp-includes/version.php index 7cac484ce4..b1477a384b 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '4.4-beta4-35737'; +$wp_version = '4.4-beta4-35738'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.