diff --git a/src/wp-includes/class-wp-customize-setting.php b/src/wp-includes/class-wp-customize-setting.php index 65fa2e2234..c7cff51fe5 100644 --- a/src/wp-includes/class-wp-customize-setting.php +++ b/src/wp-includes/class-wp-customize-setting.php @@ -143,6 +143,11 @@ class WP_Customize_Setting { if ( 'option' === $this->type || 'theme_mod' === $this->type ) { // Other setting types can opt-in to aggregate multidimensional explicitly. $this->aggregate_multidimensional(); + + // Allow option settings to indicate whether they should be autoloaded. + if ( 'option' === $this->type && isset( $args['autoload'] ) ) { + self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['autoload'] = $args['autoload']; + } } } @@ -173,10 +178,6 @@ class WP_Customize_Setting { * @access protected */ protected function aggregate_multidimensional() { - if ( empty( $this->id_data['keys'] ) ) { - return; - } - $id_base = $this->id_data['base']; if ( ! isset( self::$aggregated_multidimensionals[ $this->type ] ) ) { self::$aggregated_multidimensionals[ $this->type ] = array(); @@ -188,7 +189,10 @@ class WP_Customize_Setting { 'root_value' => $this->get_root_value( array() ), // Root value for initial state, manipulated by preview and update calls. ); } - $this->is_multidimensional_aggregated = true; + + if ( ! empty( $this->id_data['keys'] ) ) { + $this->is_multidimensional_aggregated = true; + } } /** @@ -502,7 +506,11 @@ class WP_Customize_Setting { protected function set_root_value( $value ) { $id_base = $this->id_data['base']; if ( 'option' === $this->type ) { - return update_option( $id_base, $value ); + $autoload = true; + if ( isset( self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['autoload'] ) ) { + $autoload = self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['autoload']; + } + return update_option( $id_base, $value, $autoload ); } else if ( 'theme_mod' ) { set_theme_mod( $id_base, $value ); return true; diff --git a/tests/phpunit/tests/customize/setting.php b/tests/phpunit/tests/customize/setting.php index 296554b08d..da789b12d1 100644 --- a/tests/phpunit/tests/customize/setting.php +++ b/tests/phpunit/tests/customize/setting.php @@ -472,5 +472,62 @@ class Tests_WP_Customize_Setting extends WP_UnitTestCase { $this->assertNotEquals( $post_value, get_option( $name ) ); restore_current_blog(); } + + /** + * @ticket 33499 + */ + function test_option_autoloading() { + global $wpdb; + wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) ); + + $name = 'autoloaded1'; + $setting = new WP_Customize_Setting( $this->manager, $name, array( + 'type' => 'option', + ) ); + $value = 'value1'; + $this->manager->set_post_value( $setting->id, $value ); + $setting->save(); + $autoload = $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", $setting->id ) ); + $this->assertEquals( 'yes', $autoload ); + $this->assertEquals( $value, get_option( $name ) ); + + $name = 'autoloaded2'; + $setting = new WP_Customize_Setting( $this->manager, $name, array( + 'type' => 'option', + 'autoload' => true, + ) ); + $value = 'value2'; + $this->manager->set_post_value( $setting->id, $value ); + $setting->save(); + $autoload = $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", $setting->id ) ); + $this->assertEquals( 'yes', $autoload ); + $this->assertEquals( $value, get_option( $name ) ); + + $name = 'not-autoloaded1'; + $setting = new WP_Customize_Setting( $this->manager, $name, array( + 'type' => 'option', + 'autoload' => false, + ) ); + $value = 'value3'; + $this->manager->set_post_value( $setting->id, $value ); + $setting->save(); + $autoload = $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", $setting->id ) ); + $this->assertEquals( 'no', $autoload ); + $this->assertEquals( $value, get_option( $name ) ); + + $id_base = 'multi-not-autoloaded'; + $setting1 = new WP_Customize_Setting( $this->manager, $id_base . '[foo]', array( + 'type' => 'option', + ) ); + $setting2 = new WP_Customize_Setting( $this->manager, $id_base . '[bar]', array( + 'type' => 'option', + 'autoload' => false, + ) ); + $this->manager->set_post_value( $setting1->id, 'value1' ); + $this->manager->set_post_value( $setting2->id, 'value2' ); + $setting1->save(); + $autoload = $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", $id_base ) ); + $this->assertEquals( 'no', $autoload, 'Even though setting1 did not indicate autoload (thus normally true), since another multidimensional option setting of the base did say autoload=false, it should be autoload=no' ); + } }