• Bedrock

How to Disable Plugins on Certain Environments

1. Edit config

First of all, we have to define the plugins we would like to disable. Let’s use an array stored in constant for that purpose.

In my case, I would like to disable Autoptimize (file minification) and WP Super Cache (page caching) on my local environment:

define('DEV_DISABLED_PLUGINS', serialize([
    'autoptimize/autoptimize.php',
    'wp-super-cache/wp-cache.php'
]));

Place the code above in config/environments/<environment>.php — in my case, development.php.

2. Create mu-plugin

Now we need to actually do the disabling part. There are few ways to do it but the most common one is to leverage the option_active_plugins filter. This method is still valid even though it was first used many years ago.

Create web/app/mu-plugins/my-plugin-disabler.php with:

<?php
/*
Plugin Name: Simple Environment plugin disabler
Description:  Disables plugins based on environment settings.
Author: Kamil Grzegorczyk
Version: 0.1
*/

if (defined('DEV_DISABLED_PLUGINS')) {
    $plugins_to_disable = unserialize(DEV_DISABLED_PLUGINS);

    if (!empty($plugins_to_disable) && is_array($plugins_to_disable)) {
        require_once(dirname(__FILE__) . '/vendor/DisablePlugins.php');
        $utility = new DisablePlugins($plugins_to_disable);

        //part below is optional but for me it is crucial
        error_log('Locally disabled plugins: ' . var_export($plugins_to_disable, true));
    }
}

So far so good right? We created mu-plugin and checked if we have defined any plugins to be disabled.

Inside the IF statement, we use the magical utility called DisablePlugins but we did not define that anywhere so let’s fix that.

Add DisablePlugins utility

Years ago Mark Jaquith, one of the WP Core developers, wrote a small utility to disable plugins using the option_active_plugins filter.

Even though it was created 7 years ago it will be more than enough in our scenario. And we want to be a smart developer who does not need to reinvent the wheel, right?

While still being in the mu-plugins directory please create a vendor subdirectory and paste the following contents to into web/app/mu-plugins/vendor/DisablePlugins.php:

<?php
/**
 * Plugin disabling engine class
 * Author: Mark Jaquith
 * Author URI: http://markjaquith.com/
 * Plugin URI: https://gist.github.com/markjaquith/1044546
 * Using fork: https://gist.github.com/Rarst/4402927
 */

class DisablePlugins
{
    public static $instance;
    private $disabled = [];

    /**
     * Sets up the options filter, and optionally handles an array of plugins to disable
     * @param array $disables Optional array of plugin filenames to disable
     */
    public function __construct(array $disables = null)
    {
        /**
         * Handle what was passed in
         */
        if (is_array($disables)) {
            foreach ($disables as $disable) {
                $this->disable($disable);
            }
        }

        /**
         * Add the filters
         */
        add_filter('option_active_plugins', [$this, 'do_disabling']);
        add_filter('site_option_active_sitewide_plugins', [$this, 'do_network_disabling']);

        /**
         * Allow other plugins to access this instance
         */
        self::$instance = $this;
    }

    /**
     * Adds a filename to the list of plugins to disable
     */
    public function disable($file)
    {
        $this->disabled[] = $file;
    }

    /**
     * Hooks in to the option_active_plugins filter and does the disabling
     * @param array $plugins WP-provided list of plugin filenames
     * @return array The filtered array of plugin filenames
     */
    public function do_disabling($plugins)
    {
        if (count($this->disabled)) {
            foreach ((array)$this->disabled as $plugin) {
                $key = array_search($plugin, $plugins);
                if (false !== $key) {
                    unset($plugins[$key]);
                }
            }
        }

        return $plugins;
    }

    /**
     * Hooks in to the site_option_active_sitewide_plugins filter and does the disabling
     *
     * @param array $plugins
     *
     * @return array
     */
    public function do_network_disabling($plugins)
    {
        if (count($this->disabled)) {
            foreach ((array)$this->disabled as $plugin) {
                if (isset($plugins[$plugin])) {
                    unset($plugins[$plugin]);
                }
            }
        }

        return $plugins;
    }
}

Conclusion

It wasn’t so scary was it?

Now you can use that solution in any environment you wish, you can even place it into your production config file if that fits your scenario.

Take care!

Originally posted at https://kamilgrzegorczyk.com/2018/05/02/how-to-disable-plugins-on-certain-environment/

Join the discussion on Roots Discourse

Join over 5,800 subscribers on our newsletter to get the latest Roots updates, along with occasional tips on building better WordPress sites.

Looking for WordPress plugin recommendations, the newest modern WordPress projects, and general web development tips and articles?

“Easily the best WordPress email I get.” Colin OBrien

Follow us on Twitter @rootswp

Ready to checkout?