{ global $wp_theme_directories; if ( $stylesheet_or_template && $theme_root = get_raw_theme_root( $stylesheet_or_template ) ) { // Always prepend WP_CONTENT_DIR unless the root currently registered as a theme directory. // This gives relative theme roots the benefit of the doubt when things go haywire. if ( ! in_array( $theme_root, (array) $wp_theme_directories ) ) $theme_root = WP_CONTENT_DIR . $theme_root; } else { $theme_root = WP_CONTENT_DIR . '/themes'; } /** * Filters the absolute path to the themes directory. * * @since 1.5.0 * * @param string $theme_root Absolute path to themes directory. */ return apply_filters( 'theme_root', $theme_root ); } /** * Retrieve URI for themes directory. * * Does not have trailing slash. * * @since 1.5.0 * * @global array $wp_theme_directories * * @param string $stylesheet_or_template Optional. The stylesheet or template name of the theme. * Default is to leverage the main theme root. * @param string $theme_root Optional. The theme root for which calculations will be based, preventing * the need for a get_raw_theme_root() call. * @return string Themes URI. */ function get_theme_root_uri( $stylesheet_or_template = false, $theme_root = false ) { global $wp_theme_directories; if ( $stylesheet_or_template && ! $theme_root ) $theme_root = get_raw_theme_root( $stylesheet_or_template ); if ( $stylesheet_or_template && $theme_root ) { if ( in_array( $theme_root, (array) $wp_theme_directories ) ) { // Absolute path. Make an educated guess. YMMV -- but note the filter below. if ( 0 === strpos( $theme_root, WP_CONTENT_DIR ) ) $theme_root_uri = content_url( str_replace( WP_CONTENT_DIR, '', $theme_root ) ); elseif ( 0 === strpos( $theme_root, ABSPATH ) ) $theme_root_uri = site_url( str_replace( ABSPATH, '', $theme_root ) ); elseif ( 0 === strpos( $theme_root, WP_PLUGIN_DIR ) || 0 === strpos( $theme_root, WPMU_PLUGIN_DIR ) ) $theme_root_uri = plugins_url( basename( $theme_root ), $theme_root ); else $theme_root_uri = $theme_root; } else { $theme_root_uri = content_url( $theme_root ); } } else { $theme_root_uri = content_url( 'themes' ); } /** * Filters the URI for themes directory. * * @since 1.5.0 * * @param string $theme_root_uri The URI for themes directory. * @param string $siteurl WordPress web address which is set in General Options. * @param string $stylesheet_or_template Stylesheet or template name of the theme. */ return apply_filters( 'theme_root_uri', $theme_root_uri, get_option( 'siteurl' ), $stylesheet_or_template ); } /** * Get the raw theme root relative to the content directory with no filters applied. * * @since 3.1.0 * * @global array $wp_theme_directories * * @param string $stylesheet_or_template The stylesheet or template name of the theme * @param bool $skip_cache Optional. Whether to skip the cache. * Defaults to false, meaning the cache is used. * @return string Theme root */ function get_raw_theme_root( $stylesheet_or_template, $skip_cache = false ) { global $wp_theme_directories; if ( count($wp_theme_directories) <= 1 ) return '/themes'; $theme_root = false; // If requesting the root for the current theme, consult options to avoid calling get_theme_roots() if ( ! $skip_cache ) { if ( get_option('stylesheet') == $stylesheet_or_template ) $theme_root = get_option('stylesheet_root'); elseif ( get_option('template') == $stylesheet_or_template ) $theme_root = get_option('template_root'); } if ( empty($theme_root) ) { $theme_roots = get_theme_roots(); if ( !empty($theme_roots[$stylesheet_or_template]) ) $theme_root = $theme_roots[$stylesheet_or_template]; } return $theme_root; } /** * Display localized stylesheet link element. * * @since 2.1.0 */ function locale_stylesheet() { $stylesheet = get_locale_stylesheet_uri(); if ( empty($stylesheet) ) return; echo ''; } /** * Switches the theme. * * Accepts one argument: $stylesheet of the theme. It also accepts an additional function signature * of two arguments: $template then $stylesheet. This is for backward compatibility. * * @since 2.5.0 * * @global array $wp_theme_directories * @global WP_Customize_Manager $wp_customize * @global array $sidebars_widgets * * @param string $stylesheet Stylesheet name */ function switch_theme( $stylesheet ) { global $wp_theme_directories, $wp_customize, $sidebars_widgets; $_sidebars_widgets = null; if ( 'wp_ajax_customize_save' === current_action() ) { $_sidebars_widgets = $wp_customize->post_value( $wp_customize->get_setting( 'old_sidebars_widgets_data' ) ); } elseif ( is_array( $sidebars_widgets ) ) { $_sidebars_widgets = $sidebars_widgets; } if ( is_array( $_sidebars_widgets ) ) { set_theme_mod( 'sidebars_widgets', array( 'time' => time(), 'data' => $_sidebars_widgets ) ); } $nav_menu_locations = get_theme_mod( 'nav_menu_locations' ); if ( func_num_args() > 1 ) { $stylesheet = func_get_arg( 1 ); } $old_theme = wp_get_theme(); $new_theme = wp_get_theme( $stylesheet ); $template = $new_theme->get_template(); update_option( 'template', $template ); update_option( 'stylesheet', $stylesheet ); if ( count( $wp_theme_directories ) > 1 ) { update_option( 'template_root', get_raw_theme_root( $template, true ) ); update_option( 'stylesheet_root', get_raw_theme_root( $stylesheet, true ) ); } else { delete_option( 'template_root' ); delete_option( 'stylesheet_root' ); } $new_name = $new_theme->get('Name'); update_option( 'current_theme', $new_name ); // 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 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, $old_theme ); } /** * Checks that current theme files 'index.php' and 'style.css' exists. * * 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 {@see 'validate_current_theme'} filter to return false to * disable this functionality. * * @since 1.5.0 * @see WP_DEFAULT_THEME * * @return bool */ function validate_current_theme() { /** * Filters whether to validate the current theme. * * @since 2.7.0 * * @param bool $validate Whether to validate the current theme. Default true. */ if ( wp_installing() || ! apply_filters( 'validate_current_theme', true ) ) return true; 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