Make WordPress Core

Ticket #31484: 31484.3.diff

File 31484.3.diff, 20.2 KB (added by westonruter, 10 years ago)

Additional changes: https://github.com/xwp/wordpress-develop/compare/df2f03f...21c7e5

  • src/wp-admin/customize.php

    diff --git src/wp-admin/customize.php src/wp-admin/customize.php
    index d6cec32..a858c25 100644
    do_action( 'customize_controls_print_scripts' ); 
    252252                $settings['settings'][ $id ] = array(
    253253                        'value'     => $setting->js_value(),
    254254                        'transport' => $setting->transport,
     255                        'dirty'     => $setting->dirty,
    255256                );
    256257        }
    257258
  • src/wp-admin/js/customize-controls.js

    diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js
    index d95287c..ccce08e 100644
     
    1717
    1818                        this.id = id;
    1919                        this.transport = this.transport || 'refresh';
     20                        this._dirty = options.dirty || false;
    2021
    2122                        this.bind( this.preview );
    2223                },
     
    24242425                $.each( api.settings.settings, function( id, data ) {
    24252426                        api.create( id, id, data.value, {
    24262427                                transport: data.transport,
    2427                                 previewer: api.previewer
     2428                                previewer: api.previewer,
     2429                                dirty: !! data.dirty
    24282430                        } );
    24292431                });
    24302432
  • src/wp-includes/class-wp-customize-manager.php

    diff --git src/wp-includes/class-wp-customize-manager.php src/wp-includes/class-wp-customize-manager.php
    index ffdb3f3..d050345 100644
    final class WP_Customize_Manager { 
    695695         * Switch the theme and trigger the save() method on each setting.
    696696         *
    697697         * @since 3.4.0
     698         * @since 4.1.2 Add $options param.
     699         *
     700         * @param array $options {
     701         *      Override default behaviors for save method.
     702         *      @type bool $check_ajax_referer Whether check_ajax_referer() is performed. Defaults to true.
     703         *      @type bool $send_json Whether to return json; if false, returns WP_Error on failure, and the customize_save_response array on success. Defaults to true.
     704         * }
     705         * @return WP_Error|array|null
    698706         */
    699         public function save() {
     707        public function save( $options = array() ) {
     708                $options = array_merge(
     709                        array(
     710                                'check_ajax_referer' => true,
     711                                'send_json' => true,
     712                        ),
     713                        empty( $options ) ? array() : $options
     714                );
     715
    700716                if ( ! $this->is_preview() ) {
    701                         wp_send_json_error( 'not_preview' );
     717                        $error = 'not_preview';
     718                        if ( $options['send_json'] ) {
     719                                wp_send_json_error( $error );
     720                        } else {
     721                                return new WP_Error( $error );
     722                        }
    702723                }
    703724
    704725                $action = 'save-customize_' . $this->get_stylesheet();
    705                 if ( ! check_ajax_referer( $action, 'nonce', false ) ) {
    706                         wp_send_json_error( 'invalid_nonce' );
     726                if ( $options['check_ajax_referer'] && ! check_ajax_referer( $action, 'nonce', false ) ) {
     727                        $error = 'invalid_nonce';
     728                        if ( $options['send_json'] ) {
     729                                wp_send_json_error( $error );
     730                        } else {
     731                                return new WP_Error( $error );
     732                        }
    707733                }
    708734
     735                /**
     736                 * Fires before the theme has switched in the Customizer, and before settings
     737                 * have been saved.
     738                 *
     739                 * @since 4.1.2
     740                 *
     741                 * @param WP_Customize_Manager $this WP_Customize_Manager instance.
     742                 */
     743                do_action( 'customize_save_before_switch_theme', $this );
     744
    709745                // Do we have to switch themes?
    710746                if ( ! $this->is_theme_active() ) {
    711747                        // Temporarily stop previewing the theme to allow switch_themes()
    final class WP_Customize_Manager { 
    751787                 * @param WP_Customize_Manager $this WP_Customize_Manager instance.
    752788                 */
    753789                $response = apply_filters( 'customize_save_response', array(), $this );
    754                 wp_send_json_success( $response );
     790                if ( $options['send_json'] ) {
     791                        wp_send_json_success( $response );
     792                } else {
     793                        return $response;
     794                }
    755795        }
    756796
    757797        /**
  • src/wp-includes/class-wp-customize-setting.php

    diff --git src/wp-includes/class-wp-customize-setting.php src/wp-includes/class-wp-customize-setting.php
    index 5618314..18598dc 100644
    class WP_Customize_Setting { 
    6060        public $sanitize_callback    = '';
    6161        public $sanitize_js_callback = '';
    6262
     63        /**
     64         * Whether or not the setting is initially dirty when created.
     65         *
     66         * This is used to ensure that a setting will be sent from the pane to the
     67         * preview when loading the Customizer. Normally a setting only is synced to
     68         * the preview if it has been changed. This allows the setting to be sent
     69         * from the start.
     70         *
     71         * @since 4.1.2
     72         * @access public
     73         * @var bool
     74         */
     75        public $dirty = false;
     76
    6377        protected $id_data = array();
    6478
    6579        /**
  • src/wp-includes/class-wp-customize-widgets.php

    diff --git src/wp-includes/class-wp-customize-widgets.php src/wp-includes/class-wp-customize-widgets.php
    index 674dee6..79193f9 100644
    final class WP_Customize_Widgets { 
    216216                $sidebars_widgets = $this->old_sidebars_widgets;
    217217                $sidebars_widgets = retrieve_widgets( 'customize' );
    218218                add_filter( 'option_sidebars_widgets', array( $this, 'filter_option_sidebars_widgets_for_theme_switch' ), 1 );
     219                unset( $GLOBALS['_wp_sidebars_widgets'] ); // reset global cache var used by wp_get_sidebars_widgets()
    219220        }
    220221
    221222        /**
    final class WP_Customize_Widgets { 
    232233         * @access public
    233234         *
    234235         * @param array $old_sidebars_widgets
     236         * @return array
    235237         */
    236238        public function filter_customize_value_old_sidebars_widgets_data( $old_sidebars_widgets ) {
    237239                return $this->old_sidebars_widgets;
    final class WP_Customize_Widgets { 
    249251         * @access public
    250252         *
    251253         * @param array $sidebars_widgets
     254         * @return array
    252255         */
    253256        public function filter_option_sidebars_widgets_for_theme_switch( $sidebars_widgets ) {
    254257                $sidebars_widgets = $GLOBALS['sidebars_widgets'];
    final class WP_Customize_Widgets { 
    332335                        $setting_id = 'old_sidebars_widgets_data';
    333336                        $setting_args = $this->get_setting_args( $setting_id, array(
    334337                                'type' => 'global_variable',
     338                                'dirty' => true,
    335339                        ) );
    336340                        $this->manager->add_setting( $setting_id, $setting_args );
    337341                }
    final class WP_Customize_Widgets { 
    356360                                $setting_id   = sprintf( 'sidebars_widgets[%s]', $sidebar_id );
    357361                                $setting_args = $this->get_setting_args( $setting_id );
    358362                                if ( ! $this->manager->get_setting( $setting_id ) ) {
     363                                        if ( ! $this->manager->is_theme_active() ) {
     364                                                $setting_args['dirty'] = true;
     365                                        }
    359366                                        $this->manager->add_setting( $setting_id, $setting_args );
    360367                                }
    361368                                $new_setting_ids[] = $setting_id;
    final class WP_Customize_Widgets { 
    894901         * @access public
    895902         *
    896903         * @param array $sidebars_widgets List of widgets for the current sidebar.
     904         * @return array
    897905         */
    898906        public function preview_sidebars_widgets( $sidebars_widgets ) {
    899907                $sidebars_widgets = get_option( 'sidebars_widgets' );
  • src/wp-includes/class-wp-theme.php

    diff --git src/wp-includes/class-wp-theme.php src/wp-includes/class-wp-theme.php
    index 523c733..41e2ca2 100644
    final class WP_Theme implements ArrayAccess { 
    11211121         * @return array Array of stylesheet names.
    11221122         */
    11231123        public static function get_allowed_on_network() {
    1124                 static $allowed_themes;
    1125                 if ( ! isset( $allowed_themes ) )
    1126                         $allowed_themes = (array) get_site_option( 'allowedthemes' );
    1127                 return $allowed_themes;
     1124                return (array) get_site_option( 'allowedthemes' );
    11281125        }
    11291126
    11301127        /**
    final class WP_Theme implements ArrayAccess { 
    11371134         * @return array Array of stylesheet names.
    11381135         */
    11391136        public static function get_allowed_on_site( $blog_id = null ) {
    1140                 static $allowed_themes = array();
     1137                $allowed_themes = wp_cache_get( 'themes_allowed_on_site' );
     1138                if ( empty( $allowed_themes ) ) {
     1139                        $allowed_themes = array();
     1140                }
    11411141
    11421142                if ( ! $blog_id || ! is_multisite() )
    11431143                        $blog_id = get_current_blog_id();
    final class WP_Theme implements ArrayAccess { 
    11911191                        }
    11921192                }
    11931193
    1194                 return (array) $allowed_themes[ $blog_id ];
     1194                $allowed_on_site = (array) $allowed_themes[ $blog_id ];
     1195                wp_cache_set( 'themes_allowed_on_site', $allowed_on_site );
     1196                return $allowed_on_site;
    11951197        }
    11961198
    11971199        /**
  • src/wp-includes/theme.php

    diff --git src/wp-includes/theme.php src/wp-includes/theme.php
    index 3f5b5e7..1ddf221 100644
    function switch_theme( $stylesheet ) { 
    762762        global $wp_theme_directories, $wp_customize, $sidebars_widgets;
    763763
    764764        $_sidebars_widgets = null;
    765         if ( 'wp_ajax_customize_save' === current_action() ) {
     765        if ( did_action( 'customize_save_before_switch_theme' ) ) {
    766766                $_sidebars_widgets = $wp_customize->post_value( $wp_customize->get_setting( 'old_sidebars_widgets_data' ) );
    767767        } elseif ( is_array( $sidebars_widgets ) ) {
    768768                $_sidebars_widgets = $sidebars_widgets;
    function switch_theme( $stylesheet ) { 
    807807                 * we need to to remove the theme mods to avoid overwriting changes made via
    808808                 * the Customizer when accessing wp-admin/widgets.php.
    809809                 */
    810                 if ( 'wp_ajax_customize_save' === current_action() ) {
     810                if ( did_action( 'customize_save_before_switch_theme' ) ) {
    811811                        remove_theme_mod( 'sidebars_widgets' );
    812812                }
    813813        }
  • tests/phpunit/includes/testcase.php

    diff --git tests/phpunit/includes/testcase.php tests/phpunit/includes/testcase.php
    index 81f9686..a54b5e6 100644
    class WP_UnitTestCase extends PHPUnit_Framework_TestCase { 
    8787        function clean_up_global_scope() {
    8888                $_GET = array();
    8989                $_POST = array();
     90                $_REQUEST = array();
    9091                $this->flush_cache();
    9192        }
    9293
  • tests/phpunit/tests/customize/setting.php

    diff --git tests/phpunit/tests/customize/setting.php tests/phpunit/tests/customize/setting.php
    index a783287..bf91a7d 100644
    class Tests_WP_Customize_Setting extends WP_UnitTestCase { 
    4444                $this->assertEquals( '', $setting->sanitize_js_callback );
    4545                $this->assertFalse( has_filter( "customize_sanitize_{$setting->id}" ) );
    4646                $this->assertFalse( has_filter( "customize_sanitize_js_{$setting->id}" ) );
     47                $this->assertEquals( false, $setting->dirty );
    4748        }
    4849
    4950        function test_constructor_with_args() {
  • tests/phpunit/tests/customize/widgets.php

    diff --git tests/phpunit/tests/customize/widgets.php tests/phpunit/tests/customize/widgets.php
    index 8decbef..a7c9e40 100644
    class Tests_WP_Customize_Widgets extends WP_UnitTestCase { 
    1212         */
    1313        protected $manager;
    1414
     15        protected $twentyfifteen_sidebars_widgets;
     16        protected $twentythirteen_sidebars_widgets;
     17
    1518        function setUp() {
    1619                parent::setUp();
    1720                require_once( ABSPATH . WPINC . '/class-wp-customize-manager.php' );
    class Tests_WP_Customize_Widgets extends WP_UnitTestCase { 
    2124                unset( $GLOBALS['_wp_sidebars_widgets'] ); // clear out cache set by wp_get_sidebars_widgets()
    2225                $sidebars_widgets = wp_get_sidebars_widgets();
    2326                $this->assertEqualSets( array( 'wp_inactive_widgets', 'sidebar-1' ), array_keys( wp_get_sidebars_widgets() ) );
    24                 $this->assertContains( 'search-2', $sidebars_widgets['sidebar-1'] );
    25                 $this->assertContains( 'categories-2', $sidebars_widgets['sidebar-1'] );
     27                $initial_sidebar_1 = array(
     28                        'search-2',
     29                        'recent-posts-2',
     30                        'recent-comments-2',
     31                        'archives-2',
     32                        'categories-2',
     33                        'meta-2',
     34                );
     35                $this->assertEquals( $initial_sidebar_1, $sidebars_widgets['sidebar-1'] );
    2636                $this->assertArrayHasKey( 2, get_option( 'widget_search' ) );
    2737                $widget_categories = get_option( 'widget_categories' );
    2838                $this->assertArrayHasKey( 2, $widget_categories );
    class Tests_WP_Customize_Widgets extends WP_UnitTestCase { 
    99109        }
    100110
    101111        /**
     112         * @param string $new_theme Stylesheet
     113         *
     114         * @throws Exception
     115         */
     116        function prepare_theme_switch_state( $new_theme ) {
     117                $old_theme = get_stylesheet();
     118                if ( 'twentyfifteen' !== $old_theme ) {
     119                        throw new Exception( 'Currently expecting initial theme to be twentyfifteen.' );
     120                }
     121                if ( $new_theme === $old_theme ) {
     122                        throw new Exception( 'A different theme must be supplied than the current theme.' );
     123                }
     124
     125                // Make sure the new theme and the old theme are both among allowed themes
     126                update_site_option( 'allowedthemes', array_fill_keys( array( $new_theme, $old_theme ), true ) );
     127                $this->assertTrue( wp_get_theme( $old_theme )->is_allowed(), "Expected old theme $old_theme to be allowed." );
     128                $this->assertTrue( wp_get_theme( $new_theme )->is_allowed(), "Expected new theme $new_theme to be allowed" );
     129
     130                // Set the sidebars_widgets theme mods for both the old theme and the new theme
     131                $this->twentyfifteen_sidebars_widgets = wp_get_sidebars_widgets();
     132                $this->twentythirteen_sidebars_widgets = $this->twentyfifteen_sidebars_widgets;
     133                $this->twentythirteen_sidebars_widgets['sidebar-2'] = array();
     134                for ( $i = 0; $i < 3; $i += 1 ) {
     135                        $this->twentythirteen_sidebars_widgets['sidebar-2'][] = array_pop( $this->twentythirteen_sidebars_widgets['sidebar-1'] );
     136                }
     137                $this->twentythirteen_sidebars_widgets['sidebar-1'] = array_reverse( $this->twentythirteen_sidebars_widgets['sidebar-1'] );
     138                update_option( 'theme_mods_twentythirteen', array(
     139                        'sidebars_widgets' => array(
     140                                'time' => time() - 3600,
     141                                'data' => $this->twentythirteen_sidebars_widgets,
     142                        ),
     143                ) );
     144
     145                $this->switch_theme_and_check_switched( $new_theme );
     146                $sidebars_widgets = get_option( 'sidebars_widgets' );
     147                $this->assertEquals( $this->twentythirteen_sidebars_widgets['sidebar-1'], $sidebars_widgets['sidebar-1'] );
     148                $this->assertEquals( $this->twentythirteen_sidebars_widgets['sidebar-2'], $sidebars_widgets['sidebar-2'] );
     149
     150                $this->switch_theme_and_check_switched( $old_theme );
     151                $sidebars_widgets = get_option( 'sidebars_widgets' );
     152                $this->assertEquals( $this->twentyfifteen_sidebars_widgets['sidebar-1'], $sidebars_widgets['sidebar-1'] );
     153        }
     154
     155        /**
     156         * @param string $new_theme Stylesheet
     157         *
     158         * @throws Exception
     159         */
     160        function switch_theme_and_check_switched( $new_theme ) {
     161                switch_theme( $new_theme );
     162                $this->setup_sidebars_for_theme_switch( $new_theme );
     163                check_theme_switched();
     164        }
     165
     166        /**
     167         * Emulate loading the theme's functions.php
     168         *
     169         * @param string $new_theme stylesheet
     170         *
     171         * @throws Exception
     172         */
     173        function setup_sidebars_for_theme_switch( $new_theme ) {
     174                if ( 'twentythirteen' === $new_theme ) {
     175                        register_sidebar( array(
     176                                'name'          => __( 'Secondary Widget Area', 'twentythirteen' ),
     177                                'id'            => 'sidebar-2',
     178                                'description'   => __( 'Appears on posts and pages in the sidebar.', 'twentythirteen' ),
     179                                'before_widget' => '<aside id="%1$s" class="widget %2$s">',
     180                                'after_widget'  => '</aside>',
     181                                'before_title'  => '<h3 class="widget-title">',
     182                                'after_title'   => '</h3>',
     183                        ) );
     184                } else if ( 'twentyfifteen' === $new_theme ) {
     185                        unregister_sidebar( 'sidebar-2' );
     186                } else {
     187                        throw new Exception( 'Only twentyfifteen and twentythirteen are supported.' );
     188                }
     189        }
     190
     191        function test_override_sidebars_widgets_for_non_theme_switch() {
     192                if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
     193                        $this->markTestSkipped( 'The WP_Customize_Widgets::override_sidebars_widgets_for_theme_switch() method short-circuits if DOING_AJAX.' );
     194                }
     195                $this->do_customize_boot_actions();
     196                $this->assertEmpty( $this->manager->get_setting( 'old_sidebars_widgets_data' ) );
     197        }
     198
     199        /**
     200         * Test WP_Customize_Widgets::override_sidebars_widgets_for_theme_switch()
     201         *
     202         * @todo A lot of this should be in a test for WP_Customize_Manager::setup_theme()
     203         */
     204        function test_override_sidebars_widgets_for_theme_switch() {
     205                global $wpdb;
     206
     207                if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
     208                        $this->markTestSkipped( 'The WP_Customize_Widgets::override_sidebars_widgets_for_theme_switch() method short-circuits if DOING_AJAX.' );
     209                }
     210                $start_time = time();
     211                $old_theme = get_stylesheet();
     212                $new_theme = 'twentythirteen';
     213                $this->assertNotEquals( $new_theme, $old_theme );
     214
     215                $initial_sidebars_widgets = get_option( 'sidebars_widgets' );
     216                $this->prepare_theme_switch_state( $new_theme );
     217                $checked_sidebars_widgets = get_option( 'sidebars_widgets' );
     218                $this->assertEquals( $initial_sidebars_widgets['sidebar-1'], $checked_sidebars_widgets['sidebar-1'], 'Expected sidebar-1 to be back in initial state after round-trip theme switch.' );
     219                $this->assertArrayNotHasKey( 'orphaned_widgets_1', $checked_sidebars_widgets );
     220                $this->assertArrayNotHasKey( 'sidebar-2', $checked_sidebars_widgets );
     221
     222                // Initialize the Customizer with a preview for the new theme
     223                $_REQUEST['theme'] = $new_theme;
     224                add_action( 'start_previewing_theme', array( $this, 'set_up_sidebars_for_theme_preview' ) );
     225                $this->do_customize_boot_actions();
     226                $this->assertEquals( $new_theme, $this->manager->get_stylesheet() );
     227
     228                $sidebars_widgets = get_option( 'sidebars_widgets' );
     229                $this->assertArrayNotHasKey( 'orphaned_widgets_1', $sidebars_widgets );
     230                $this->assertEquals( $this->twentythirteen_sidebars_widgets['sidebar-1'], $sidebars_widgets['sidebar-1'] );
     231                $this->assertEquals( $this->twentythirteen_sidebars_widgets['sidebar-2'], $sidebars_widgets['sidebar-2'] );
     232                unset( $sidebars_widgets['array_version'] );
     233                $this->assertEquals( $sidebars_widgets, wp_get_sidebars_widgets() );
     234
     235                $db_sidebars_widgets = maybe_unserialize( $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'sidebars_widgets'" ) );
     236                $this->assertEquals( $db_sidebars_widgets['sidebar-1'], $initial_sidebars_widgets['sidebar-1'] );
     237                $this->assertArrayNotHasKey( 'sidebar-2', $db_sidebars_widgets );
     238
     239                $old_sidebars_widgets_setting = $this->manager->get_setting( 'old_sidebars_widgets_data' );
     240                $this->assertNotEmpty( $old_sidebars_widgets_setting );
     241                $old_sidebars_widgets_value = $old_sidebars_widgets_setting->value();
     242                $this->assertNotEmpty( $old_sidebars_widgets_value );
     243                $this->assertEquals( $this->twentyfifteen_sidebars_widgets['sidebar-1'], $old_sidebars_widgets_value['sidebar-1'] );
     244                $this->assertArrayNotHasKey( 'sidebar-2', $old_sidebars_widgets_value['sidebar-1'] );
     245
     246                $expected_dirty_settings = array( 'sidebars_widgets[sidebar-1]', 'sidebars_widgets[sidebar-2]', 'old_sidebars_widgets_data' );
     247                foreach ( $expected_dirty_settings as $dirty_setting_id ) {
     248                        $this->assertTrue( $this->manager->get_setting( $dirty_setting_id )->dirty, "Expected setting $dirty_setting_id to be dirty." );
     249                }
     250
     251                // Now save the customizer, and remove preview filters which interfere with saving
     252                foreach ( $this->manager->settings() as $setting ) {
     253                        if ( $setting->dirty ) {
     254                                $this->manager->set_post_value( $setting->id, $setting->value() );
     255                                $id_base = preg_replace( '/\[.*/', '', $setting->id );
     256                                if ( 'theme_mod' === $setting->type ) {
     257                                        remove_filter( "theme_mod_{$id_base}", array( $setting, '_preview_filter' ) );
     258                                } else if ( 'option' === $setting->type ) {
     259                                        remove_filter( "pre_option_{$id_base}", array( $setting, '_preview_filter' ) );
     260                                        remove_filter( "option_{$id_base}", array( $setting, '_preview_filter' ) );
     261                                        remove_filter( "default_option_{$id_base}", array( $setting, '_preview_filter' ) );
     262                                }
     263                        }
     264                }
     265                remove_filter( 'option_sidebars_widgets', array( $this->manager->widgets, 'filter_option_sidebars_widgets_for_theme_switch' ), 1 );
     266                $response = $this->manager->save( array( 'check_ajax_referer' => false, 'send_json' => false ) );
     267                $this->assertInternalType( 'array', $response ); // and not a WP_Error
     268
     269                // Ensure that the new theme's sidebars have been saved as expected
     270                $db_sidebars_widgets = maybe_unserialize( $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'sidebars_widgets'" ) );
     271                $this->assertEquals( $this->twentythirteen_sidebars_widgets['sidebar-1'], $db_sidebars_widgets['sidebar-1'] );
     272                $this->assertEquals( $this->twentythirteen_sidebars_widgets['sidebar-2'], $db_sidebars_widgets['sidebar-2'] );
     273
     274                // Ensure that the old theme's sidebars have been placed in that theme's widgets_sidebars theme mod
     275                $old_theme_sidebars_widgets_theme_mod = get_option( "theme_mods_{$old_theme}" );
     276                $this->assertEquals( $old_sidebars_widgets_value, $old_theme_sidebars_widgets_theme_mod['sidebars_widgets']['data'] );
     277                $this->assertGreaterThanOrEqual( $old_theme_sidebars_widgets_theme_mod['sidebars_widgets']['time'], $start_time );
     278                $new_theme_mods = get_option( "theme_mods_{$new_theme}" );
     279                $this->assertEmpty( $new_theme_mods['sidebars_widgets'], "Expected new theme's sidebars_widgets theme mod to be gone." );
     280        }
     281
     282        /**
     283         * @param WP_Customize_Manager $wp_customize
     284         */
     285        function set_up_sidebars_for_theme_preview( $wp_customize ) {
     286                $this->setup_sidebars_for_theme_switch( $wp_customize->get_stylesheet() );
     287        }
     288
     289        /**
    102290         * Test WP_Customize_Widgets::get_setting_args()
    103291         */
    104292        function test_get_setting_args() {