From 5b1b51f9ab6a7346ec5e2cc57e4289368d0bd59a Mon Sep 17 00:00:00 2001 From: Victor Camnerin Date: Mon, 31 Aug 2026 09:50:00 +0200 Subject: [PATCH] Always set the Language property on translation updates `wp language update` reads `$update->Language` when logging each pack it is about to install, but only assigned it when the translations API returned an `english_name` for that locale. The two sides can disagree: the update check offers packs for every locale installed on the site, while `get_all_languages()` re-queries the translations API pinned to the *installed* extension version. When that lookup returns nothing, `reset()` yields false, the property is never set, and PHP 8 raises "Warning: Undefined property: stdClass::$Language" before printing the locale as an empty string. Fall back to the raw locale code so the line stays meaningful and the command stays warning-free. --- features/language-plugin.feature | 32 +++++++++++++++++++++++++++ src/WP_CLI/CommandWithTranslation.php | 13 +++++------ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/features/language-plugin.feature b/features/language-plugin.feature index b738af15..2cb03376 100644 --- a/features/language-plugin.feature +++ b/features/language-plugin.feature @@ -592,3 +592,35 @@ Feature: Manage plugin translation files for a WordPress install # If the fix is working, installed languages should be detected via text domain When I run `wp language plugin is-installed test-plugin de_DE` Then the return code should be 0 + + @require-wp-4.0 + Scenario: Update a translation that the translations API does not list + Given a WP install + And an empty cache + + When I run `wp plugin install akismet --version=3.2 --force` + Then STDERR should be empty + + When I run `wp language plugin install akismet de_DE` + Then STDERR should be empty + + When I run `wp plugin install akismet --version=4.0 --force` + Then STDERR should be empty + + # The update check still offers the de_DE language pack, but the translations + # API no longer reports de_DE for the installed version, so there is no + # english_name to fall back on. + And that HTTP requests to api.wordpress.org/translations/plugins/1.0/ will respond with: + """ + HTTP/1.1 200 + Content-Type: application/json + + {"translations":[]} + """ + + When I run `wp language plugin update akismet` + Then STDOUT should contain: + """ + Updating 'de_DE' translation for Akismet + """ + And STDERR should be empty diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index b0efeccb..46d40f24 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -106,13 +106,12 @@ public function update( $args, $assoc_args ) { $translation = wp_list_filter( $all_languages, array( 'language' => $update->language ) ); $translation = (object) reset( $translation ); - $update->Type = ucfirst( $update->type ); - $update->Name = $name; - $update->Version = $update->version; - - if ( isset( $translation->english_name ) ) { - $update->Language = $translation->english_name; - } + $update->Type = ucfirst( $update->type ); + $update->Name = $name; + $update->Version = $update->version; + $update->Language = isset( $translation->english_name ) + ? $translation->english_name + : $update->language; if ( ! isset( $updates_per_type[ $update->type ] ) ) { $updates_per_type[ $update->type ] = array();