From 716b7d4d2635f2df142a5e272530a461085c35f7 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Wed, 21 Feb 2024 19:26:08 +0000 Subject: [PATCH] Themes: Use original template paths when switching blogs. This fixes a bug introduced by [57129] and [56635] in which deprecating the previous `TEMPLATEPATH` and `STYLESHEETPATH` constants in favor of `get_template_directory()` and `get_stylesheet_directory()` functions caused the active theme template path to change when using `switch_to_blog()`. This introduces a new function, `wp_set_template_globals()`, which is called during the bootstrap process to store the template paths to new globals values `$wp_template_path` and `$wp_stylesheet_path`. This restores behavior to how things worked prior to [56635] but retains the ability for template values to be reset for better testability. Related #18298, #60025. Props joemcgill, flixos90, mukesh27, swissspidy, manfcarlo, metropolis_john, jeremyfelt. Fixes #60290. Built from https://develop.svn.wordpress.org/trunk@57685 git-svn-id: http://core.svn.wordpress.org/trunk@57186 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/theme.php | 16 +++++++------- wp-includes/comment-template.php | 21 +++++++++---------- wp-includes/load.php | 15 +++++++------ wp-includes/template.php | 36 +++++++++++++++++++++++++------- wp-includes/theme.php | 16 +++++++++++++- wp-includes/version.php | 2 +- wp-settings.php | 3 ++- 7 files changed, 73 insertions(+), 36 deletions(-) diff --git a/wp-admin/includes/theme.php b/wp-admin/includes/theme.php index 0249fb4fe1..e89250b4f7 100644 --- a/wp-admin/includes/theme.php +++ b/wp-admin/includes/theme.php @@ -1160,12 +1160,17 @@ function wp_get_theme_error( $theme ) { * * @since 5.2.0 * + * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. + * @global string $wp_template_path Path to current theme's template directory. + * * @param string $theme Single theme to resume. * @param string $redirect Optional. URL to redirect to. Default empty string. * @return bool|WP_Error True on success, false if `$theme` was not paused, * `WP_Error` on failure. */ function resume_theme( $theme, $redirect = '' ) { + global $wp_stylesheet_path, $wp_template_path; + list( $extension ) = explode( '/', $theme ); /* @@ -1173,14 +1178,11 @@ function resume_theme( $theme, $redirect = '' ) { * creating a fatal error. */ if ( ! empty( $redirect ) ) { - $stylesheet_path = get_stylesheet_directory(); - $template_path = get_template_directory(); - $functions_path = ''; - if ( str_contains( $stylesheet_path, $extension ) ) { - $functions_path = $stylesheet_path . '/functions.php'; - } elseif ( str_contains( $template_path, $extension ) ) { - $functions_path = $template_path . '/functions.php'; + if ( str_contains( $wp_stylesheet_path, $extension ) ) { + $functions_path = $wp_stylesheet_path . '/functions.php'; + } elseif ( str_contains( $wp_template_path, $extension ) ) { + $functions_path = $wp_template_path . '/functions.php'; } if ( ! empty( $functions_path ) ) { diff --git a/wp-includes/comment-template.php b/wp-includes/comment-template.php index 29f440f3a7..d125f0c2dd 100644 --- a/wp-includes/comment-template.php +++ b/wp-includes/comment-template.php @@ -1390,22 +1390,24 @@ function wp_comment_form_unfiltered_html_nonce() { * * @since 1.5.0 * - * @global WP_Query $wp_query WordPress Query object. - * @global WP_Post $post Global post object. - * @global wpdb $wpdb WordPress database abstraction object. + * @global WP_Query $wp_query WordPress Query object. + * @global WP_Post $post Global post object. + * @global wpdb $wpdb WordPress database abstraction object. * @global int $id - * @global WP_Comment $comment Global comment object. + * @global WP_Comment $comment Global comment object. * @global string $user_login * @global string $user_identity * @global bool $overridden_cpage * @global bool $withcomments + * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. + * @global string $wp_template_path Path to current theme's template directory. * * @param string $file Optional. The file to load. Default '/comments.php'. * @param bool $separate_comments Optional. Whether to separate the comments by comment type. * Default false. */ function comments_template( $file = '/comments.php', $separate_comments = false ) { - global $wp_query, $withcomments, $post, $wpdb, $id, $comment, $user_login, $user_identity, $overridden_cpage; + global $wp_query, $withcomments, $post, $wpdb, $id, $comment, $user_login, $user_identity, $overridden_cpage, $wp_stylesheet_path, $wp_template_path; if ( ! ( is_single() || is_page() || $withcomments ) || empty( $post ) ) { return; @@ -1600,10 +1602,7 @@ function comments_template( $file = '/comments.php', $separate_comments = false define( 'COMMENTS_TEMPLATE', true ); } - $stylesheet_path = get_stylesheet_directory(); - $template_path = get_template_directory(); - - $theme_template = $stylesheet_path . $file; + $theme_template = trailingslashit( $wp_stylesheet_path ) . $file; /** * Filters the path to the theme template file used for the comments template. @@ -1616,8 +1615,8 @@ function comments_template( $file = '/comments.php', $separate_comments = false if ( file_exists( $include ) ) { require $include; - } elseif ( file_exists( $template_path . $file ) ) { - require $template_path . $file; + } elseif ( file_exists( trailingslashit( $wp_template_path ) . $file ) ) { + require trailingslashit( $wp_template_path ) . $file; } else { // Backward compat code will be removed in a future release. require ABSPATH . WPINC . '/theme-compat/comments.php'; } diff --git a/wp-includes/load.php b/wp-includes/load.php index d10aff376f..509c1cb319 100644 --- a/wp-includes/load.php +++ b/wp-includes/load.php @@ -1046,12 +1046,14 @@ function wp_skip_paused_plugins( array $plugins ) { * @since 5.1.0 * @access private * - * @global string $pagenow The filename of the current screen. + * @global string $pagenow The filename of the current screen. + * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. + * @global string $wp_template_path Path to current theme's template directory. * * @return string[] Array of absolute paths to theme directories. */ function wp_get_active_and_valid_themes() { - global $pagenow; + global $pagenow, $wp_stylesheet_path, $wp_template_path; $themes = array(); @@ -1059,14 +1061,11 @@ function wp_get_active_and_valid_themes() { return $themes; } - $stylesheet_path = get_stylesheet_directory(); - $template_path = get_template_directory(); - - if ( $template_path !== $stylesheet_path ) { - $themes[] = $stylesheet_path; + if ( is_child_theme() ) { + $themes[] = $wp_stylesheet_path; } - $themes[] = $template_path; + $themes[] = $wp_template_path; /* * Remove themes from the list of active themes when we're on an endpoint diff --git a/wp-includes/template.php b/wp-includes/template.php index 2bb682193c..401df4db19 100644 --- a/wp-includes/template.php +++ b/wp-includes/template.php @@ -679,6 +679,21 @@ function get_attachment_template() { return get_query_template( 'attachment', $templates ); } +/** + * Set up the globals used for template loading. + * + * @since 6.5.0 + * + * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. + * @global string $wp_template_path Path to current theme's template directory. + */ +function wp_set_template_globals() { + global $wp_stylesheet_path, $wp_template_path; + + $wp_stylesheet_path = get_stylesheet_directory(); + $wp_template_path = get_template_directory(); +} + /** * Retrieves the name of the highest priority template file that exists. * @@ -689,6 +704,9 @@ function get_attachment_template() { * @since 2.7.0 * @since 5.5.0 The `$args` parameter was added. * + * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. + * @global string $wp_template_path Path to current theme's template directory. + * * @param string|array $template_names Template file(s) to search for, in order. * @param bool $load If true the template file will be loaded if it is found. * @param bool $load_once Whether to require_once or require. Has no effect if `$load` is false. @@ -698,20 +716,24 @@ function get_attachment_template() { * @return string The template filename if one is located. */ function locate_template( $template_names, $load = false, $load_once = true, $args = array() ) { - $stylesheet_path = get_stylesheet_directory(); - $template_path = get_template_directory(); - $is_child_theme = $stylesheet_path !== $template_path; + global $wp_stylesheet_path, $wp_template_path; + + if ( ! isset( $wp_stylesheet_path ) || ! isset( $wp_template_path ) ) { + wp_set_template_globals(); + } + + $is_child_theme = is_child_theme(); $located = ''; foreach ( (array) $template_names as $template_name ) { if ( ! $template_name ) { continue; } - if ( file_exists( $stylesheet_path . '/' . $template_name ) ) { - $located = $stylesheet_path . '/' . $template_name; + if ( file_exists( $wp_stylesheet_path . '/' . $template_name ) ) { + $located = $wp_stylesheet_path . '/' . $template_name; break; - } elseif ( $is_child_theme && file_exists( $template_path . '/' . $template_name ) ) { - $located = $template_path . '/' . $template_name; + } elseif ( $is_child_theme && file_exists( $wp_template_path . '/' . $template_name ) ) { + $located = $wp_template_path . '/' . $template_name; break; } elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) { $located = ABSPATH . WPINC . '/theme-compat/' . $template_name; diff --git a/wp-includes/theme.php b/wp-includes/theme.php index c8cbc60cc6..7157318b9b 100644 --- a/wp-includes/theme.php +++ b/wp-includes/theme.php @@ -153,11 +153,17 @@ function wp_clean_themes_cache( $clear_update_cache = true ) { * Whether a child theme is in use. * * @since 3.0.0 + * @since 6.5.0 Makes use of global template variables. + * + * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. + * @global string $wp_template_path Path to current theme's template directory. * * @return bool True if a child theme is in use, false otherwise. */ function is_child_theme() { - return get_template_directory() !== get_stylesheet_directory(); + global $wp_stylesheet_path, $wp_template_path; + + return $wp_stylesheet_path !== $wp_template_path; } /** @@ -836,6 +842,14 @@ function switch_theme( $stylesheet ) { update_option( 'theme_switched', $old_theme->get_stylesheet() ); + /* + * Reset template globals when switching themes outside of a switched blog + * context to ensure templates will be loaded from the new theme. + */ + if ( ! is_multisite() || ! ms_is_switched() ) { + wp_set_template_globals(); + } + // Clear pattern caches. if ( ! is_multisite() ) { $new_theme->delete_pattern_cache(); diff --git a/wp-includes/version.php b/wp-includes/version.php index 624b2d0849..96961c8eb1 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.5-beta2-57684'; +$wp_version = '6.5-beta2-57685'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. diff --git a/wp-settings.php b/wp-settings.php index a341cbccdb..a284dcb6e4 100644 --- a/wp-settings.php +++ b/wp-settings.php @@ -608,8 +608,9 @@ $GLOBALS['wp_roles'] = new WP_Roles(); */ do_action( 'setup_theme' ); -// Define the template related constants. +// Define the template related constants and globals. wp_templating_constants(); +wp_set_template_globals(); // Load the default text localization domain. load_default_textdomain();