I18N: Enable unloading of text domains that have been loaded just in time.

[37415] removed the requirement to call `load_plugin_textdomain()` / `load_theme_textdomain()`. This caused `unload_textdomain()` to not work properly anymore in these cases.

With this change, unloaded text domains need to be explicitly loaded manually if you want to use them again.

Props swissspidy, ocean90.
Fixes #37113. See #34114.

git-svn-id: https://develop.svn.wordpress.org/trunk@37855 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Pascal Birchler 2016-06-23 14:47:44 +00:00
parent 048bb7b250
commit d0555f9544
2 changed files with 69 additions and 7 deletions

View File

@ -509,14 +509,17 @@ function translate_nooped_plural( $nooped_plural, $count, $domain = 'default' )
*
* @since 1.5.0
*
* @global array $l10n
* @global array $l10n An array of all currently loaded text domains.
* @global array $l10n_unloaded An array of all text domains that have been unloaded again.
*
* @param string $domain Text domain. Unique identifier for retrieving translated strings.
* @param string $mofile Path to the .mo file.
* @return bool True on success, false on failure.
*/
function load_textdomain( $domain, $mofile ) {
global $l10n;
global $l10n, $l10n_unloaded;
$l10n_unloaded = (array) $l10n_unloaded;
/**
* Filters whether to override the .mo file loading.
@ -530,6 +533,8 @@ function load_textdomain( $domain, $mofile ) {
$plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile );
if ( true == $plugin_override ) {
unset( $l10n_unloaded[ $domain ] );
return true;
}
@ -561,6 +566,8 @@ function load_textdomain( $domain, $mofile ) {
if ( isset( $l10n[$domain] ) )
$mo->merge_with( $l10n[$domain] );
unset( $l10n_unloaded[ $domain ] );
$l10n[$domain] = &$mo;
return true;
@ -571,13 +578,16 @@ function load_textdomain( $domain, $mofile ) {
*
* @since 3.0.0
*
* @global array $l10n
* @global array $l10n An array of all currently loaded text domains.
* @global array $l10n_unloaded An array of all text domains that have been unloaded again.
*
* @param string $domain Text domain. Unique identifier for retrieving translated strings.
* @return bool Whether textdomain was unloaded.
*/
function unload_textdomain( $domain ) {
global $l10n;
global $l10n, $l10n_unloaded;
$l10n_unloaded = (array) $l10n_unloaded;
/**
* Filters whether to override the text domain unloading.
@ -589,8 +599,11 @@ function unload_textdomain( $domain ) {
*/
$plugin_override = apply_filters( 'override_unload_textdomain', false, $domain );
if ( $plugin_override )
if ( $plugin_override ) {
$l10n_unloaded[ $domain ] = true;
return true;
}
/**
* Fires before the text domain is unloaded.
@ -603,6 +616,9 @@ function unload_textdomain( $domain ) {
if ( isset( $l10n[$domain] ) ) {
unset( $l10n[$domain] );
$l10n_unloaded[ $domain ] = true;
return true;
}
@ -793,15 +809,20 @@ function load_child_theme_textdomain( $domain, $path = false ) {
* @access private
*
* @see get_translations_for_domain()
* @global array $l10n_unloaded An array of all text domains that have been unloaded again.
*
* @param string $domain Text domain. Unique identifier for retrieving translated strings.
* @return bool True when the textdomain is successfully loaded, false otherwise.
*/
function _load_textdomain_just_in_time( $domain ) {
global $l10n_unloaded;
$l10n_unloaded = (array) $l10n_unloaded;
static $cached_mofiles = null;
// Short-circuit if domain is 'default' which is reserved for core.
if ( 'default' === $domain ) {
if ( 'default' === $domain || isset( $l10n_unloaded[ $domain ] ) ) {
return false;
}

View File

@ -22,6 +22,8 @@ class Tests_L10n_loadTextdomainJustInTime extends WP_UnitTestCase {
add_filter( 'template_root', array( $this, 'filter_theme_root' ) );
wp_clean_themes_cache();
unset( $GLOBALS['wp_themes'] );
unset( $GLOBALS['l10n_unloaded'] );
}
function tearDown() {
@ -89,7 +91,7 @@ class Tests_L10n_loadTextdomainJustInTime extends WP_UnitTestCase {
}
/**
* @ticket 341142
* @ticket 34114
*/
public function test_get_translations_for_domain_does_not_return_null_if_override_load_textdomain_is_used() {
add_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
@ -100,4 +102,43 @@ class Tests_L10n_loadTextdomainJustInTime extends WP_UnitTestCase {
$this->assertTrue( $translations instanceof NOOP_Translations );
}
/**
* @ticket 37113
*/
public function test_should_allow_unloading_of_text_domain() {
add_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
require_once DIR_TESTDATA . '/plugins/internationalized-plugin.php';
$expected_output_before = i18n_plugin_test();
$is_textdomain_loaded_before = is_textdomain_loaded( 'internationalized-plugin' );
unload_textdomain( 'internationalized-plugin' );
remove_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
$expected_output_after = i18n_plugin_test();
$is_textdomain_loaded_after = is_textdomain_loaded( 'internationalized-plugin' );
add_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
load_textdomain( 'internationalized-plugin', WP_LANG_DIR . '/plugins/internationalized-plugin-de_DE.mo' );
$expected_output_final = i18n_plugin_test();
$is_textdomain_loaded_final = is_textdomain_loaded( 'internationalized-plugin' );
unload_textdomain( 'internationalized-plugin' );
remove_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
// Text domain loaded just in time.
$this->assertSame( 'Das ist ein Dummy Plugin', $expected_output_before );
$this->assertTrue( $is_textdomain_loaded_before );
// Text domain unloaded.
$this->assertSame( 'This is a dummy plugin', $expected_output_after );
$this->assertFalse( $is_textdomain_loaded_after );
// Text domain loaded manually again.
$this->assertSame( 'Das ist ein Dummy Plugin', $expected_output_final );
$this->assertTrue( $is_textdomain_loaded_final );
}
}