I18N: Refactor determine_locale() for performance and readability.

Refactors the function to avoid unnecessary `get_locale()` calls and slightly improve performance, while keeping it readable.

Adds tests.

Props Cybr, spacedmonkey, swissspidy.
Fixes #58317.

git-svn-id: https://develop.svn.wordpress.org/trunk@55862 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Pascal Birchler 2023-05-26 17:55:40 +00:00
parent 404fd63386
commit 66d85f381e
2 changed files with 276 additions and 20 deletions

View File

@ -132,30 +132,26 @@ function determine_locale() {
*/
$determined_locale = apply_filters( 'pre_determine_locale', null );
if ( ! empty( $determined_locale ) && is_string( $determined_locale ) ) {
if ( $determined_locale && is_string( $determined_locale ) ) {
return $determined_locale;
}
$determined_locale = get_locale();
if ( is_admin() ) {
if (
isset( $GLOBALS['pagenow'] ) && 'wp-login.php' === $GLOBALS['pagenow'] &&
( ! empty( $_GET['wp_lang'] ) || ! empty( $_COOKIE['wp_lang'] ) )
) {
if ( ! empty( $_GET['wp_lang'] ) ) {
$determined_locale = sanitize_locale_name( $_GET['wp_lang'] );
} else {
$determined_locale = sanitize_locale_name( $_COOKIE['wp_lang'] );
}
} else if (
( isset( $_GET['_locale'] ) && 'user' === $_GET['_locale'] && wp_is_json_request() ) ||
is_admin()
) {
$determined_locale = get_user_locale();
}
if ( isset( $_GET['_locale'] ) && 'user' === $_GET['_locale'] && wp_is_json_request() ) {
$determined_locale = get_user_locale();
}
$wp_lang = '';
if ( ! empty( $_GET['wp_lang'] ) ) {
$wp_lang = sanitize_locale_name( wp_unslash( $_GET['wp_lang'] ) );
} elseif ( ! empty( $_COOKIE['wp_lang'] ) ) {
$wp_lang = sanitize_locale_name( wp_unslash( $_COOKIE['wp_lang'] ) );
}
if ( ! empty( $wp_lang ) && ! empty( $GLOBALS['pagenow'] ) && 'wp-login.php' === $GLOBALS['pagenow'] ) {
$determined_locale = $wp_lang;
} else {
$determined_locale = get_locale();
}
/**

View File

@ -0,0 +1,260 @@
<?php
/**
* @group l10n
* @group i18n
*
* @covers ::determine_locale
*/
class Tests_L10n_DetermineLocale extends WP_UnitTestCase {
protected $locale;
protected static $user_id;
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
self::$user_id = $factory->user->create(
array(
'role' => 'administrator',
'locale' => 'userLocale',
)
);
}
public function tear_down() {
unset( $_SERVER['CONTENT_TYPE'], $_GET['_locale'], $_COOKIE['wp_lang'], $GLOBALS['pagenow'] );
parent::tear_down();
}
public function test_short_circuit_empty() {
add_filter( 'pre_determine_locale', '__return_false' );
$this->assertNotFalse( determine_locale() );
}
public function test_short_circuit_no_string() {
add_filter(
'pre_determine_locale',
static function() {
return 1234;
}
);
$this->assertNotFalse( determine_locale() );
}
public function test_short_circuit_string() {
add_filter(
'pre_determine_locale',
static function() {
return 'myNewLocale';
}
);
$this->assertSame( 'myNewLocale', determine_locale() );
}
public function test_defaults_to_site_locale() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
$this->assertSame( get_locale(), determine_locale() );
}
public function test_is_admin_no_user() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
set_current_screen( 'dashboard' );
$this->assertSame( 'siteLocale', determine_locale() );
}
public function test_is_admin_user_locale() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
set_current_screen( 'dashboard' );
wp_set_current_user( self::$user_id );
$this->assertSame( 'userLocale', determine_locale() );
}
public function test_json_request_user_locale() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
wp_set_current_user( self::$user_id );
$_SERVER['CONTENT_TYPE'] = 'application/json';
$_GET['_locale'] = 'user';
$this->assertSame( 'userLocale', determine_locale() );
}
public function test_json_request_user_locale_no_user() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
$_SERVER['CONTENT_TYPE'] = 'application/json';
$_GET['_locale'] = 'user';
$this->assertSame( 'siteLocale', determine_locale() );
}
public function test_json_request_missing_get_param() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
wp_set_current_user( self::$user_id );
$_SERVER['CONTENT_TYPE'] = 'application/json';
$this->assertSame( 'siteLocale', determine_locale() );
}
public function test_json_request_incorrect_get_param() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
wp_set_current_user( self::$user_id );
$_SERVER['CONTENT_TYPE'] = 'application/json';
$_GET['_locale'] = 'foo';
$this->assertSame( 'siteLocale', determine_locale() );
}
public function test_get_param_but_no_json_request() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
wp_set_current_user( self::$user_id );
$_GET['_locale'] = 'user';
$this->assertSame( 'siteLocale', determine_locale() );
}
public function test_wp_login_get_param_not_on_login_page() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
wp_set_current_user( self::$user_id );
$_GET['wp_lang'] = 'de_DE';
$this->assertSame( 'siteLocale', determine_locale() );
}
public function test_wp_login_get_param_on_login_page() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
wp_set_current_user( self::$user_id );
$GLOBALS['pagenow'] = 'wp-login.php';
$_GET['wp_lang'] = 'de_DE';
$this->assertSame( 'de_DE', determine_locale() );
}
public function test_wp_login_get_param_on_login_page_empty_string() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
wp_set_current_user( self::$user_id );
$GLOBALS['pagenow'] = 'wp-login.php';
$_GET['wp_lang'] = '';
$this->assertSame( 'siteLocale', determine_locale() );
}
public function test_wp_login_cookie_not_on_login_page() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
wp_set_current_user( self::$user_id );
$_COOKIE['wp_lang'] = 'de_DE';
$this->assertSame( 'siteLocale', determine_locale() );
}
public function test_wp_login_cookie_on_login_page() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
wp_set_current_user( self::$user_id );
$GLOBALS['pagenow'] = 'wp-login.php';
$_COOKIE['wp_lang'] = 'de_DE';
$this->assertSame( 'de_DE', determine_locale() );
}
public function test_wp_login_cookie_on_login_page_empty_string() {
add_filter(
'locale',
static function() {
return 'siteLocale';
}
);
wp_set_current_user( self::$user_id );
$GLOBALS['pagenow'] = 'wp-login.php';
$_COOKIE['wp_lang'] = '';
$this->assertSame( 'siteLocale', determine_locale() );
}
}