From e95e96911f26ffeaf31fda66bde33c6261347768 Mon Sep 17 00:00:00 2001 From: Kamran Abdul Aziz Date: Sun, 13 Sep 2026 16:27:26 +0530 Subject: [PATCH] Fix update_unavailable_reason leaking across rows in plugin and theme list The reason string was set inside the item loop when an update did not meet the PHP or WordPress requirement, but it was never reset for the next item. Every plugin or theme listed after an incompatible one then showed the first item's reason, even with update none or available. Reset the variable for each item so only the affected row carries a reason. Covers both Plugin_Command::get_item_list() and the ParseThemeNameInput trait, which got the same pattern from the same commit. --- features/plugin.feature | 58 ++++++++++++++++++++++++++++++ features/theme.feature | 58 ++++++++++++++++++++++++++++++ src/Plugin_Command.php | 5 ++- src/WP_CLI/ParseThemeNameInput.php | 5 ++- 4 files changed, 124 insertions(+), 2 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index dfd3f3ef..07dd97db 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -1131,3 +1131,61 @@ Feature: Manage WordPress plugins """ Warning: example: This update requires PHP version 100 """ + + @require-wp-4.0 + Scenario: The unavailable reason of one plugin does not leak into other plugins + Given a WP install + And a wp-content/plugins/aaa-example/aaa-example.php file: + """ + =' ); + // Reset for each plugin so a previous plugin's reason does not leak into this row. + $update_unavailable_reason = ''; + if ( ! $compatible_php ) { $update = 'unavailable'; @@ -1030,7 +1033,7 @@ protected function get_item_list() { 'wporg_status' => $wporg_info['status'], 'wporg_last_updated' => $wporg_info['last_updated'], 'recently_active' => in_array( $file, array_keys( $recently_active ), true ), - 'update_unavailable_reason' => isset( $update_unavailable_reason ) ? $update_unavailable_reason : '', + 'update_unavailable_reason' => $update_unavailable_reason, ]; if ( $this->check_headers['tested_up_to'] ) { diff --git a/src/WP_CLI/ParseThemeNameInput.php b/src/WP_CLI/ParseThemeNameInput.php index df46b9c8..069526af 100644 --- a/src/WP_CLI/ParseThemeNameInput.php +++ b/src/WP_CLI/ParseThemeNameInput.php @@ -103,6 +103,9 @@ private function get_all_themes() { $compatible_php = empty( $requires_php ) || version_compare( PHP_VERSION, $requires_php, '>=' ); $compatible_wp = empty( $requires ) || version_compare( $wp_version, $requires, '>=' ); + // Reset for each theme so a previous theme's reason does not leak into this row. + $update_unavailable_reason = ''; + if ( ! $compatible_php ) { $update = 'unavailable'; @@ -155,7 +158,7 @@ private function get_all_themes() { 'auto_update_indicated' => $auto_update_indicated, 'requires' => $requires, 'requires_php' => $requires_php, - 'update_unavailable_reason' => isset( $update_unavailable_reason ) ? $update_unavailable_reason : '', + 'update_unavailable_reason' => $update_unavailable_reason, 'type' => $theme_type, ];