24

I'm in the process of setting up a (potentially) large multisite network, and I'm looking to make it as easy as possible now to add and configure sites when needed. I'm currently at the phase where I'm dealing with plugins.

With multisite I am aware of several different ways you can activate plugins

  • Put the plugin in /plugins, activate it on every site invidually
  • Put the plugin in /plugins, use 'network activate' to activate it on all sites
  • Put the plugin in /mu-plugins, automatically activated on every site

Now, I've been playing with the settings and I want to activate Akismet on all sites but one or two. I thought I would be able to network activate the plugin and then disable it on a single site, but I am unable to do so - if I use network activate then there is only the option to 'network deactivate' - which deactivates the plugin across all sites.

Is there a way to have the handy functionality of network activate but yet still have the convenience of being able to deactivate plugins on a site-by-site basis?

8 Answers 8

34

You can use the filter site_option_*.

E.g. the following will disable akismet on blog with id 2.

add_filter('site_option_active_sitewide_plugins', 'modify_sitewide_plugins');

function modify_sitewide_plugins($value) {
    global $current_blog;

    if( $current_blog->blog_id == 2 ) {
        unset($value['akismet/akismet.php']);
    }

    return $value;
}
10
  • 1
    +1 for providing clean, PHP-level solution which solves problem in question without need to install extra plugin -- because I'm a purity maniac and love Wordpress as clean and plugin-less as possible! :]
    – trejder
    Commented Nov 12, 2012 at 10:14
  • 2
    Dropped this code in a PHP file in mu-plugins and works like a dream!
    – bgallagh3r
    Commented Dec 4, 2015 at 12:02
  • 1
    Good to note that this won't really work in a theme. It needs to be run sooner, so mu-plugins is a great place for it. It might run as a plugin, but I would shoot for mu-plugins if that does not work either.
    – Jake
    Commented Jan 7, 2016 at 4:22
  • 2
    Also, this filter gets run a LOT, I would check if the index in the array is set before unsetting it. After the first time, it will keep trying on an array where that item doesn't exist. if ( isset($value['akismet/akismet.php']) ) { unset($value['akismet/akismet.php']); }
    – Jake
    Commented Jan 7, 2016 at 4:24
  • 1
    This is still working great on 4.9.4.
    – Jake
    Commented Feb 14, 2018 at 22:29
3

This plugin: http://firestats.cc/wiki/WPMUPluginCommander

bypasses the network activation stuff and does its own. and lets you disable the plugin on a site by site basis.

Update: Looks like this plugin breaks the sitewide tags plugin, so be careful before trying on a production network.

1
3

Here is what worked for me to disable a plugin for one particular theme on a multisite / multitheme install. I added these few lines at the top of the functions.php file in my theme:

/**
 * Disable fancybox plugin for this theme, it breaks javascript
 */
function deactivate_plugin_conditional() {
    if ( is_plugin_active('fancybox-for-wordpress/fancybox.php') ) {
        deactivate_plugins('fancybox-for-wordpress/fancybox.php');
    }
}
add_action( 'muplugins_loaded', 'deactivate_plugin_conditional' );
1
  • I am pretty sure this will only work on mu-plugins which is pretty limiting. I would do this on init like @GDR.
    – Jake
    Commented Jan 7, 2016 at 4:35
2

The active plugins are stored in the wp_[blog_id]_options in the field 'active_plugins' and 'active_sitewide_plugins' in wp_[blog_id]_sitemeta. These are serialised fields so don't edit them unless you know what you're doing.

Also take a look at wp-admin\plugin.php. It should be possible to write a plugin which will do what you want using the functions declared in there e.g. is_plugin_active() and activate_plugin().

However, I'm presupposing you are proficient in PHP which may not be the case.

2

Answers from sorich87 and user33465 didn't work for me with Wordpress 4.3. Adding this to theme's functions.php worked:

function deactivate_plugin_conditional() {
    $deactivated_plugin_name = 'lazy-load/lazy-load.php';
    deactivate_plugins($deactivated_plugin_name, false, true);
}
add_action( 'init', 'deactivate_plugin_conditional' );
4
  • I can confirm that the earlier upvoted solutions no longer work and that the solution by @gdr does in fact work.
    – user2015
    Commented Oct 23, 2015 at 3:00
  • I can confirm that @sorich87's solution works great in 4.4.1. You guys are not using it in a way that works apparently, but it still works. However, it probably can only work in mu-plugins and definitely not in the theme. This option will work in themes. But note that this forces a plugin deactivated vs sorich87's which just stops forcing it on the site, but still allows it to be used normally if desired. I prefer the latter, but they both could be useful.
    – Jake
    Commented Jan 7, 2016 at 4:31
  • Actually. @sorich87's solution method doesn't work if your site is the first site (ID: 1). If that is the case, it won't allow you to Network Activate the plugin. Any other ID appears to work.
    – Jake
    Commented Feb 20, 2018 at 5:42
  • And this method does the same thing for me. You can no longer activate the plugin(s) sitewide if this is in the theme for the site at ID = 1.
    – Jake
    Commented Feb 20, 2018 at 5:54
0

Not out of the box in WP 3, but it would be possible, I think, to override the option using the option_* filters.

Also, it would be sweet if you added the suggestion as a feature request in core.trac.wordpress.org.

0

The better way to handel all plugins in Multisite Network is "Plugin Commander" you can find here: http://wordpress.org/extend/plugins/plugin-commander/

-1

I managed to disabled the plugin but it was still there on the main site panel. The only solution I found to completly remove it from the main site was to check on the main.php of the plugin the site and disable it according to it:

global $current_blog;

// Only available to B
if( $current_blog->blog_id == 2 ) {


    define( 'AB_PATH', __DIR__ );

    include_once 'includes.php';

    //  plugin loaded stuff

    AB_Plugin::registerHooks();

    is_admin() ? new AB_Backend() : new AB_Frontend();

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.