Skip to content
Open
86 changes: 86 additions & 0 deletions features/plugin-is-active.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
Feature: Check if a WordPress plugin is active

Background:
Given a WP install

Scenario: Check if an active plugin is active
When I run `wp plugin activate akismet`
Then STDOUT should contain:
"""
Success:
"""

When I run `wp plugin is-active akismet`
Then the return code should be 0

Scenario: Check if an inactive plugin is not active
When I run `wp plugin activate akismet`
Then STDOUT should contain:
"""
Success:
"""

When I run `wp plugin deactivate akismet`
Then STDOUT should contain:
"""
Success:
"""

When I try `wp plugin is-active akismet`
Then the return code should be 1

Scenario: Check if a non-existent plugin is not active
When I try `wp plugin is-active non-existent-plugin`
Then the return code should be 1

Scenario: Warn when plugin is in active_plugins but file does not exist
When I run `wp plugin activate akismet`
Then STDOUT should contain:
"""
Success:
"""

When I run `wp plugin is-active akismet`
Then the return code should be 0

# Remove the plugin directory
When I run `wp plugin path akismet --dir`
Then save STDOUT as {PLUGIN_PATH}

When I run `rm -rf {PLUGIN_PATH}`
Then the return code should be 0

# Now the plugin file is gone but still in active_plugins
When I try `wp plugin is-active akismet`
Then STDERR should contain:
"""
Warning: Plugin 'akismet' is marked as active but the plugin file does not exist.
"""
And the return code should be 1

Scenario: Warn when network-activated plugin is in active_sitewide_plugins but file does not exist
Given a WP multisite install

When I run `wp plugin activate akismet --network`
Then STDOUT should contain:
"""
Success:
"""

When I run `wp plugin is-active akismet --network`
Then the return code should be 0

# Remove the plugin directory
When I run `wp plugin path akismet --dir`
Then save STDOUT as {PLUGIN_PATH}

When I run `rm -rf {PLUGIN_PATH}`
Then the return code should be 0

# Now the plugin file is gone but still in active_sitewide_plugins
When I try `wp plugin is-active akismet --network`
Then STDERR should contain:
"""
Warning: Plugin 'akismet' is marked as active but the plugin file does not exist.
"""
And the return code should be 1
53 changes: 53 additions & 0 deletions src/Plugin_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,10 @@ public function is_installed( $args, $assoc_args ) {
*
* Returns exit code 0 when active, 1 when not active.
*
* If the plugin does not exist but is still in WordPress's active plugins storage
* (such as the active plugins option or the sitewide plugins option for network-activated plugins),
* a warning will be emitted.
*
* ## OPTIONS
*
* <plugin>
Expand All @@ -1371,6 +1375,55 @@ public function is_active( $args, $assoc_args ) {
$plugin = $this->fetcher->get( $args[0] );

if ( ! $plugin ) {
// Plugin not found via fetcher, but it might still be in active_plugins option
// Check if it's in the active_plugins list
$input_name = $args[0];
// For network plugins: active_sitewide_plugins is an array where keys are plugin files and values are timestamps
// For regular plugins: active_plugins is an array of plugin file paths
$active_plugins = $network_wide ? get_site_option( 'active_sitewide_plugins', [] ) : get_option( 'active_plugins', [] );

// Ensure we have an array to work with
if ( ! is_array( $active_plugins ) ) {
$active_plugins = [];
}

// For network-wide plugins, extract the plugin files from the keys
if ( $network_wide ) {
$active_plugin_files = array_keys( $active_plugins );
} else {
$active_plugin_files = $active_plugins;
}

// Try to find a matching plugin file in active_plugins using the same logic as the fetcher
// This matches: exact file name, "name.php", or directory name
$found_in_active = '';
foreach ( $active_plugin_files as $plugin_file ) {
// Ensure plugin_file is a string
if ( ! is_string( $plugin_file ) ) {
continue;
}

// Check if the input matches the plugin file in various ways
// This mirrors the logic in WP_CLI\Fetchers\Plugin::get()
if (
( ! empty( $input_name ) && "$input_name.php" === $plugin_file ) ||
( ! empty( $input_name ) && $plugin_file === $input_name ) ||
( ! empty( $input_name ) && dirname( $plugin_file ) === $input_name && '.' !== $input_name )
) {
$found_in_active = $plugin_file;
break;
}
}

if ( $found_in_active ) {
// Plugin is in active_plugins but file doesn't exist
// Use validate_plugin to confirm the file is missing
$validation = validate_plugin( $found_in_active );
if ( is_wp_error( $validation ) ) {
WP_CLI::warning( "Plugin '{$input_name}' is marked as active but the plugin file does not exist." );
}
}

WP_CLI::halt( 1 );
}

Expand Down
Loading