X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/53f4633144ed68c8b8fb5861f992b5489894a940..refs/tags/wordpress-4.5:/wp-includes/theme.php diff --git a/wp-includes/theme.php b/wp-includes/theme.php index 823d2ca4..f4dfaeed 100644 --- a/wp-includes/theme.php +++ b/wp-includes/theme.php @@ -177,7 +177,7 @@ function get_stylesheet_directory() { * * @since 1.5.0 * - * @param string $stylesheet_dir Absolute path to the current them. + * @param string $stylesheet_dir Absolute path to the current theme. * @param string $stylesheet Directory name of the current theme. * @param string $theme_root Absolute path to themes directory. */ @@ -688,16 +688,16 @@ function switch_theme( $stylesheet ) { set_theme_mod( 'sidebars_widgets', array( 'time' => time(), 'data' => $_sidebars_widgets ) ); } - $old_theme = wp_get_theme(); - $new_theme = wp_get_theme( $stylesheet ); + $nav_menu_locations = get_theme_mod( 'nav_menu_locations' ); if ( func_num_args() > 1 ) { - $template = $stylesheet; $stylesheet = func_get_arg( 1 ); - } else { - $template = $new_theme->get_template(); } + $old_theme = wp_get_theme(); + $new_theme = wp_get_theme( $stylesheet ); + $template = $new_theme->get_template(); + update_option( 'template', $template ); update_option( 'stylesheet', $stylesheet ); @@ -716,35 +716,50 @@ function switch_theme( $stylesheet ) { // Migrate from the old mods_{name} option to theme_mods_{slug}. if ( is_admin() && false === get_option( 'theme_mods_' . $stylesheet ) ) { $default_theme_mods = (array) get_option( 'mods_' . $new_name ); + if ( ! empty( $nav_menu_locations ) && empty( $default_theme_mods['nav_menu_locations'] ) ) { + $default_theme_mods['nav_menu_locations'] = $nav_menu_locations; + } add_option( "theme_mods_$stylesheet", $default_theme_mods ); } else { /* * Since retrieve_widgets() is called when initializing a theme in the Customizer, - * we need to to remove the theme mods to avoid overwriting changes made via + * we need to remove the theme mods to avoid overwriting changes made via * the Customizer when accessing wp-admin/widgets.php. */ if ( 'wp_ajax_customize_save' === current_action() ) { remove_theme_mod( 'sidebars_widgets' ); } + + if ( ! empty( $nav_menu_locations ) ) { + $nav_mods = get_theme_mod( 'nav_menu_locations' ); + if ( empty( $nav_mods ) ) { + set_theme_mod( 'nav_menu_locations', $nav_menu_locations ); + } + } } update_option( 'theme_switched', $old_theme->get_stylesheet() ); + /** * Fires after the theme is switched. * * @since 1.5.0 + * @since 4.5.0 Introduced the `$old_theme` parameter. * * @param string $new_name Name of the new theme. * @param WP_Theme $new_theme WP_Theme instance of the new theme. + * @param WP_Theme $old_theme WP_Theme instance of the old theme. */ - do_action( 'switch_theme', $new_name, $new_theme ); + do_action( 'switch_theme', $new_name, $new_theme, $old_theme ); } /** * 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. * @@ -759,27 +774,44 @@ function validate_current_theme() { * * @since 2.7.0 * - * @param bool true Validation flag to check the current theme. + * @param bool $validate Whether to validate the current theme. Default true. */ - if ( defined('WP_INSTALLING') || ! apply_filters( 'validate_current_theme', true ) ) + if ( wp_installing() || ! apply_filters( 'validate_current_theme', true ) ) return true; - if ( get_template() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/index.php') ) { - switch_theme( WP_DEFAULT_THEME ); - return false; + 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; } - if ( get_stylesheet() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/style.css') ) { + $default = wp_get_theme( WP_DEFAULT_THEME ); + if ( $default->exists() ) { switch_theme( WP_DEFAULT_THEME ); return false; } - if ( is_child_theme() && ! file_exists( get_stylesheet_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; } - return true; + switch_theme( $default->get_stylesheet() ); + return false; } /** @@ -917,18 +949,18 @@ function remove_theme_mods() { } /** - * Retrieve text color for custom header. + * Retrieves the custom header text color in HEX format. * * @since 2.1.0 * - * @return string + * @return string Header text color in HEX format (minus the hash symbol). */ function get_header_textcolor() { return get_theme_mod('header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) ); } /** - * Display text color for custom header. + * Displays the custom header text color in HEX format (minus the hash symbol). * * @since 2.1.0 */ @@ -983,6 +1015,83 @@ function get_header_image() { return esc_url_raw( set_url_scheme( $url ) ); } +/** + * Create image tag markup for a custom header image. + * + * @since 4.4.0 + * + * @param array $attr Optional. Additional attributes for the image tag. Can be used + * to override the default attributes. Default empty. + * @return string HTML image element markup or empty string on failure. + */ +function get_header_image_tag( $attr = array() ) { + $header = get_custom_header(); + + if ( empty( $header->url ) ) { + return ''; + } + + $width = absint( $header->width ); + $height = absint( $header->height ); + + $attr = wp_parse_args( + $attr, + array( + 'src' => $header->url, + 'width' => $width, + 'height' => $height, + 'alt' => get_bloginfo( 'name' ), + ) + ); + + // Generate 'srcset' and 'sizes' if not already present. + if ( empty( $attr['srcset'] ) && ! empty( $header->attachment_id ) ) { + $image_meta = get_post_meta( $header->attachment_id, '_wp_attachment_metadata', true ); + $size_array = array( $width, $height ); + + if ( is_array( $image_meta ) ) { + $srcset = wp_calculate_image_srcset( $size_array, $header->url, $image_meta, $header->attachment_id ); + $sizes = ! empty( $attr['sizes'] ) ? $attr['sizes'] : wp_calculate_image_sizes( $size_array, $header->url, $image_meta, $header->attachment_id ); + + if ( $srcset && $sizes ) { + $attr['srcset'] = $srcset; + $attr['sizes'] = $sizes; + } + } + } + + $attr = array_map( 'esc_attr', $attr ); + $html = ' $value ) { + $html .= ' ' . $name . '="' . $value . '"'; + } + + $html .= ' />'; + + /** + * Filter the markup of header images. + * + * @since 4.4.0 + * + * @param string $html The HTML image tag markup being filtered. + * @param object $header The custom header object returned by 'get_custom_header()'. + * @param array $attr Array of the attributes for the image tag. + */ + return apply_filters( 'get_header_image_tag', $html, $header, $attr ); +} + +/** + * Display the image markup for a custom header image. + * + * @since 4.4.0 + * + * @param array $attr Optional. Attributes for the image markup. Default empty. + */ +function the_header_image_tag( $attr = array() ) { + echo get_header_image_tag( $attr ); +} + /** * Get random header image data from registered images in theme. * @@ -1098,7 +1207,7 @@ function get_uploaded_header_images() { foreach ( (array) $headers as $header ) { $url = esc_url_raw( wp_get_attachment_url( $header->ID ) ); $header_data = wp_get_attachment_metadata( $header->ID ); - $header_index = basename($url); + $header_index = $header->ID; $header_images[$header_index] = array(); $header_images[$header_index]['attachment_id'] = $header->ID; @@ -1450,6 +1559,26 @@ function add_theme_support( $feature ) { $args[0] = array_merge( $_wp_theme_features['html5'][0], $args[0] ); break; + case 'custom-logo': + if ( ! is_array( $args ) ) { + $args = array( 0 => array() ); + } + $defaults = array( + 'width' => null, + 'height' => null, + 'flex-width' => false, + 'flex-height' => false, + 'header-text' => '', + ); + $args[0] = wp_parse_args( array_intersect_key( $args[0], $defaults ), $defaults ); + + // Allow full flexibility if no size is specified. + if ( is_null( $args[0]['width'] ) && is_null( $args[0]['height'] ) ) { + $args[0]['flex-width'] = true; + $args[0]['flex-height'] = true; + } + break; + case 'custom-header-uploads' : return add_theme_support( 'custom-header', array( 'uploads' => true ) ); @@ -1622,6 +1751,30 @@ function _custom_header_background_just_in_time() { } } +/** + * Adds CSS to hide header text for custom logo, based on Customizer setting. + * + * @since 4.5.0 + * @access private + */ +function _custom_logo_header_styles() { + if ( ! current_theme_supports( 'custom-header', 'header-text' ) && get_theme_support( 'custom-logo', 'header-text' ) && ! get_theme_mod( 'header_text', true ) ) { + $classes = (array) get_theme_support( 'custom-logo', 'header-text' ); + $classes = array_map( 'sanitize_html_class', $classes ); + $classes = '.' . implode( ', .', $classes ); + + ?> + + +