Ever wanted to have some plugins active on your Staging site but automatically deactivated on your Live or Production site? Yeaaaa! Meeee! Tooo! This makes it easy to do that. I kept having an issue where the Query Monitor plugin was conflicting with another plugin… but ONLY on the Production WordPress site. Very weird. Very frustrating. Until I used this to automatically deactivate the specific plugins I listed… it saved me from having to login to the site after every time we pushed our Staging site to Production! This script assumes that every site is Production unless the site’s domain contains one of the `$stagingKeywords` (which you can customize) and automatically deactivates the plugins you put in the `PLUGINS_TO_DEACTIVATE_ON_PRODUCTION` list. And if you need the reverse functionality, then check out Deactivate_Plugins_On_Staging.
Deactivate Specific Plugins on Production Sites

See the code…
<?php
/**
* Deactivate Specific Plugins on Production Sites [SnipSnip.pro] - https://snipsnip.pro/s/825
*/
if (!class_exists('Deactivate_Plugins_On_Production')) {
/**
* Selectively deactivates plugins on production environments.
*/
class Deactivate_Plugins_On_Production {
private $stagingKeywords = ['staging', 'dev', 'local', 'test', 'sandbox', 'demo'];
private $forceDeactivations = false; // Set to true to deactivate regardless of environment detection.
// List the slugs of plugins you want to deactivate on production
const PLUGINS_TO_DEACTIVATE_ON_PRODUCTION = [
'query-monitor',
'create-block-theme',
'ai-engine*'
];
public function __construct() {
// Apply deactivations if forced or if the site is detected as a production site.
if ($this->forceDeactivations || $this->isProductionSite()) {
add_filter('option_active_plugins', [$this, 'deactivatePluginsOnProduction']);
}
}
/**
* Determines if the current site environment is production by not matching any of the specified staging keywords.
*
* @return bool True if the environment is considered production.
*/
private function isProductionSite() {
$currentUrl = strtolower(get_option('siteurl'));
foreach ($this->stagingKeywords as $keyword) {
if (strpos($currentUrl, $keyword) !== false) {
return false;
}
}
// If none of the staging keywords are found, it's considered a production environment.
return true;
}
/**
* Deactivates the specified plugins by filtering them out from the list of active plugins in production environment.
*
* @param array $activePlugins The list of currently active plugins' file paths.
* @return array The modified list with specific plugins deactivated on production.
*/
public function deactivatePluginsOnProduction($activePlugins) {
foreach (self::PLUGINS_TO_DEACTIVATE_ON_PRODUCTION as $pluginPattern) {
$pattern = strtolower($pluginPattern);
if (strpos($pattern, '*') !== false) {
$pattern = str_replace('*', '.*', $pattern);
$activePlugins = array_filter($activePlugins, function($plugin) use ($pattern) {
$pluginSlug = strtolower(substr($plugin, 0, strpos($plugin, '/')));
return !preg_match('/^' . $pattern . '$/', $pluginSlug);
});
} else {
$pluginPath = $pattern;
$key = array_search("$pluginPath/$pluginPath.php", $activePlugins);
if ($key !== false) {
unset($activePlugins[$key]);
}
}
}
return array_values($activePlugins); // Ensure the array is correctly indexed after modifications
}
}
new Deactivate_Plugins_On_Production();
}
See the code on github…