From a3affe512ba0119896623981ef06612052957df7 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 27 Nov 2023 14:14:07 +0530 Subject: [PATCH 1/6] Update theme.php --- src/wp-includes/theme.php | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index 89fccddd37393..ffb6940eb3c85 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -752,7 +752,7 @@ function locale_stylesheet() { * @param string $stylesheet Stylesheet name. */ function switch_theme( $stylesheet ) { - global $wp_theme_directories, $wp_customize, $sidebars_widgets, $wp_registered_sidebars; + global $wp_theme_directories, $wp_customize, $sidebars_widgets, $wp_registered_sidebars, $wpdb; $requirements = validate_theme_requirements( $stylesheet ); if ( is_wp_error( $requirements ) ) { @@ -840,6 +840,26 @@ function switch_theme( $stylesheet ) { $new_theme->delete_pattern_cache(); $old_theme->delete_pattern_cache(); + // Set autoload=no for the previous all themes. + $theme_mods_compare_value = '%' . $wpdb->esc_like( 'theme_mods_' ) . '%'; + $theme_mods_options = $wpdb->get_results( $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE autoload = 'yes' AND option_name LIKE %s", $theme_mods_compare_value ) ); + + // Loop through fetched options to manage autoload settings. + foreach ( (array) $theme_mods_options as $option ) { + if ( "theme_mods_$stylesheet" === $option->option_name ) { + continue; + } + + // Disable autoload for previous all themes. + wp_set_option_autoload( $option->option_name, 'no' ); + } + + // Set autoload=yes for the switched theme if not already set. + wp_set_option_autoload( "theme_mods_$stylesheet", 'yes' ); + + // Reload autoload options. + wp_load_alloptions(); + /** * Fires after the theme is switched. * From acddf26d7ed3c41905311dffd071a16232b200d4 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 27 Nov 2023 14:15:48 +0530 Subject: [PATCH 2/6] Update theme.php --- src/wp-includes/theme.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index ffb6940eb3c85..989e873c2f6c2 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -748,6 +748,7 @@ function locale_stylesheet() { * @global WP_Customize_Manager $wp_customize * @global array $sidebars_widgets * @global array $wp_registered_sidebars + * @global wpdb $wpdb WordPress database abstraction object. * * @param string $stylesheet Stylesheet name. */ From 73912e213f8f344c4b67c4eebc9e55c07b6723c7 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 27 Nov 2023 14:23:49 +0530 Subject: [PATCH 3/6] Create autoloadThemeMods.php --- .../phpunit/tests/theme/autoloadThemeMods.php | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 tests/phpunit/tests/theme/autoloadThemeMods.php diff --git a/tests/phpunit/tests/theme/autoloadThemeMods.php b/tests/phpunit/tests/theme/autoloadThemeMods.php new file mode 100644 index 0000000000000..fb8075b0ccf51 --- /dev/null +++ b/tests/phpunit/tests/theme/autoloadThemeMods.php @@ -0,0 +1,47 @@ +assertSame( 'no', $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", "theme_mods_$current_theme_stylesheet" ) ), 'Option autoload value not updated in database' ); + $this->assertSame( 'yes', $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", "theme_mods_$new_theme_stylesheet" ) ), 'Option autoload value not updated in database' ); + + // Make sure that autoloaded options are cached properly. + $autoloaded_options = wp_cache_get( 'alloptions', 'options' ); + $this->assertArrayHasKey( "theme_mods_$new_theme_stylesheet", $autoloaded_options, "Option theme_mods_$current_theme_stylesheet unexpectedly deleted from alloptions cache" ); + $this->assertArrayNotHasKey( "theme_mods_$current_theme_stylesheet", $autoloaded_options, "Option theme_mods_$new_theme_stylesheet not deleted from alloptions cache" ); + + 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" ) ), 'Option autoload value not updated in database' ); + $this->assertSame( 'no', $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", "theme_mods_$new_theme_stylesheet" ) ), 'Option autoload value not updated in database' ); + + // Make sure that autoloaded options are cached properly. + $autoloaded_options = wp_cache_get( 'alloptions', 'options' ); + $this->assertArrayNotHasKey( "theme_mods_$new_theme_stylesheet", $autoloaded_options, "Option theme_mods_$new_theme_stylesheet not deleted from alloptions cache" ); + $this->assertArrayHasKey( "theme_mods_$current_theme_stylesheet", $autoloaded_options, "Option theme_mods_$current_theme_stylesheet unexpectedly deleted from alloptions cache" ); + + // And that we haven't lost the mods. + $this->assertSame( 'a-value', get_theme_mod( 'foo-bar-option' ) ); + } +} From 92c4421b272ef9b8443549e75694a7d3b15e4461 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 27 Nov 2023 14:37:18 +0530 Subject: [PATCH 4/6] Update autoloadThemeMods.php --- tests/phpunit/tests/theme/autoloadThemeMods.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/phpunit/tests/theme/autoloadThemeMods.php b/tests/phpunit/tests/theme/autoloadThemeMods.php index fb8075b0ccf51..f0cbd3b808083 100644 --- a/tests/phpunit/tests/theme/autoloadThemeMods.php +++ b/tests/phpunit/tests/theme/autoloadThemeMods.php @@ -23,23 +23,23 @@ function test_thst_on_switch_theme_previous_theme_mods_should_not_be_autoload() switch_theme( $new_theme_stylesheet ); - $this->assertSame( 'no', $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", "theme_mods_$current_theme_stylesheet" ) ), 'Option autoload value not updated in database' ); - $this->assertSame( 'yes', $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", "theme_mods_$new_theme_stylesheet" ) ), 'Option autoload value not updated in database' ); + $this->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' ); // Make sure that autoloaded options are cached properly. $autoloaded_options = wp_cache_get( 'alloptions', 'options' ); - $this->assertArrayHasKey( "theme_mods_$new_theme_stylesheet", $autoloaded_options, "Option theme_mods_$current_theme_stylesheet unexpectedly deleted from alloptions cache" ); - $this->assertArrayNotHasKey( "theme_mods_$current_theme_stylesheet", $autoloaded_options, "Option theme_mods_$new_theme_stylesheet not deleted from alloptions cache" ); + $this->assertArrayHasKey( "theme_mods_$new_theme_stylesheet", $autoloaded_options, "Option theme_mods_$current_theme_stylesheet unexpectedly deleted from alloptions cache" ); + $this->assertArrayNotHasKey( "theme_mods_$current_theme_stylesheet", $autoloaded_options, "Option theme_mods_$new_theme_stylesheet not deleted from alloptions cache" ); 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" ) ), 'Option autoload value not updated in database' ); - $this->assertSame( 'no', $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", "theme_mods_$new_theme_stylesheet" ) ), 'Option autoload value not updated in database' ); + $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' ); // Make sure that autoloaded options are cached properly. $autoloaded_options = wp_cache_get( 'alloptions', 'options' ); - $this->assertArrayNotHasKey( "theme_mods_$new_theme_stylesheet", $autoloaded_options, "Option theme_mods_$new_theme_stylesheet not deleted from alloptions cache" ); - $this->assertArrayHasKey( "theme_mods_$current_theme_stylesheet", $autoloaded_options, "Option theme_mods_$current_theme_stylesheet unexpectedly deleted from alloptions cache" ); + $this->assertArrayNotHasKey( "theme_mods_$new_theme_stylesheet", $autoloaded_options, "Option theme_mods_$new_theme_stylesheet not deleted from alloptions cache" ); + $this->assertArrayHasKey( "theme_mods_$current_theme_stylesheet", $autoloaded_options, "Option theme_mods_$current_theme_stylesheet unexpectedly deleted from alloptions cache" ); // And that we haven't lost the mods. $this->assertSame( 'a-value', get_theme_mod( 'foo-bar-option' ) ); From 90a6168ddb05c8d6403396f261b30ab7082a5a07 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 27 Nov 2023 14:43:48 +0530 Subject: [PATCH 5/6] Update autoloadThemeMods.php --- tests/phpunit/tests/theme/autoloadThemeMods.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/theme/autoloadThemeMods.php b/tests/phpunit/tests/theme/autoloadThemeMods.php index f0cbd3b808083..0598664ff3d1b 100644 --- a/tests/phpunit/tests/theme/autoloadThemeMods.php +++ b/tests/phpunit/tests/theme/autoloadThemeMods.php @@ -12,11 +12,16 @@ */ class Tests_Autoload_Theme_Mods extends WP_Theme_UnitTestCase { - function test_thst_on_switch_theme_previous_theme_mods_should_not_be_autoload() { + /** + * Tests that theme mods should not autoloaded after switch_theme. + * + * @ticket 39537 + */ + public function test_that_on_switch_theme_previous_theme_mods_should_not_be_autoload() { global $wpdb; $current_theme_stylesheet = get_stylesheet(); - + // Set a theme mod for the current theme. $new_theme_stylesheet = 'block-theme'; set_theme_mod( 'foo-bar-option', 'a-value' ); From 2994baf8a2dbcdc3d8c5db668d76b901b05ef6e2 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 28 Nov 2023 21:21:21 +0530 Subject: [PATCH 6/6] Update theme.php --- src/wp-includes/theme.php | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index 989e873c2f6c2..b3091b3e8856e 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -748,12 +748,11 @@ function locale_stylesheet() { * @global WP_Customize_Manager $wp_customize * @global array $sidebars_widgets * @global array $wp_registered_sidebars - * @global wpdb $wpdb WordPress database abstraction object. * * @param string $stylesheet Stylesheet name. */ function switch_theme( $stylesheet ) { - global $wp_theme_directories, $wp_customize, $sidebars_widgets, $wp_registered_sidebars, $wpdb; + global $wp_theme_directories, $wp_customize, $sidebars_widgets, $wp_registered_sidebars; $requirements = validate_theme_requirements( $stylesheet ); if ( is_wp_error( $requirements ) ) { @@ -841,25 +840,15 @@ function switch_theme( $stylesheet ) { $new_theme->delete_pattern_cache(); $old_theme->delete_pattern_cache(); - // Set autoload=no for the previous all themes. - $theme_mods_compare_value = '%' . $wpdb->esc_like( 'theme_mods_' ) . '%'; - $theme_mods_options = $wpdb->get_results( $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE autoload = 'yes' AND option_name LIKE %s", $theme_mods_compare_value ) ); - - // Loop through fetched options to manage autoload settings. - foreach ( (array) $theme_mods_options as $option ) { - if ( "theme_mods_$stylesheet" === $option->option_name ) { - continue; - } - - // Disable autoload for previous all themes. - wp_set_option_autoload( $option->option_name, 'no' ); - } - - // Set autoload=yes for the switched theme if not already set. - wp_set_option_autoload( "theme_mods_$stylesheet", 'yes' ); + // 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 ); // Reload autoload options. - wp_load_alloptions(); + // wp_load_alloptions(); /** * Fires after the theme is switched.