Make WordPress Core


Ignore:
Timestamp:
11/20/2023 10:27:17 PM (5 months ago)
Author:
joemcgill
Message:

Themes: Remove memoization from stylesheet and theme directories.

This fixes bugs introduced in [56635] whereby the template or stylesheet path could be memoized incorrectly if get_template_directory() or get_stylesheet_directory() were called before the theme has been fully initialized.

Props partyfrikadelle, coreyw, kdowns, rebasaurus, meta4, flixos90, mukesh27, joemcgill.
Fixes #59847.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/theme.php

    r57009 r57129  
    189189 * @since 1.5.0
    190190 * @since 6.4.0 Memoizes filter execution so that it only runs once for the current theme.
    191  *
    192  * @global string $wp_stylesheet_path Current theme stylesheet directory path.
     191 * @since 6.4.2 Memoization removed.
    193192 *
    194193 * @return string Path to active theme's stylesheet directory.
    195194 */
    196195function get_stylesheet_directory() {
    197     global $wp_stylesheet_path;
    198 
    199     if ( null === $wp_stylesheet_path ) {
    200         $stylesheet     = get_stylesheet();
    201         $theme_root     = get_theme_root( $stylesheet );
    202         $stylesheet_dir = "$theme_root/$stylesheet";
    203 
    204         /**
    205          * Filters the stylesheet directory path for the active theme.
    206          *
    207          * @since 1.5.0
    208          *
    209          * @param string $stylesheet_dir Absolute path to the active theme.
    210          * @param string $stylesheet     Directory name of the active theme.
    211          * @param string $theme_root     Absolute path to themes directory.
    212          */
    213         $stylesheet_dir = apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root );
    214 
    215         // If there are filter callbacks, force the logic to execute on every call.
    216         if ( has_filter( 'stylesheet' ) || has_filter( 'theme_root' ) || has_filter( 'stylesheet_directory' ) ) {
    217             return $stylesheet_dir;
    218         }
    219 
    220         $wp_stylesheet_path = $stylesheet_dir;
    221     }
    222 
    223     return $wp_stylesheet_path;
     196    $stylesheet     = get_stylesheet();
     197    $theme_root     = get_theme_root( $stylesheet );
     198    $stylesheet_dir = "$theme_root/$stylesheet";
     199
     200    /**
     201     * Filters the stylesheet directory path for the active theme.
     202     *
     203     * @since 1.5.0
     204     *
     205     * @param string $stylesheet_dir Absolute path to the active theme.
     206     * @param string $stylesheet     Directory name of the active theme.
     207     * @param string $theme_root     Absolute path to themes directory.
     208     */
     209    return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root );
    224210}
    225211
     
    339325 * @since 1.5.0
    340326 * @since 6.4.0 Memoizes filter execution so that it only runs once for the current theme.
    341  *
    342  * @global string $wp_template_path Current theme template directory path.
     327 * @since 6.4.1 Memoization removed.
    343328 *
    344329 * @return string Path to active theme's template directory.
    345330 */
    346331function get_template_directory() {
    347     global $wp_template_path;
    348 
    349     if ( null === $wp_template_path ) {
    350         $template     = get_template();
    351         $theme_root   = get_theme_root( $template );
    352         $template_dir = "$theme_root/$template";
    353 
    354         /**
    355          * Filters the active theme directory path.
    356          *
    357          * @since 1.5.0
    358          *
    359          * @param string $template_dir The path of the active theme directory.
    360          * @param string $template     Directory name of the active theme.
    361          * @param string $theme_root   Absolute path to the themes directory.
    362          */
    363         $template_dir = apply_filters( 'template_directory', $template_dir, $template, $theme_root );
    364 
    365         // If there are filter callbacks, force the logic to execute on every call.
    366         if ( has_filter( 'template' ) || has_filter( 'theme_root' ) || has_filter( 'template_directory' ) ) {
    367             return $template_dir;
    368         }
    369 
    370         $wp_template_path = $template_dir;
    371     }
    372 
    373     return $wp_template_path;
     332    $template     = get_template();
     333    $theme_root   = get_theme_root( $template );
     334    $template_dir = "$theme_root/$template";
     335
     336    /**
     337     * Filters the active theme directory path.
     338     *
     339     * @since 1.5.0
     340     *
     341     * @param string $template_dir The path of the active theme directory.
     342     * @param string $template     Directory name of the active theme.
     343     * @param string $theme_root   Absolute path to the themes directory.
     344     */
     345    return apply_filters( 'template_directory', $template_dir, $template, $theme_root );
    374346}
    375347
     
    777749 * @global array                $sidebars_widgets
    778750 * @global array                $wp_registered_sidebars
    779  * @global string               $wp_stylesheet_path
    780  * @global string               $wp_template_path
    781751 *
    782752 * @param string $stylesheet Stylesheet name.
    783753 */
    784754function switch_theme( $stylesheet ) {
    785     global $wp_theme_directories, $wp_customize, $sidebars_widgets, $wp_registered_sidebars, $wp_stylesheet_path, $wp_template_path;
     755    global $wp_theme_directories, $wp_customize, $sidebars_widgets, $wp_registered_sidebars;
    786756
    787757    $requirements = validate_theme_requirements( $stylesheet );
     
    866836
    867837    update_option( 'theme_switched', $old_theme->get_stylesheet() );
    868 
    869     /*
    870      * Reset globals to force refresh the next time these directories are
    871      * accessed via `get_stylesheet_directory()` / `get_template_directory()`.
    872      */
    873     $wp_stylesheet_path = null;
    874     $wp_template_path   = null;
    875838
    876839    // Clear pattern caches.
Note: See TracChangeset for help on using the changeset viewer.