From c557605794d938df2e1e0d600f188b9172ad53da Mon Sep 17 00:00:00 2001 From: desrosj Date: Wed, 20 Nov 2024 02:50:24 +0000 Subject: [PATCH] i18n: Account for `load_*_textdomain()` after JIT loading. When `load_*_textdomain()` functions are called after WordPress has already attempted just-in-time loading of translations, nothing happens. This updates the related logic to retry translation loading when a custom path is set to ensure all translations are available. Additionally, this also fixes cases where an `en_US.mo` file is provided with non-English strings to override the default language. Follow up to [59157]. Props swissspidy, peterwilsoncc, desrosj, apermo, sergeybiryukov, wildworks, tigriweb, twvania, looswebstudio, stimul, audrasjb, finntown, bluantinoo, timwhitlock, albigdd. See #62337. Built from https://develop.svn.wordpress.org/trunk@59430 git-svn-id: http://core.svn.wordpress.org/trunk@58816 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/class-wp-textdomain-registry.php | 12 +++++++- wp-includes/l10n.php | 29 ++++++++++++++++++-- wp-includes/version.php | 2 +- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/wp-includes/class-wp-textdomain-registry.php b/wp-includes/class-wp-textdomain-registry.php index e5aeb82e5c..bb2135e365 100644 --- a/wp-includes/class-wp-textdomain-registry.php +++ b/wp-includes/class-wp-textdomain-registry.php @@ -153,6 +153,16 @@ class WP_Textdomain_Registry { * @param string $path Language directory path. */ public function set_custom_path( $domain, $path ) { + // If just-in-time loading was triggered before, reset the entry so it can be tried again. + + if ( isset( $this->all[ $domain ] ) ) { + $this->all[ $domain ] = array_filter( $this->all[ $domain ] ); + } + + if ( empty( $this->current[ $domain ] ) ) { + unset( $this->current[ $domain ] ); + } + $this->custom_paths[ $domain ] = rtrim( $path, '/' ); } @@ -336,7 +346,7 @@ class WP_Textdomain_Registry { * If no path is found for the given locale and a custom path has been set * using load_plugin_textdomain/load_theme_textdomain, use that one. */ - if ( 'en_US' !== $locale && isset( $this->custom_paths[ $domain ] ) ) { + if ( isset( $this->custom_paths[ $domain ] ) ) { $fallback_location = rtrim( $this->custom_paths[ $domain ], '/' ) . '/'; $this->set( $domain, $locale, $fallback_location ); return $fallback_location; diff --git a/wp-includes/l10n.php b/wp-includes/l10n.php index bee3581618..f9239f84b9 100644 --- a/wp-includes/l10n.php +++ b/wp-includes/l10n.php @@ -985,6 +985,9 @@ function load_default_textdomain( $locale = null ) { * @since 4.6.0 The function now tries to load the .mo file from the languages directory first. * @since 6.7.0 Translations are no longer immediately loaded, but handed off to the just-in-time loading mechanism. * + * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry. + * @global array $l10n An array of all currently loaded text domains. + * * @param string $domain Unique identifier for retrieving translated strings * @param string|false $deprecated Optional. Deprecated. Use the $plugin_rel_path parameter instead. * Default false. @@ -994,7 +997,8 @@ function load_default_textdomain( $locale = null ) { */ function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path = false ) { /** @var WP_Textdomain_Registry $wp_textdomain_registry */ - global $wp_textdomain_registry; + /** @var array $l10n */ + global $wp_textdomain_registry, $l10n; if ( ! is_string( $domain ) ) { return false; @@ -1011,6 +1015,11 @@ function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path $wp_textdomain_registry->set_custom_path( $domain, $path ); + // If just-in-time loading was triggered before, reset the entry so it can be tried again. + if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof NOOP_Translations ) { + unset( $l10n[ $domain ] ); + } + return true; } @@ -1022,6 +1031,7 @@ function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path * @since 6.7.0 Translations are no longer immediately loaded, but handed off to the just-in-time loading mechanism. * * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry. + * @global array $l10n An array of all currently loaded text domains. * * @param string $domain Text domain. Unique identifier for retrieving translated strings. * @param string $mu_plugin_rel_path Optional. Relative to `WPMU_PLUGIN_DIR` directory in which the .mo @@ -1030,7 +1040,8 @@ function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path */ function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) { /** @var WP_Textdomain_Registry $wp_textdomain_registry */ - global $wp_textdomain_registry; + /** @var array $l10n */ + global $wp_textdomain_registry, $l10n; if ( ! is_string( $domain ) ) { return false; @@ -1040,6 +1051,11 @@ function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) { $wp_textdomain_registry->set_custom_path( $domain, $path ); + // If just-in-time loading was triggered before, reset the entry so it can be tried again. + if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof NOOP_Translations ) { + unset( $l10n[ $domain ] ); + } + return true; } @@ -1056,6 +1072,7 @@ function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) { * @since 6.7.0 Translations are no longer immediately loaded, but handed off to the just-in-time loading mechanism. * * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry. + * @global array $l10n An array of all currently loaded text domains. * * @param string $domain Text domain. Unique identifier for retrieving translated strings. * @param string|false $path Optional. Path to the directory containing the .mo file. @@ -1064,7 +1081,8 @@ function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) { */ function load_theme_textdomain( $domain, $path = false ) { /** @var WP_Textdomain_Registry $wp_textdomain_registry */ - global $wp_textdomain_registry; + /** @var array $l10n */ + global $wp_textdomain_registry, $l10n; if ( ! is_string( $domain ) ) { return false; @@ -1076,6 +1094,11 @@ function load_theme_textdomain( $domain, $path = false ) { $wp_textdomain_registry->set_custom_path( $domain, $path ); + // If just-in-time loading was triggered before, reset the entry so it can be tried again. + if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof NOOP_Translations ) { + unset( $l10n[ $domain ] ); + } + return true; } diff --git a/wp-includes/version.php b/wp-includes/version.php index 4a9de2c060..ed3c384b38 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.8-alpha-59427'; +$wp_version = '6.8-alpha-59430'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.