Opened 3 years ago
Last modified 3 years ago
#54259 new enhancement
The function deactivate_plugins should run only in the backend
Reported by: | giuse | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | |
Component: | Plugins | Keywords: | |
Focuses: | Cc: |
Description
Hello.
I think the function deactivate_plugins (https://developer.wordpress.org/reference/functions/deactivate_plugins/) should run only in the backend, never on the frontend.
Many plugin authors abuse this function to deactivate their plugin when it depends on another plugin that is inactive. If they don't check if the page is visited on the backend this function may cause serious issues in some situations.
If the presence of the "parent" plugin is not checked properly, by allowing this function on the frontend, you may have some plugins that are not intentionally disabled.
Here is an example to clarify what I mean.
We have plugin B that depends on plugin A.
In the code of the main file of plugin B it's written something like this:
<?php $plugin_B = plugin_basename( __FILE__ ); $plugin_A = 'plugin-A/plugin-A.php'; if( !in_array( $plugin_A,get_option( 'active_plugins' ) ){ deactivate_plugins( $plugin_B ) }
The option 'active_plugins' can be filtered by a mu-plugin that runs before plugin B. This means that if on a specific page the filter of 'active_plugins' returns a set of plugins without plugin A, on frontend the code above will deactivate plugin B if that specific page is visited. And it will do it globally, not just filtering the option 'active_plugins', because the function deactivate_plugins will save the option 'active_plugins' with the wrong set of active plugins.
I think the option 'active_plugins' should never be saved after visiting the frontend, but this is what the function deactivate_plugins may do in a situation like that one described in the example above.
I would just add the line if( !is_admin() ) return;
function deactivate_plugins( $plugins, $silent = false, $network_wide = null ) { if( !is_admin() ) return; //.... }