diff --git a/src/wp-includes/l10n.php b/src/wp-includes/l10n.php index 1923c8c2a2..632f432f62 100644 --- a/src/wp-includes/l10n.php +++ b/src/wp-includes/l10n.php @@ -821,7 +821,7 @@ function load_textdomain( $domain, $mofile, $locale = null ) { if ( 'mo' !== $preferred_format ) { array_unshift( $translation_files, - substr_replace( $mofile, ".l10n.$preferred_format", - strlen( $preferred_format ) ) + substr_replace( $mofile, ".l10n.$preferred_format", - strlen( '.mo' ) ) ); } diff --git a/src/wp-includes/l10n/class-wp-translation-controller.php b/src/wp-includes/l10n/class-wp-translation-controller.php index fbe5fa7d0c..616dce5793 100644 --- a/src/wp-includes/l10n/class-wp-translation-controller.php +++ b/src/wp-includes/l10n/class-wp-translation-controller.php @@ -151,11 +151,13 @@ final class WP_Translation_Controller { } if ( null !== $locale ) { - foreach ( $this->loaded_translations[ $locale ][ $textdomain ] as $i => $moe ) { - if ( $file === $moe || $file === $moe->get_file() ) { - unset( $this->loaded_translations[ $locale ][ $textdomain ][ $i ] ); - unset( $this->loaded_files[ $moe->get_file() ][ $locale ][ $textdomain ] ); - return true; + if ( isset( $this->loaded_translations[ $locale ][ $textdomain ] ) ) { + foreach ( $this->loaded_translations[ $locale ][ $textdomain ] as $i => $moe ) { + if ( $file === $moe || $file === $moe->get_file() ) { + unset( $this->loaded_translations[ $locale ][ $textdomain ][ $i ] ); + unset( $this->loaded_files[ $moe->get_file() ][ $locale ][ $textdomain ] ); + return true; + } } } @@ -163,6 +165,10 @@ final class WP_Translation_Controller { } foreach ( $this->loaded_translations as $l => $domains ) { + if ( ! isset( $domains[ $textdomain ] ) ) { + continue; + } + foreach ( $domains[ $textdomain ] as $i => $moe ) { if ( $file === $moe || $file === $moe->get_file() ) { unset( $this->loaded_translations[ $l ][ $textdomain ][ $i ] ); @@ -185,18 +191,21 @@ final class WP_Translation_Controller { * @return bool True on success, false otherwise. */ public function unload_textdomain( string $textdomain = 'default', string $locale = null ): bool { + $unloaded = false; + if ( null !== $locale ) { - foreach ( $this->loaded_translations[ $locale ][ $textdomain ] as $moe ) { - unset( $this->loaded_files[ $moe->get_file() ][ $locale ][ $textdomain ] ); + if ( isset( $this->loaded_translations[ $locale ][ $textdomain ] ) ) { + $unloaded = true; + foreach ( $this->loaded_translations[ $locale ][ $textdomain ] as $moe ) { + unset( $this->loaded_files[ $moe->get_file() ][ $locale ][ $textdomain ] ); + } } unset( $this->loaded_translations[ $locale ][ $textdomain ] ); - return true; + return $unloaded; } - $unloaded = false; - foreach ( $this->loaded_translations as $l => $domains ) { if ( ! isset( $domains[ $textdomain ] ) ) { continue; diff --git a/tests/phpunit/tests/l10n/wpTranslationController.php b/tests/phpunit/tests/l10n/wpTranslationController.php index 9e33a1f543..5a7206f6d9 100644 --- a/tests/phpunit/tests/l10n/wpTranslationController.php +++ b/tests/phpunit/tests/l10n/wpTranslationController.php @@ -105,6 +105,30 @@ class WP_Translation_Controller_Tests extends WP_UnitTestCase { $this->assertTrue( $unload_php_successful ); } + /** + * @covers ::load_textdomain + * + * @return void + */ + public function test_load_textdomain_prefers_php_files_by_default() { + $load_successful = load_textdomain( 'wp-tests-domain', DIR_TESTDATA . '/pomo/simple.mo' ); + + $instance = WP_Translation_Controller::instance(); + + $is_loaded = $instance->is_textdomain_loaded( 'wp-tests-domain', 'en_US' ); + + $unload_mo = $instance->unload_file( DIR_TESTDATA . '/pomo/simple.mo', 'wp-tests-domain' ); + $unload_php = $instance->unload_file( DIR_TESTDATA . '/pomo/simple.l10n.php', 'wp-tests-domain' ); + + $unload_successful = unload_textdomain( 'wp-tests-domain' ); + + $this->assertTrue( $load_successful, 'Translation not successfully loaded' ); + $this->assertTrue( $is_loaded ); + $this->assertFalse( $unload_mo ); + $this->assertTrue( $unload_php ); + $this->assertTrue( $unload_successful ); + } + /** * @covers ::load_textdomain * @@ -296,6 +320,21 @@ class WP_Translation_Controller_Tests extends WP_UnitTestCase { $this->assertFalse( $is_loaded_after ); } + /** + * @covers ::unload_file + * @covers ::unload_textdomain + * + * @return void + */ + public function test_unload_non_existent_files_and_textdomains() { + $controller = new WP_Translation_Controller(); + $this->assertFalse( $controller->unload_textdomain( 'foobarbaz' ) ); + $this->assertFalse( $controller->unload_textdomain( 'foobarbaz', 'es_ES' ) ); + $this->assertFalse( $controller->unload_textdomain( 'default', 'es_ES' ) ); + $this->assertFalse( $controller->unload_file( DIR_TESTDATA . '/l10n/fa_IR.mo' ) ); + $this->assertFalse( $controller->unload_file( DIR_TESTDATA . '/l10n/fa_IR.mo', 'es_ES' ) ); + } + /** * @covers ::load_textdomain * @covers ::unload_textdomain diff --git a/tests/phpunit/tests/l10n/wpTranslationsConvert.php b/tests/phpunit/tests/l10n/wpTranslationsConvert.php index 0de159b609..320d15da77 100644 --- a/tests/phpunit/tests/l10n/wpTranslationsConvert.php +++ b/tests/phpunit/tests/l10n/wpTranslationsConvert.php @@ -28,7 +28,7 @@ class WP_Translation_Controller_Convert_Tests extends WP_UnitTestCase { } /** - * @covers ::unload + * @covers ::unload_textdomain * * @return void */ @@ -40,7 +40,7 @@ class WP_Translation_Controller_Convert_Tests extends WP_UnitTestCase { /** * @covers ::load - * @covers ::unload + * @covers ::unload_textdomain * @covers ::is_textdomain_loaded * @covers ::translate * @covers ::locate_translation @@ -62,7 +62,7 @@ class WP_Translation_Controller_Convert_Tests extends WP_UnitTestCase { } /** - * @covers ::unload + * @covers ::unload_file * @covers WP_Translation_File::get_file * * @return void @@ -77,7 +77,7 @@ class WP_Translation_Controller_Convert_Tests extends WP_UnitTestCase { } /** - * @covers ::unload + * @covers ::unload_textdomain * @covers ::is_textdomain_loaded * * @return void @@ -235,7 +235,7 @@ class WP_Translation_Controller_Convert_Tests extends WP_UnitTestCase { /** * @covers ::load - * @covers ::unload + * @covers ::unload_file * @covers ::is_textdomain_loaded * @covers ::translate * @covers ::translate_plural @@ -289,7 +289,7 @@ class WP_Translation_Controller_Convert_Tests extends WP_UnitTestCase { * @covers ::set_locale * @covers ::get_locale * @covers ::load - * @covers ::unload + * @covers ::unload_file * @covers ::is_textdomain_loaded * @covers ::translate * @covers ::translate_plural @@ -333,7 +333,7 @@ class WP_Translation_Controller_Convert_Tests extends WP_UnitTestCase { } /** - * @covers ::unload + * @covers ::unload_textdomain * * @return void */ @@ -411,7 +411,6 @@ class WP_Translation_Controller_Convert_Tests extends WP_UnitTestCase { /** * @covers ::load - * @covers ::unload * @covers ::is_textdomain_loaded * @covers ::translate * @covers ::translate_plural