Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 (
"$input_name.php" === $plugin_file ||
$plugin_file === $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