Make WordPress Core

Changeset 55161


Ignore:
Timestamp:
01/30/2023 10:25:53 AM (15 months ago)
Author:
swissspidy
Message:

I18N: Introduce switch_to_user_locale().

This new function makes it easier to switch to a specific user’s locale by reducing duplicate code and storing the user’s ID as additional context for plugins to consume. Existing usage of switch_to_locale() in core has been replaced with switch_to_user_locale() where appropriate.

Also, this change ensures WP_Locale_Switcher properly filters determine_locale so that anyyone using the determine_locale() function will get the correct locale information when switching is in effect.

Props costdev.
Fixes #57123.
See #26511.

Location:
trunk
Files:
13 edited

Legend:

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

    r54169 r55161  
    14581458    update_option( 'adminhash', $new_admin_email );
    14591459
    1460     $switched_locale = switch_to_locale( get_user_locale() );
     1460    $switched_locale = switch_to_user_locale( get_current_user_id() );
    14611461
    14621462    /* translators: Do not translate USERNAME, ADMIN_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */
  • trunk/src/wp-admin/includes/privacy-tools.php

    r54891 r55161  
    596596    // Localize message content for user; fallback to site default for visitors.
    597597    if ( ! empty( $request->user_id ) ) {
    598         $locale = get_user_locale( $request->user_id );
     598        $switched_locale = switch_to_user_locale( $request->user_id );
    599599    } else {
    600         $locale = get_locale();
    601     }
    602 
    603     $switched_locale = switch_to_locale( $locale );
     600        $switched_locale = switch_to_locale( get_locale() );
     601    }
    604602
    605603    /** This filter is documented in wp-includes/functions.php */
  • trunk/src/wp-admin/user-new.php

    r55145 r55161  
    111111            do_action( 'invite_user', $user_id, $role, $newuser_key );
    112112
    113             $switched_locale = switch_to_locale( get_user_locale( $user_details ) );
     113            $switched_locale = switch_to_user_locale( $user_id );
    114114
    115115            if ( '' !== get_option( 'blogname' ) ) {
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r54935 r55161  
    21352135        }
    21362136
    2137         $switched_locale = switch_to_locale( get_user_locale() );
     2137        $switched_locale = switch_to_user_locale( get_current_user_id() );
    21382138        $l10n            = array(
    21392139            'shiftClickToEdit'  => __( 'Shift-click to edit this element.' ),
  • trunk/src/wp-includes/class-wp-customize-widgets.php

    r54133 r55161  
    12651265        global $wp_registered_sidebars, $wp_registered_widgets;
    12661266
    1267         $switched_locale = switch_to_locale( get_user_locale() );
     1267        $switched_locale = switch_to_user_locale( get_current_user_id() );
    12681268
    12691269        $l10n = array(
  • trunk/src/wp-includes/class-wp-locale-switcher.php

    r55010 r55161  
    1616class WP_Locale_Switcher {
    1717    /**
    18      * Locale stack.
    19      *
    20      * @since 4.7.0
    21      * @var string[]
    22      */
    23     private $locales = array();
     18     * Locale switching stack.
     19     *
     20     * @since 4.7.0
     21     * @var array
     22     */
     23    private $stack = array();
    2424
    2525    /**
     
    5454     * Initializes the locale switcher.
    5555     *
    56      * Hooks into the {@see 'locale'} filter to change the locale on the fly.
     56     * Hooks into the {@see 'locale'} and {@see 'determine_locale'} filters
     57     * to change the locale on the fly.
    5758     *
    5859     * @since 4.7.0
     
    6061    public function init() {
    6162        add_filter( 'locale', array( $this, 'filter_locale' ) );
     63        add_filter( 'determine_locale', array( $this, 'filter_locale' ) );
    6264    }
    6365
     
    6769     * @since 4.7.0
    6870     *
    69      * @param string $locale The locale to switch to.
     71     * @param string    $locale  The locale to switch to.
     72     * @param int|false $user_id Optional. User ID as context. Default false.
    7073     * @return bool True on success, false on failure.
    7174     */
    72     public function switch_to_locale( $locale ) {
     75    public function switch_to_locale( $locale, $user_id = false ) {
    7376        $current_locale = determine_locale();
    7477        if ( $current_locale === $locale ) {
     
    8083        }
    8184
    82         $this->locales[] = $locale;
     85        $this->stack[] = array( $locale, $user_id );
    8386
    8487        $this->change_locale( $locale );
     
    8891         *
    8992         * @since 4.7.0
    90          *
    91          * @param string $locale The new locale.
     93         * @since 6.2.0 The `$user_id` parameter was added.
     94         *
     95         * @param string   $locale  The new locale.
     96         * @param null|int $user_id User ID for context if available.
    9297         */
    93         do_action( 'switch_locale', $locale );
     98        do_action( 'switch_locale', $locale, $user_id );
    9499
    95100        return true;
     
    97102
    98103    /**
     104     * Switches the translations according to the given user's locale.
     105     *
     106     * @since 6.2.0
     107     *
     108     * @param int $user_id User ID.
     109     * @return bool True on success, false on failure.
     110     */
     111    public function switch_to_user_locale( $user_id ) {
     112        $locale = get_user_locale( $user_id );
     113        return $this->switch_to_locale( $locale, $user_id );
     114    }
     115
     116    /**
    99117     * Restores the translations according to the previous locale.
    100118     *
     
    104122     */
    105123    public function restore_previous_locale() {
    106         $previous_locale = array_pop( $this->locales );
     124        $previous_locale = array_pop( $this->stack );
    107125
    108126        if ( null === $previous_locale ) {
     
    111129        }
    112130
    113         $locale = end( $this->locales );
     131        $entry  = end( $this->stack );
     132        $locale = is_array( $entry ) ? $entry[0] : false;
    114133
    115134        if ( ! $locale ) {
     
    128147         * @param string $previous_locale The previous locale.
    129148         */
    130         do_action( 'restore_previous_locale', $locale, $previous_locale );
     149        do_action( 'restore_previous_locale', $locale, $previous_locale[0] );
    131150
    132151        return $locale;
     
    141160     */
    142161    public function restore_current_locale() {
    143         if ( empty( $this->locales ) ) {
    144             return false;
    145         }
    146 
    147         $this->locales = array( $this->original_locale );
     162        if ( empty( $this->stack ) ) {
     163            return false;
     164        }
     165
     166        $this->stack = array( array( $this->original_locale, false ) );
    148167
    149168        return $this->restore_previous_locale();
     
    158177     */
    159178    public function is_switched() {
    160         return ! empty( $this->locales );
     179        return ! empty( $this->stack );
     180    }
     181
     182    /**
     183     * Returns the locale currently switched to.
     184     *
     185     * @since 6.2.0
     186     *
     187     * @return string|false Locale if the locale has been switched, false otherwise.
     188     */
     189    public function get_current_locale() {
     190        $entry = end( $this->stack );
     191
     192        if ( $entry ) {
     193            return $entry[0];
     194        }
     195
     196        return false;
     197    }
     198
     199    /**
     200     * Returns the user ID related to the currently switched locale.
     201     *
     202     * @since 6.2.0
     203     *
     204     * @return int|false User ID if set and if the locale has been switched, false otherwise.
     205     */
     206    public function get_current_user_id() {
     207        $entry = end( $this->stack );
     208
     209        if ( $entry ) {
     210            return $entry[1];
     211        }
     212
     213        return false;
    161214    }
    162215
     
    170223     */
    171224    public function filter_locale( $locale ) {
    172         $switched_locale = end( $this->locales );
     225        $switched_locale = $this->get_current_locale();
    173226
    174227        if ( $switched_locale ) {
  • trunk/src/wp-includes/class-wp-recovery-mode-email-service.php

    r55001 r55161  
    117117        $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
    118118
    119         $switched_locale = false;
    120 
    121         // The switch_to_locale() function is loaded before it can actually be used.
    122         if ( function_exists( 'switch_to_locale' ) && isset( $GLOBALS['wp_locale_switcher'] ) ) {
    123             $switched_locale = switch_to_locale( get_locale() );
    124         }
     119        $switched_locale = switch_to_locale( get_locale() );
    125120
    126121        if ( $extension ) {
  • trunk/src/wp-includes/customize/class-wp-customize-selective-refresh.php

    r54133 r55161  
    173173        }
    174174
    175         $switched_locale = switch_to_locale( get_user_locale() );
     175        $switched_locale = switch_to_user_locale( get_current_user_id() );
    176176        $l10n            = array(
    177177            'shiftClickToEdit' => __( 'Shift-click to edit this element.' ),
  • trunk/src/wp-includes/l10n.php

    r54938 r55161  
    16661666    global $wp_locale_switcher;
    16671667
     1668    if ( ! $wp_locale_switcher ) {
     1669        return false;
     1670    }
     1671
    16681672    return $wp_locale_switcher->switch_to_locale( $locale );
     1673}
     1674
     1675/**
     1676 * Switches the translations according to the given user's locale.
     1677 *
     1678 * @since 6.2.0
     1679 *
     1680 * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object.
     1681 *
     1682 * @param int $user_id User ID.
     1683 * @return bool True on success, false on failure.
     1684 */
     1685function switch_to_user_locale( $user_id ) {
     1686    /* @var WP_Locale_Switcher $wp_locale_switcher */
     1687    global $wp_locale_switcher;
     1688
     1689    if ( ! $wp_locale_switcher ) {
     1690        return false;
     1691    }
     1692
     1693    return $wp_locale_switcher->switch_to_user_locale( $user_id );
    16691694}
    16701695
     
    16821707    global $wp_locale_switcher;
    16831708
     1709    if ( ! $wp_locale_switcher ) {
     1710        return false;
     1711    }
     1712
    16841713    return $wp_locale_switcher->restore_previous_locale();
    16851714}
     
    16971726    /* @var WP_Locale_Switcher $wp_locale_switcher */
    16981727    global $wp_locale_switcher;
     1728
     1729    if ( ! $wp_locale_switcher ) {
     1730        return false;
     1731    }
    16991732
    17001733    return $wp_locale_switcher->restore_current_locale();
  • trunk/src/wp-includes/ms-functions.php

    r55075 r55161  
    955955
    956956    $user            = get_user_by( 'login', $user_login );
    957     $switched_locale = switch_to_locale( get_user_locale( $user ) );
     957    $switched_locale = $user && switch_to_user_locale( $user->ID );
    958958
    959959    $message = sprintf(
     
    10691069
    10701070    $user            = get_user_by( 'login', $user_login );
    1071     $switched_locale = switch_to_locale( get_user_locale( $user ) );
     1071    $switched_locale = $user && switch_to_user_locale( $user->ID );
    10721072
    10731073    // Send email with activation link.
     
    16111611    $user = get_userdata( $user_id );
    16121612
    1613     $switched_locale = switch_to_locale( get_user_locale( $user ) );
     1613    $switched_locale = switch_to_user_locale( $user_id );
    16141614
    16151615    $welcome_email = get_site_option( 'welcome_email' );
     
    17351735    if ( $network_admin ) {
    17361736        // If the network admin email address corresponds to a user, switch to their locale.
    1737         $switched_locale = switch_to_locale( get_user_locale( $network_admin ) );
     1737        $switched_locale = switch_to_user_locale( $network_admin->ID );
    17381738    } else {
    17391739        // Otherwise switch to the locale of the current site.
     
    18441844    $user = get_userdata( $user_id );
    18451845
    1846     $switched_locale = switch_to_locale( get_user_locale( $user ) );
     1846    $switched_locale = switch_to_user_locale( $user_id );
    18471847
    18481848    /**
     
    27272727    update_site_option( 'network_admin_hash', $new_admin_email );
    27282728
    2729     $switched_locale = switch_to_locale( get_user_locale() );
     2729    $switched_locale = switch_to_user_locale( get_current_user_id() );
    27302730
    27312731    /* translators: Do not translate USERNAME, ADMIN_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */
  • trunk/src/wp-includes/pluggable.php

    r55069 r55161  
    21892189        }
    21902190
    2191         $switched_locale = switch_to_locale( get_user_locale( $user ) );
     2191        $switched_locale = switch_to_user_locale( $user_id );
    21922192
    21932193        /* translators: %s: User login. */
  • trunk/src/wp-includes/user.php

    r55015 r55161  
    25792579    $switched_locale = false;
    25802580    if ( ! empty( $send_password_change_email ) || ! empty( $send_email_change_email ) ) {
    2581         $switched_locale = switch_to_locale( get_user_locale( $user_id ) );
     2581        $switched_locale = switch_to_user_locale( $user_id );
    25822582    }
    25832583
     
    31403140    $locale = get_user_locale( $user_data );
    31413141
    3142     $switched_locale = switch_to_locale( $locale );
     3142    $switched_locale = switch_to_user_locale( $user_data->ID );
    31433143
    31443144    if ( is_multisite() ) {
     
    42454245    // Localize message content for user; fallback to site default for visitors.
    42464246    if ( ! empty( $request->user_id ) ) {
    4247         $locale = get_user_locale( $request->user_id );
     4247        $switched_locale = switch_to_user_locale( $request->user_id );
    42484248    } else {
    4249         $locale = get_locale();
    4250     }
    4251 
    4252     $switched_locale = switch_to_locale( $locale );
     4249        $switched_locale = switch_to_locale( get_locale() );
     4250    }
    42534251
    42544252    /**
     
    46564654    // Localize message content for user; fallback to site default for visitors.
    46574655    if ( ! empty( $request->user_id ) ) {
    4658         $locale = get_user_locale( $request->user_id );
     4656        $switched_locale = switch_to_user_locale( $request->user_id );
    46594657    } else {
    4660         $locale = get_locale();
    4661     }
    4662 
    4663     $switched_locale = switch_to_locale( $locale );
     4658        $switched_locale = switch_to_locale( get_locale() );
     4659    }
    46644660
    46654661    $email_data = array(
  • trunk/tests/phpunit/tests/l10n/wpLocaleSwitcher.php

    r55010 r55161  
    1717    protected $previous_locale = '';
    1818
    19     public function set_up() {
    20         parent::set_up();
    21 
    22         $this->locale          = '';
    23         $this->previous_locale = '';
    24 
    25         unset( $GLOBALS['l10n'], $GLOBALS['l10n_unloaded'] );
    26 
    27         global $wp_textdomain_registry, $wp_locale_switcher;
    28 
    29         $wp_textdomain_registry = new WP_Textdomain_Registry();
    30 
    31         remove_filter( 'locale', array( $wp_locale_switcher, 'filter_locale' ) );
    32         $wp_locale_switcher = new WP_Locale_Switcher();
    33         $wp_locale_switcher->init();
    34     }
    35 
    36     public function tear_down() {
    37         unset( $GLOBALS['l10n'], $GLOBALS['l10n_unloaded'] );
    38 
    39         global $wp_textdomain_registry, $wp_locale_switcher;
    40 
    41         $wp_textdomain_registry = new WP_Textdomain_Registry();
    42 
    43         remove_filter( 'locale', array( $wp_locale_switcher, 'filter_locale' ) );
    44         $wp_locale_switcher = new WP_Locale_Switcher();
    45         $wp_locale_switcher->init();
    46 
    47         parent::tear_down();
    48     }
    49 
    50     /**
    51      * @covers ::switch_to_locale
    52      */
    53     public function test_switch_to_non_existent_locale_returns_false() {
    54         $this->assertFalse( switch_to_locale( 'foo_BAR' ) );
    55     }
    56 
    57     /**
    58      * @covers ::switch_to_locale
    59      */
    60     public function test_switch_to_non_existent_locale_does_not_change_locale() {
    61         switch_to_locale( 'foo_BAR' );
    62 
    63         $this->assertSame( 'en_US', get_locale() );
    64     }
    65 
    66     /**
    67      * @covers ::switch_to_locale
    68      */
    69     public function test_switch_to_locale_returns_true() {
    70         $expected = switch_to_locale( 'en_GB' );
    71 
    72         // Cleanup.
    73         restore_previous_locale();
    74 
    75         $this->assertTrue( $expected );
    76     }
    77 
    78     /**
    79      * @covers ::switch_to_locale
    80      */
    81     public function test_switch_to_locale_changes_the_locale() {
    82         switch_to_locale( 'en_GB' );
    83 
    84         $locale = get_locale();
    85 
    86         // Cleanup.
    87         restore_previous_locale();
    88 
    89         $this->assertSame( 'en_GB', $locale );
    90     }
    91 
    92     /**
    93      * @covers ::switch_to_locale
    94      * @covers ::translate
    95      * @covers ::__
    96      */
    97     public function test_switch_to_locale_loads_translation() {
    98         switch_to_locale( 'es_ES' );
    99 
    100         $actual = __( 'Invalid parameter.' );
    101 
    102         // Cleanup.
    103         restore_previous_locale();
    104 
    105         $this->assertSame( 'Parámetro no válido. ', $actual );
    106     }
    107 
    108     /**
    109      * @covers ::switch_to_locale
    110      */
    111     public function test_switch_to_locale_changes_wp_locale_global() {
    112         global $wp_locale;
    113 
    114         $expected = array(
    115             'thousands_sep' => '.',
    116             'decimal_point' => ',',
    117         );
    118 
    119         switch_to_locale( 'de_DE' );
    120 
    121         $wp_locale_de_de = clone $wp_locale;
    122 
    123         // Cleanup.
    124         restore_previous_locale();
    125 
    126         $this->assertSameSetsWithIndex( $expected, $wp_locale_de_de->number_format );
    127     }
    128 
    129     /**
    130      * @covers ::switch_to_locale
    131      */
    132     public function test_switch_to_locale_en_US() {
    133         switch_to_locale( 'en_GB' );
    134         $locale_en_gb = get_locale();
    135         switch_to_locale( 'en_US' );
    136         $locale_en_us = get_locale();
    137 
    138         // Cleanup.
    139         restore_current_locale();
    140 
    141         $this->assertSame( 'en_GB', $locale_en_gb );
    142         $this->assertSame( 'en_US', $locale_en_us );
    143     }
    144 
    145     /**
    146      * @covers ::switch_to_locale
    147      */
    148     public function test_switch_to_locale_multiple_times() {
    149         switch_to_locale( 'en_GB' );
    150         switch_to_locale( 'es_ES' );
    151         $locale = get_locale();
    152 
    153         // Cleanup.
    154         restore_previous_locale();
    155         restore_previous_locale();
    156 
    157         $this->assertSame( 'es_ES', $locale );
    158     }
    159 
    160     /**
    161      * @covers ::switch_to_locale
    162      * @covers ::__
    163      * @covers ::translate
    164      */
    165     public function test_switch_to_locale_multiple_times_loads_translation() {
    166         switch_to_locale( 'en_GB' );
    167         switch_to_locale( 'de_DE' );
    168         switch_to_locale( 'es_ES' );
    169 
    170         $actual = __( 'Invalid parameter.' );
    171 
    172         // Cleanup.
    173         restore_previous_locale();
    174         restore_previous_locale();
    175         restore_previous_locale();
    176 
    177         $this->assertSame( 'Parámetro no válido. ', $actual );
    178     }
    179 
    180     /**
    181      * @covers ::restore_previous_locale
    182      */
    183     public function test_restore_previous_locale_without_switching() {
    184         $this->assertFalse( restore_previous_locale() );
    185     }
    186 
    187     /**
    188      * @covers ::restore_previous_locale
    189      */
    190     public function test_restore_previous_locale_changes_the_locale_back() {
    191         switch_to_locale( 'en_GB' );
    192 
    193         // Cleanup.
    194         restore_previous_locale();
    195 
    196         $this->assertSame( 'en_US', get_locale() );
    197     }
    198 
    199     /**
    200      * @covers ::restore_previous_locale
    201      */
    202     public function test_restore_previous_locale_after_switching_multiple_times() {
    203         switch_to_locale( 'en_GB' );
    204         switch_to_locale( 'es_ES' );
    205         restore_previous_locale();
    206 
    207         $locale = get_locale();
    208 
    209         // Cleanup.
    210         restore_previous_locale();
    211 
    212         $this->assertSame( 'en_GB', $locale );
    213     }
    214 
    215     /**
    216      * @covers ::restore_previous_locale
    217      * @covers ::__
    218      * @covers ::translate
    219      */
    220     public function test_restore_previous_locale_restores_translation() {
    221         switch_to_locale( 'es_ES' );
    222         restore_previous_locale();
    223 
    224         $actual = __( 'Invalid parameter.' );
    225 
    226         $this->assertSame( 'Invalid parameter.', $actual );
    227     }
    228 
    229     /**
    230      * @covers ::restore_previous_locale
    231      */
    232     public function test_restore_previous_locale_action_passes_previous_locale() {
    233         switch_to_locale( 'en_GB' );
    234         switch_to_locale( 'es_ES' );
    235 
    236         add_action( 'restore_previous_locale', array( $this, 'store_locale' ), 10, 2 );
    237 
    238         restore_previous_locale();
    239 
    240         $previous_locale = $this->previous_locale;
    241 
    242         // Cleanup.
    243         restore_previous_locale();
    244 
    245         $this->assertSame( 'es_ES', $previous_locale );
    246     }
    247 
    248     /**
    249      * @covers ::restore_previous_locale
    250      */
    251     public function test_restore_previous_locale_restores_wp_locale_global() {
    252         global $wp_locale;
    253 
    254         $expected = array(
    255             'thousands_sep' => ',',
    256             'decimal_point' => '.',
    257         );
    258 
    259         switch_to_locale( 'de_DE' );
    260         restore_previous_locale();
    261 
    262         $this->assertSameSetsWithIndex( $expected, $wp_locale->number_format );
    263     }
    264 
    265     /**
    266      * @covers ::restore_current_locale
    267      */
    268     public function test_restore_current_locale_without_switching() {
    269         $this->assertFalse( restore_current_locale() );
    270     }
    271 
    272     /**
    273      * @covers ::restore_previous_locale
    274      */
    275     public function test_restore_current_locale_after_switching_multiple_times() {
    276         switch_to_locale( 'en_GB' );
    277         switch_to_locale( 'nl_NL' );
    278         switch_to_locale( 'es_ES' );
    279 
    280         restore_current_locale();
    281 
    282         $this->assertSame( 'en_US', get_locale() );
    283     }
    284 
    285     public function store_locale( $locale, $previous_locale ) {
    286         $this->locale          = $locale;
    287         $this->previous_locale = $previous_locale;
    288     }
    289 
    290     /**
    291      * @covers ::is_locale_switched
    292      */
    293     public function test_is_locale_switched_if_not_switched() {
    294         $this->assertFalse( is_locale_switched() );
    295     }
    296 
    297     /**
    298      * @covers ::is_locale_switched
    299      */
    300     public function test_is_locale_switched_original_locale() {
    301         $original_locale = get_locale();
    302 
    303         switch_to_locale( 'en_GB' );
    304         switch_to_locale( $original_locale );
    305 
    306         $is_locale_switched = is_locale_switched();
    307 
    308         restore_current_locale();
    309 
    310         $this->assertTrue( $is_locale_switched );
    311     }
    312 
    313     /**
    314      * @covers ::is_locale_switched
    315      */
    316     public function test_is_locale_switched() {
    317         switch_to_locale( 'en_GB' );
    318         switch_to_locale( 'nl_NL' );
    319 
    320         $is_locale_switched = is_locale_switched();
    321 
    322         restore_current_locale();
    323 
    324         $this->assertTrue( $is_locale_switched );
    325     }
    326 
    327     /**
    328      * @covers ::switch_to_locale
    329      */
    330     public function test_switch_to_site_locale_if_user_locale_is_set() {
    331         global $l10n, $wp_locale_switcher;
    332 
    333         $site_locale = get_locale();
    334 
    335         $user_id = self::factory()->user->create(
     19    /**
     20     * @var int
     21     */
     22    protected static $user_id;
     23
     24    public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
     25        self::$user_id = $factory->user->create(
    33626            array(
    33727                'role'   => 'administrator',
     
    33929            )
    34030        );
    341 
    342         wp_set_current_user( $user_id );
     31    }
     32
     33    public function set_up() {
     34        parent::set_up();
     35
     36        $this->locale          = '';
     37        $this->previous_locale = '';
     38
     39        unset( $GLOBALS['l10n'], $GLOBALS['l10n_unloaded'] );
     40
     41        global $wp_textdomain_registry, $wp_locale_switcher;
     42
     43        $wp_textdomain_registry = new WP_Textdomain_Registry();
     44
     45        remove_filter( 'locale', array( $wp_locale_switcher, 'filter_locale' ) );
     46        $wp_locale_switcher = new WP_Locale_Switcher();
     47        $wp_locale_switcher->init();
     48    }
     49
     50    public function tear_down() {
     51        unset( $GLOBALS['l10n'], $GLOBALS['l10n_unloaded'] );
     52
     53        global $wp_textdomain_registry, $wp_locale_switcher;
     54
     55        $wp_textdomain_registry = new WP_Textdomain_Registry();
     56
     57        remove_filter( 'locale', array( $wp_locale_switcher, 'filter_locale' ) );
     58        $wp_locale_switcher = new WP_Locale_Switcher();
     59        $wp_locale_switcher->init();
     60
     61        parent::tear_down();
     62    }
     63
     64    /**
     65     * @covers ::switch_to_locale
     66     */
     67    public function test_switch_to_non_existent_locale_returns_false() {
     68        $this->assertFalse( switch_to_locale( 'foo_BAR' ) );
     69    }
     70
     71    /**
     72     * @covers ::switch_to_locale
     73     */
     74    public function test_switch_to_non_existent_locale_does_not_change_locale() {
     75        switch_to_locale( 'foo_BAR' );
     76
     77        $this->assertSame( 'en_US', get_locale() );
     78    }
     79
     80    /**
     81     * @covers ::switch_to_locale
     82     */
     83    public function test_switch_to_locale_returns_true() {
     84        $expected = switch_to_locale( 'en_GB' );
     85
     86        // Cleanup.
     87        restore_previous_locale();
     88
     89        $this->assertTrue( $expected );
     90    }
     91
     92    /**
     93     * @covers ::switch_to_locale
     94     */
     95    public function test_switch_to_locale_changes_the_locale() {
     96        switch_to_locale( 'en_GB' );
     97
     98        $locale = get_locale();
     99
     100        // Cleanup.
     101        restore_previous_locale();
     102
     103        $this->assertSame( 'en_GB', $locale );
     104    }
     105
     106    /**
     107     * @ticket 57123
     108     *
     109     * @covers ::switch_to_locale
     110     */
     111    public function test_switch_to_locale_changes_determined_locale() {
     112        switch_to_locale( 'en_GB' );
     113
     114        $locale = determine_locale();
     115
     116        // Cleanup.
     117        restore_previous_locale();
     118
     119        $this->assertSame( 'en_GB', $locale );
     120    }
     121
     122    /**
     123     * @covers ::switch_to_locale
     124     * @covers ::translate
     125     * @covers ::__
     126     */
     127    public function test_switch_to_locale_loads_translation() {
     128        switch_to_locale( 'es_ES' );
     129
     130        $actual = __( 'Invalid parameter.' );
     131
     132        // Cleanup.
     133        restore_previous_locale();
     134
     135        $this->assertSame( 'Parámetro no válido. ', $actual );
     136    }
     137
     138    /**
     139     * @covers ::switch_to_locale
     140     */
     141    public function test_switch_to_locale_changes_wp_locale_global() {
     142        global $wp_locale;
     143
     144        $expected = array(
     145            'thousands_sep' => '.',
     146            'decimal_point' => ',',
     147        );
     148
     149        switch_to_locale( 'de_DE' );
     150
     151        $wp_locale_de_de = clone $wp_locale;
     152
     153        // Cleanup.
     154        restore_previous_locale();
     155
     156        $this->assertSameSetsWithIndex( $expected, $wp_locale_de_de->number_format );
     157    }
     158
     159    /**
     160     * @covers ::switch_to_locale
     161     */
     162    public function test_switch_to_locale_en_US() {
     163        switch_to_locale( 'en_GB' );
     164        $locale_en_gb = get_locale();
     165        switch_to_locale( 'en_US' );
     166        $locale_en_us = get_locale();
     167
     168        // Cleanup.
     169        restore_current_locale();
     170
     171        $this->assertSame( 'en_GB', $locale_en_gb );
     172        $this->assertSame( 'en_US', $locale_en_us );
     173    }
     174
     175    /**
     176     * @covers ::switch_to_locale
     177     */
     178    public function test_switch_to_locale_multiple_times() {
     179        switch_to_locale( 'en_GB' );
     180        switch_to_locale( 'es_ES' );
     181        $locale = get_locale();
     182
     183        // Cleanup.
     184        restore_previous_locale();
     185        restore_previous_locale();
     186
     187        $this->assertSame( 'es_ES', $locale );
     188    }
     189
     190    /**
     191     * @covers ::switch_to_locale
     192     * @covers ::__
     193     * @covers ::translate
     194     */
     195    public function test_switch_to_locale_multiple_times_loads_translation() {
     196        switch_to_locale( 'en_GB' );
     197        switch_to_locale( 'de_DE' );
     198        switch_to_locale( 'es_ES' );
     199
     200        $actual = __( 'Invalid parameter.' );
     201
     202        // Cleanup.
     203        restore_previous_locale();
     204        restore_previous_locale();
     205        restore_previous_locale();
     206
     207        $this->assertSame( 'Parámetro no válido. ', $actual );
     208    }
     209
     210    /**
     211     * @covers ::restore_previous_locale
     212     */
     213    public function test_restore_previous_locale_without_switching() {
     214        $this->assertFalse( restore_previous_locale() );
     215    }
     216
     217    /**
     218     * @covers ::restore_previous_locale
     219     */
     220    public function test_restore_previous_locale_changes_the_locale_back() {
     221        switch_to_locale( 'en_GB' );
     222
     223        // Cleanup.
     224        restore_previous_locale();
     225
     226        $this->assertSame( 'en_US', get_locale() );
     227    }
     228
     229    /**
     230     * @covers ::restore_previous_locale
     231     */
     232    public function test_restore_previous_locale_after_switching_multiple_times() {
     233        switch_to_locale( 'en_GB' );
     234        switch_to_locale( 'es_ES' );
     235        restore_previous_locale();
     236
     237        $locale = get_locale();
     238
     239        // Cleanup.
     240        restore_previous_locale();
     241
     242        $this->assertSame( 'en_GB', $locale );
     243    }
     244
     245    /**
     246     * @covers ::restore_previous_locale
     247     * @covers ::__
     248     * @covers ::translate
     249     */
     250    public function test_restore_previous_locale_restores_translation() {
     251        switch_to_locale( 'es_ES' );
     252        restore_previous_locale();
     253
     254        $actual = __( 'Invalid parameter.' );
     255
     256        $this->assertSame( 'Invalid parameter.', $actual );
     257    }
     258
     259    /**
     260     * @covers ::restore_previous_locale
     261     */
     262    public function test_restore_previous_locale_action_passes_previous_locale() {
     263        switch_to_locale( 'en_GB' );
     264        switch_to_locale( 'es_ES' );
     265
     266        add_action( 'restore_previous_locale', array( $this, 'store_locale' ), 10, 2 );
     267
     268        restore_previous_locale();
     269
     270        $previous_locale = $this->previous_locale;
     271
     272        // Cleanup.
     273        restore_previous_locale();
     274
     275        $this->assertSame( 'es_ES', $previous_locale );
     276    }
     277
     278    /**
     279     * @covers ::restore_previous_locale
     280     */
     281    public function test_restore_previous_locale_restores_wp_locale_global() {
     282        global $wp_locale;
     283
     284        $expected = array(
     285            'thousands_sep' => ',',
     286            'decimal_point' => '.',
     287        );
     288
     289        switch_to_locale( 'de_DE' );
     290        restore_previous_locale();
     291
     292        $this->assertSameSetsWithIndex( $expected, $wp_locale->number_format );
     293    }
     294
     295    /**
     296     * @covers ::restore_current_locale
     297     */
     298    public function test_restore_current_locale_without_switching() {
     299        $this->assertFalse( restore_current_locale() );
     300    }
     301
     302    /**
     303     * @covers ::restore_previous_locale
     304     */
     305    public function test_restore_current_locale_after_switching_multiple_times() {
     306        switch_to_locale( 'en_GB' );
     307        switch_to_locale( 'nl_NL' );
     308        switch_to_locale( 'es_ES' );
     309
     310        restore_current_locale();
     311
     312        $this->assertSame( 'en_US', get_locale() );
     313    }
     314
     315    public function store_locale( $locale, $previous_locale ) {
     316        $this->locale          = $locale;
     317        $this->previous_locale = $previous_locale;
     318    }
     319
     320    /**
     321     * @covers ::is_locale_switched
     322     */
     323    public function test_is_locale_switched_if_not_switched() {
     324        $this->assertFalse( is_locale_switched() );
     325    }
     326
     327    /**
     328     * @covers ::is_locale_switched
     329     */
     330    public function test_is_locale_switched_original_locale() {
     331        $original_locale = get_locale();
     332
     333        switch_to_locale( 'en_GB' );
     334        switch_to_locale( $original_locale );
     335
     336        $is_locale_switched = is_locale_switched();
     337
     338        restore_current_locale();
     339
     340        $this->assertTrue( $is_locale_switched );
     341    }
     342
     343    /**
     344     * @covers ::is_locale_switched
     345     */
     346    public function test_is_locale_switched() {
     347        switch_to_locale( 'en_GB' );
     348        switch_to_locale( 'nl_NL' );
     349
     350        $is_locale_switched = is_locale_switched();
     351
     352        restore_current_locale();
     353
     354        $this->assertTrue( $is_locale_switched );
     355    }
     356
     357    /**
     358     * @covers ::switch_to_locale
     359     */
     360    public function test_switch_to_site_locale_if_user_locale_is_set() {
     361        global $l10n, $wp_locale_switcher;
     362
     363        $site_locale = get_locale();
     364
     365        wp_set_current_user( self::$user_id );
    343366        set_current_screen( 'dashboard' );
    344367
     
    383406        $site_locale = get_locale();
    384407
    385         $user_id = self::factory()->user->create(
    386             array(
    387                 'role'   => 'administrator',
    388                 'locale' => 'de_DE',
    389             )
    390         );
    391 
    392         wp_set_current_user( $user_id );
     408        wp_set_current_user( self::$user_id );
    393409        set_current_screen( 'dashboard' );
    394410
     
    431447        $site_locale = get_locale();
    432448
    433         $user_id = self::factory()->user->create(
    434             array(
    435                 'role'   => 'administrator',
    436                 'locale' => 'en_GB',
    437             )
    438         );
    439 
    440         wp_set_current_user( $user_id );
     449        wp_set_current_user( self::$user_id );
     450        update_user_meta( self::$user_id, 'locale', 'en_GB' );
    441451        set_current_screen( 'dashboard' );
    442452
     
    584594    }
    585595
     596    /**
     597     * @ticket 57123
     598     *
     599     * @covers ::switch_to_locale
     600     * @covers ::switch_to_user_locale
     601     * @covers WP_Locale_Switcher::get_current_locale
     602     * @covers WP_Locale_Switcher::get_current_user_id
     603     */
     604    public function test_returns_current_locale_and_user_after_switching() {
     605        global $wp_locale_switcher;
     606
     607        $user_2 = self::factory()->user->create(
     608            array(
     609                'role'   => 'administrator',
     610                'locale' => 'es_ES',
     611            )
     612        );
     613
     614        $locale_1  = $wp_locale_switcher->get_current_locale();
     615        $user_id_1 = $wp_locale_switcher->get_current_user_id();
     616
     617        switch_to_user_locale( self::$user_id );
     618
     619        $locale_2  = $wp_locale_switcher->get_current_locale();
     620        $user_id_2 = $wp_locale_switcher->get_current_user_id();
     621
     622        switch_to_locale( 'en_GB' );
     623
     624        $locale_3  = $wp_locale_switcher->get_current_locale();
     625        $user_id_3 = $wp_locale_switcher->get_current_user_id();
     626
     627        switch_to_user_locale( $user_2 );
     628
     629        $locale_4  = $wp_locale_switcher->get_current_locale();
     630        $user_id_4 = $wp_locale_switcher->get_current_user_id();
     631
     632        restore_current_locale();
     633
     634        $locale_5  = $wp_locale_switcher->get_current_locale();
     635        $user_id_5 = $wp_locale_switcher->get_current_user_id();
     636
     637        $this->assertFalse( $locale_1, 'Locale should be false before switching' );
     638        $this->assertFalse( $user_id_1, 'User ID should be false before switching' );
     639
     640        $this->assertSame( 'de_DE', $locale_2, 'The locale was not changed to de_DE' );
     641        $this->assertSame( self::$user_id, $user_id_2, 'User ID should match the main admin ID' );
     642
     643        $this->assertSame( 'en_GB', $locale_3, 'The locale was not changed to en_GB' );
     644        $this->assertFalse( $user_id_3, 'User ID should be false after normal locale switching' );
     645
     646        $this->assertSame( 'es_ES', $locale_4, 'The locale was not changed to es_ES' );
     647        $this->assertSame( $user_2, $user_id_4, 'User ID should match the second admin ID' );
     648
     649        $this->assertFalse( $locale_5, 'Locale should be false after restoring' );
     650        $this->assertFalse( $user_id_5, 'User ID should be false after restoring' );
     651
     652    }
     653
    586654    public function filter_locale() {
    587655        return 'es_ES';
Note: See TracChangeset for help on using the changeset viewer.