Deactivate Specific Plugins on Production Sites

Deactivate Specific Plugins On Production Sites Snipsnip Pro .code Snippets

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.

What it does…

The code snippet provides a way to deactivate certain plugins on production environments. It checks the current site environment and deactivates the specified plugins if the site is considered a production site. This helps prevent unnecessary plugins from running, improving the overall performance and security of the website.

Why it does it…

Deactivating plugins on production sites is beneficial for several reasons. First, it reduces the number of active plugins, which can improve website performance by reducing resource usage. Second, it minimizes the potential security risks associated with running unnecessary or outdated plugins. By deactivating specific plugins on production sites, you can ensure that only essential and up-to-date plugins are active, enhancing both performance and security.

How it does it…

– The code snippet defines a class called `Deactivate_Plugins_On_Production`, which selectively deactivates plugins on production environments.
– The class has a private property called `$stagingKeywords`, which contains a list of keywords that indicate a staging environment.
– There is also a private property called `$forceDeactivations`, which can be set to `true` to deactivate plugins regardless of environment detection.
– The code snippet includes a constant called `PLUGINS_TO_DEACTIVATE_ON_PRODUCTION`, which lists the slugs of the plugins you want to deactivate on production.
– The class constructor checks if the force deactivations flag is set or if the site is detected as a production site. If either condition is true, it adds a filter to deactivate the specified plugins.
– The class has a private method called `isProductionSite()`, which determines if the current site environment is production by checking if the site URL contains any of the staging keywords.
– The class also has a public method called `deactivatePluginsOnProduction()`, which takes the list of currently active plugins and deactivates the specified plugins on production. It uses regular expressions to match plugin slugs and removes the matching plugins from the list.

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…