From 06379c6f368a2fea6c9e27dfcc46b3032747e860 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 26 Mar 2026 12:00:10 +0100 Subject: [PATCH 1/5] Clear translation file cache after uninstall As of WP 6.5, the presence of .mo and .l10n.php files is cached. --- src/Core_Language_Command.php | 1 + src/Plugin_Language_Command.php | 1 + src/Theme_Language_Command.php | 1 + src/WP_CLI/CommandWithTranslation.php | 13 +++++++++++++ 4 files changed, 16 insertions(+) diff --git a/src/Core_Language_Command.php b/src/Core_Language_Command.php index 16347599..3bcc7132 100644 --- a/src/Core_Language_Command.php +++ b/src/Core_Language_Command.php @@ -374,6 +374,7 @@ public function uninstall( $args ) { } if ( $deleted ) { + $this->clear_translation_files_cache( WP_LANG_DIR . $dir ); WP_CLI::success( 'Language uninstalled.' ); } else { WP_CLI::error( "Couldn't uninstall language." ); diff --git a/src/Plugin_Language_Command.php b/src/Plugin_Language_Command.php index e6f10d3e..0e4b9ad3 100644 --- a/src/Plugin_Language_Command.php +++ b/src/Plugin_Language_Command.php @@ -551,6 +551,7 @@ public function uninstall( $args, $assoc_args ) { if ( $count_files_to_remove === $count_files_removed ) { $result['status'] = 'uninstalled'; ++$successes; + $this->clear_translation_files_cache( $dir ); \WP_CLI::log( "Language '{$language_code}' for '{$plugin}' uninstalled." ); } elseif ( $count_files_removed ) { \WP_CLI::log( "Language '{$language_code}' for '{$plugin}' partially uninstalled." ); diff --git a/src/Theme_Language_Command.php b/src/Theme_Language_Command.php index 7e5bce13..af91b5e5 100644 --- a/src/Theme_Language_Command.php +++ b/src/Theme_Language_Command.php @@ -570,6 +570,7 @@ public function uninstall( $args, $assoc_args ) { if ( $count_files_to_remove === $count_files_removed ) { $result['status'] = 'uninstalled'; ++$successes; + $this->clear_translation_files_cache( $dir ); \WP_CLI::log( "Language '{$language_code}' for '{$theme}' uninstalled." ); } elseif ( $count_files_removed ) { \WP_CLI::log( "Language '{$language_code}' for '{$theme}' partially uninstalled." ); diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index dc2d1da3..46b503be 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -439,4 +439,17 @@ protected function get_all_languages( $slug = null ) { protected function get_formatter( &$assoc_args ) { return new Formatter( $assoc_args, $this->obj_fields, $this->obj_type ); } + + /** + * Clears the translation files cache for a given directory. + * + * @param string $dir The directory to clear the cache for. + */ + protected function clear_translation_files_cache( $dir ) { + // As of WP 6.5, the presence of .mo and .l10n.php files is cached. + if ( function_exists( 'wp_cache_delete' ) ) { + $path = rtrim( $dir, '/' ) . '/'; + wp_cache_delete( md5( $path ), 'translation_files' ); + } + } } From 168d56282170f0f96176a5663d4ca6584306c576 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 26 Mar 2026 12:11:42 +0100 Subject: [PATCH 2/5] Remove `function_exists` check --- src/WP_CLI/CommandWithTranslation.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index 46b503be..b0efeccb 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -443,13 +443,12 @@ protected function get_formatter( &$assoc_args ) { /** * Clears the translation files cache for a given directory. * + * As of WP 6.5, the presence of .mo and .l10n.php files is cached. + * * @param string $dir The directory to clear the cache for. */ protected function clear_translation_files_cache( $dir ) { - // As of WP 6.5, the presence of .mo and .l10n.php files is cached. - if ( function_exists( 'wp_cache_delete' ) ) { - $path = rtrim( $dir, '/' ) . '/'; - wp_cache_delete( md5( $path ), 'translation_files' ); - } + $path = rtrim( $dir, '/' ) . '/'; + wp_cache_delete( md5( $path ), 'translation_files' ); } } From 46c06d7845340233e897395f7923ee1588aa9cfe Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 26 Mar 2026 12:12:49 +0100 Subject: [PATCH 3/5] Fix for partial uninstall --- src/Plugin_Language_Command.php | 1 + src/Theme_Language_Command.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Plugin_Language_Command.php b/src/Plugin_Language_Command.php index 0e4b9ad3..dd47d74a 100644 --- a/src/Plugin_Language_Command.php +++ b/src/Plugin_Language_Command.php @@ -557,6 +557,7 @@ public function uninstall( $args, $assoc_args ) { \WP_CLI::log( "Language '{$language_code}' for '{$plugin}' partially uninstalled." ); $result['status'] = 'partial uninstall'; ++$errors; + $this->clear_translation_files_cache( $dir ); } elseif ( $had_one_file ) { /* $count_files_removed == 0 */ \WP_CLI::log( "Couldn't uninstall language '{$language_code}' from plugin {$plugin}." ); $result['status'] = 'failed to uninstall'; diff --git a/src/Theme_Language_Command.php b/src/Theme_Language_Command.php index af91b5e5..dd790438 100644 --- a/src/Theme_Language_Command.php +++ b/src/Theme_Language_Command.php @@ -576,6 +576,7 @@ public function uninstall( $args, $assoc_args ) { \WP_CLI::log( "Language '{$language_code}' for '{$theme}' partially uninstalled." ); $result['status'] = 'partial uninstall'; ++$errors; + $this->clear_translation_files_cache( $dir ); } elseif ( $had_one_file ) { /* $count_files_removed == 0 */ \WP_CLI::log( "Couldn't uninstall language '{$language_code}' from theme {$theme}." ); $result['status'] = 'failed to uninstall'; From 0407ebcfc03d50e89d490fea28b391a55c30c69d Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 26 Mar 2026 12:39:12 +0100 Subject: [PATCH 4/5] Fix deleted check in core language command --- src/Core_Language_Command.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Core_Language_Command.php b/src/Core_Language_Command.php index 3bcc7132..25204657 100644 --- a/src/Core_Language_Command.php +++ b/src/Core_Language_Command.php @@ -370,7 +370,9 @@ public function uninstall( $args ) { } /** @var WP_Filesystem_Base $wp_filesystem */ - $deleted = $wp_filesystem->delete( WP_LANG_DIR . $dir . '/' . $file ); + if ( $wp_filesystem->delete( WP_LANG_DIR . $dir . '/' . $file ) ) { + $deleted = true; + } } if ( $deleted ) { From 8b1c0c4c6fb075153c2ea7d1cae54a79e09fa3bb Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 26 Mar 2026 12:53:15 +0100 Subject: [PATCH 5/5] Improve some tests involving object cache drop-in --- features/language-core.feature | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/features/language-core.feature b/features/language-core.feature index ecab9c70..141f2c93 100644 --- a/features/language-core.feature +++ b/features/language-core.feature @@ -225,9 +225,12 @@ Feature: Manage core translation files for a WordPress install Given an empty directory And WP files And a database - And I run `wp core download --version= --force` + And I try `wp core download --version= --force` + And the return code should be 0 And wp-config.php - And I run `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` + # The SQLite object cache drop-in might produce a "no such table: wp_options" STDERR during installation. + And I try `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` + And the return code should be 0 When I run `wp language core list --fields=language,status,update` Then STDOUT should be a table containing rows: @@ -505,9 +508,12 @@ Feature: Manage core translation files for a WordPress install Given an empty directory And WP files And a database - And I run `wp core download --version= --force` + And I try `wp core download --version= --force` + And the return code should be 0 And wp-config.php - And I run `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` + # The SQLite object cache drop-in might produce a "no such table: wp_options" STDERR during installation. + And I try `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` + And the return code should be 0 When I run `wp language core install en_CA ja` Then STDERR should be empty