JetPack is constantly being updated, and it tends to introduce some really cool new features fairly often. However, occasionally, those new features can cause major issues in large multisite environments.
There are a handful of plugins out there that let you gain some control over JetPack’s features. Most of them, though, such as Manual Control for JetPack, are simply designed to stop JetPack from auto-activating new features. That’s handy, but it’s not always going to fix the issue you’re encountering.
Earlier this week, JetPack began to wreak havoc on the UMW website. For a lot of installations, the new Protect module can add some cool security features to your site. However, in an environment where the administration area is locked down to a handful of IP addresses that are shared across the institution, it can actually lock out most of your users at once.
Once the reports started rolling in, telling me that user after user was unable to login because their IP address had been flagged, I knew I had to do something quickly.
After a bit of research, I found a nice way to get better control over JetPack.
Filtering Default Modules
To begin with, we need to get control over which modules JetPack auto-activates when the plugin itself is activated for the first time. To do so, we’ll hook into the `jetpack_get_default_modules` filter. This filter sends you an numerically-indexed array of module slugs. You can then remove any modules you don’t want auto-activated from that array.
Filtering Available Modules
The next step is to filter the list of available modules. If you don’t want your users to be able to activate certain features within JetPack, you can hide specific modules from them by hooking into the `jetpack_get_available_modules` filter. This filter sends you an associative array, where the module slugs are the keys, and each array value is an object containing a lot of information about that module.
Deactivating Modules Systematically
The tricky part, though, for us, was the fact that the Protect module had already been auto-activated on a lot of our sites. We needed to find a way to deactivate it systematically without having to pour through each individual site. To do that, we need to retrieve a list of all of the active modules, filter that list to remove any modules we want deactivated, and then update the database with the new list of active modules.
In our case, I decided to take a blacklist approach; I set up a list of modules I wanted to eradicate from our site, and then removed them. On the one hand, whenever a fancy new auto-activated module rolls out with a new version of JetPack, it will automatically be available to our users without me having to change any of my code; on the other hand, if that module is another one we don’t want on our site, I will need to edit my code.
Putting It All Together
I’ve packaged it all together in a mu-plugin. Feel free to visit and/or fork my Git repository for the plugin and use it as you see fit. Essentially, it works like this:
- I hook into the appropriate actions (`init` to force-deactivate modules) and filters (`jetpack_get_default_modules` and `jetpack_get_available_modules`) within the `__construct` method for my plugin class
- I built a method that returns the array of module slugs I want to block
- I filter the default module list by creating an empty array, looping through the original array of default modules, comparing them to my array of blocked modules, then adding them to my new empty array if their handles weren’t found in my blocked array. I then return the new array of modules.
- I filter the available module list in a very similar manner to the default module list.
- I force-deactivate my blocked modules by using `Jetpack_Options::get_option( ‘active_modules’, array() )` to retrieve the current list of active modules. Then, I use `array_diff` to remove any modules that are in my block list, and then use `Jetpack_Options::update_option()` to update the list of active modules. It should be noted that a similar method could be used to force-activate JetPack modules, if you had the desire to do so.
As an aside, I have found that, although we’re blocking the “Site Management” module from the list of available modules, the nag still appears asking you to activate it on new sites (in two different places – the main admin dashboard, shown in the first screen shot below, and on the JetPack Settings page, shown in the second screen shot below). It seems odd that it should appear (and it may be a bug), but it does. I’m currently looking into ways to disable that nag.
See the bottom of this post for information about how I fixed this issue.
Much of the code I put together was inspired by a blog post from Jeremy Herve on the subject. However, his blog post didn’t really elaborate on how to force-deactivate the JetPack modules. For that, I found a little inspiration in one of Jeremy’s Gists, and then dug through the JetPack code to see how best to scale it.
I was able to get rid of the “Manage” nag on the dashboard and JetPack Settings pages by hooking into the `can_display_jetpack_manage_notice` filter and returning false.