@@ -1235,6 +1235,10 @@ private function get_plugin_dependencies( $slug ) {
12351235 return [];
12361236 }
12371237
1238+ /**
1239+ * @var object{requires_plugins?: array} $api
1240+ */
1241+
12381242 // Check if requires_plugins field exists and is not empty
12391243 if ( ! empty ( $ api ->requires_plugins ) && is_array ( $ api ->requires_plugins ) ) {
12401244 return $ api ->requires_plugins ;
@@ -1508,6 +1512,10 @@ public function is_installed( $args, $assoc_args ) {
15081512 *
15091513 * Returns exit code 0 when active, 1 when not active.
15101514 *
1515+ * If the plugin does not exist but is still in WordPress's active plugins storage
1516+ * (such as the active plugins option or the sitewide plugins option for network-activated plugins),
1517+ * a warning will be emitted.
1518+ *
15111519 * ## OPTIONS
15121520 *
15131521 * <plugin>
@@ -1531,6 +1539,55 @@ public function is_active( $args, $assoc_args ) {
15311539 $ plugin = $ this ->fetcher ->get ( $ args [0 ] );
15321540
15331541 if ( ! $ plugin ) {
1542+ // Plugin not found via fetcher, but it might still be in active_plugins option
1543+ // Check if it's in the active_plugins list
1544+ $ input_name = $ args [0 ];
1545+ // For network plugins: active_sitewide_plugins is an array where keys are plugin files and values are timestamps
1546+ // For regular plugins: active_plugins is an array of plugin file paths
1547+ $ active_plugins = $ network_wide ? get_site_option ( 'active_sitewide_plugins ' , [] ) : get_option ( 'active_plugins ' , [] );
1548+
1549+ // Ensure we have an array to work with
1550+ if ( ! is_array ( $ active_plugins ) ) {
1551+ $ active_plugins = [];
1552+ }
1553+
1554+ // For network-wide plugins, extract the plugin files from the keys
1555+ if ( $ network_wide ) {
1556+ $ active_plugin_files = array_keys ( $ active_plugins );
1557+ } else {
1558+ $ active_plugin_files = $ active_plugins ;
1559+ }
1560+
1561+ // Try to find a matching plugin file in active_plugins using the same logic as the fetcher
1562+ // This matches: exact file name, "name.php", or directory name
1563+ $ found_in_active = '' ;
1564+ foreach ( $ active_plugin_files as $ plugin_file ) {
1565+ // Ensure plugin_file is a string
1566+ if ( ! is_string ( $ plugin_file ) ) {
1567+ continue ;
1568+ }
1569+
1570+ // Check if the input matches the plugin file in various ways
1571+ // This mirrors the logic in WP_CLI\Fetchers\Plugin::get()
1572+ if (
1573+ "$ input_name.php " === $ plugin_file ||
1574+ $ plugin_file === $ input_name ||
1575+ ( dirname ( $ plugin_file ) === $ input_name && '. ' !== $ input_name )
1576+ ) {
1577+ $ found_in_active = $ plugin_file ;
1578+ break ;
1579+ }
1580+ }
1581+
1582+ if ( $ found_in_active ) {
1583+ // Plugin is in active_plugins but file doesn't exist
1584+ // Use validate_plugin to confirm the file is missing
1585+ $ validation = validate_plugin ( $ found_in_active );
1586+ if ( is_wp_error ( $ validation ) ) {
1587+ WP_CLI ::warning ( "Plugin ' {$ input_name }' is marked as active but the plugin file does not exist. " );
1588+ }
1589+ }
1590+
15341591 WP_CLI ::halt ( 1 );
15351592 }
15361593
0 commit comments