Commit c557605794 for wordpress.org

commit c557605794d938df2e1e0d600f188b9172ad53da
Author: desrosj <desrosj@git.wordpress.org>
Date:   Wed Nov 20 02:50:24 2024 +0000

    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

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<string, WP_Translations|NOOP_Translations> $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<string, WP_Translations|NOOP_Translations> $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<string, WP_Translations|NOOP_Translations> $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<string, WP_Translations|NOOP_Translations> $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<string, WP_Translations|NOOP_Translations> $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<string, WP_Translations|NOOP_Translations> $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.