From 66d85f381e88dd4dac2106ba73a36464859d76d4 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Fri, 26 May 2023 17:55:40 +0000 Subject: [PATCH] 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 --- src/wp-includes/l10n.php | 36 ++- tests/phpunit/tests/l10n/determineLocale.php | 260 +++++++++++++++++++ 2 files changed, 276 insertions(+), 20 deletions(-) create mode 100644 tests/phpunit/tests/l10n/determineLocale.php diff --git a/src/wp-includes/l10n.php b/src/wp-includes/l10n.php index 448a233fa8..080007b869 100644 --- a/src/wp-includes/l10n.php +++ b/src/wp-includes/l10n.php @@ -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(); } /** diff --git a/tests/phpunit/tests/l10n/determineLocale.php b/tests/phpunit/tests/l10n/determineLocale.php new file mode 100644 index 0000000000..702690e6c1 --- /dev/null +++ b/tests/phpunit/tests/l10n/determineLocale.php @@ -0,0 +1,260 @@ +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() ); + } +}