@@ -1221,6 +1221,10 @@ private function get_plugin_dependencies( $slug ) {
12211221 return [];
12221222 }
12231223
1224+ /**
1225+ * @var object{requires_plugins?: array} $api
1226+ */
1227+
12241228 // Check if requires_plugins field exists and is not empty
12251229 if ( ! empty ( $ api ->requires_plugins ) && is_array ( $ api ->requires_plugins ) ) {
12261230 return $ api ->requires_plugins ;
@@ -1494,6 +1498,10 @@ public function is_installed( $args, $assoc_args ) {
14941498 *
14951499 * Returns exit code 0 when active, 1 when not active.
14961500 *
1501+ * If the plugin does not exist but is still in WordPress's active plugins storage
1502+ * (such as the active plugins option or the sitewide plugins option for network-activated plugins),
1503+ * a warning will be emitted.
1504+ *
14971505 * ## OPTIONS
14981506 *
14991507 * <plugin>
@@ -1517,6 +1525,55 @@ public function is_active( $args, $assoc_args ) {
15171525 $ plugin = $ this ->fetcher ->get ( $ args [0 ] );
15181526
15191527 if ( ! $ plugin ) {
1528+ // Plugin not found via fetcher, but it might still be in active_plugins option
1529+ // Check if it's in the active_plugins list
1530+ $ input_name = $ args [0 ];
1531+ // For network plugins: active_sitewide_plugins is an array where keys are plugin files and values are timestamps
1532+ // For regular plugins: active_plugins is an array of plugin file paths
1533+ $ active_plugins = $ network_wide ? get_site_option ( 'active_sitewide_plugins ' , [] ) : get_option ( 'active_plugins ' , [] );
1534+
1535+ // Ensure we have an array to work with
1536+ if ( ! is_array ( $ active_plugins ) ) {
1537+ $ active_plugins = [];
1538+ }
1539+
1540+ // For network-wide plugins, extract the plugin files from the keys
1541+ if ( $ network_wide ) {
1542+ $ active_plugin_files = array_keys ( $ active_plugins );
1543+ } else {
1544+ $ active_plugin_files = $ active_plugins ;
1545+ }
1546+
1547+ // Try to find a matching plugin file in active_plugins using the same logic as the fetcher
1548+ // This matches: exact file name, "name.php", or directory name
1549+ $ found_in_active = '' ;
1550+ foreach ( $ active_plugin_files as $ plugin_file ) {
1551+ // Ensure plugin_file is a string
1552+ if ( ! is_string ( $ plugin_file ) ) {
1553+ continue ;
1554+ }
1555+
1556+ // Check if the input matches the plugin file in various ways
1557+ // This mirrors the logic in WP_CLI\Fetchers\Plugin::get()
1558+ if (
1559+ "$ input_name.php " === $ plugin_file ||
1560+ $ plugin_file === $ input_name ||
1561+ ( dirname ( $ plugin_file ) === $ input_name && '. ' !== $ input_name )
1562+ ) {
1563+ $ found_in_active = $ plugin_file ;
1564+ break ;
1565+ }
1566+ }
1567+
1568+ if ( $ found_in_active ) {
1569+ // Plugin is in active_plugins but file doesn't exist
1570+ // Use validate_plugin to confirm the file is missing
1571+ $ validation = validate_plugin ( $ found_in_active );
1572+ if ( is_wp_error ( $ validation ) ) {
1573+ WP_CLI ::warning ( "Plugin ' {$ input_name }' is marked as active but the plugin file does not exist. " );
1574+ }
1575+ }
1576+
15201577 WP_CLI ::halt ( 1 );
15211578 }
15221579
0 commit comments