From 7ce128134985dd9fc3cb2a83dccf31d8b8924071 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Mon, 4 Dec 2023 19:36:27 +0000 Subject: [PATCH] Themes: Avoid autoloading the previous theme's theme mods when switching to another theme. This reduces unnecessarily autoloaded data from inactive themes, which can contribute to slow database performance as part of excessive autoloading. Props mukesh27, rajinsharwar, igmoweb, joemcgill, swissspidy, westonruter, flixos90. Fixes #59537. See #59975. git-svn-id: https://develop.svn.wordpress.org/trunk@57153 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/theme.php | 7 ++++ .../phpunit/tests/theme/autoloadThemeMods.php | 42 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tests/phpunit/tests/theme/autoloadThemeMods.php diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index f063bc97a0..81c91ab5cc 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -840,6 +840,13 @@ function switch_theme( $stylesheet ) { $new_theme->delete_pattern_cache(); $old_theme->delete_pattern_cache(); + // Set autoload=no for the old theme, autoload=yes for the switched theme. + $theme_mods_options = array( + 'theme_mods_' . $stylesheet => 'yes', + 'theme_mods_' . $old_theme->get_stylesheet() => 'no', + ); + wp_set_option_autoload_values( $theme_mods_options ); + /** * Fires after the theme is switched. * diff --git a/tests/phpunit/tests/theme/autoloadThemeMods.php b/tests/phpunit/tests/theme/autoloadThemeMods.php new file mode 100644 index 0000000000..e653ac6a77 --- /dev/null +++ b/tests/phpunit/tests/theme/autoloadThemeMods.php @@ -0,0 +1,42 @@ +assertSame( 'no', $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", "theme_mods_$current_theme_stylesheet" ) ), 'Theme mods autoload value not set to no in database' ); + $this->assertSame( 'yes', $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", "theme_mods_$new_theme_stylesheet" ) ), 'Theme mods autoload value not set to yes in database' ); + + switch_theme( $current_theme_stylesheet ); + + $this->assertSame( 'yes', $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", "theme_mods_$current_theme_stylesheet" ) ), 'Theme mods autoload value not set to yes in database' ); + $this->assertSame( 'no', $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", "theme_mods_$new_theme_stylesheet" ) ), 'Theme mods autoload value not set to no in database' ); + + // Basic assertion to make sure that we haven't lost the mods. + $this->assertSame( 'a-value', get_theme_mod( 'foo-bar-option' ) ); + } +}