Categories
How To

Protect My Plugins, Please

Managing sites involves managing plugins. No. Not like that.

I have a site that literally requires a specific plugin always be active for things to work. It has a lot of very complicated code, and two things must never ever happen to this:

  1. It should never be disabled
  2. It should never be updated by WordPress

Well. Okay. Let’s do that.

A Caveat A Caveat

If you don’t have a way in place to update and secure the plugin you’re hiding, DON’T DO THIS. Once you hide it, people won’t know to update it and, in fact, won’t be able to. Because you’re also preventing traditional updates. In my case, I have a git repository that triggers a push (plus some other magic).

Again. Unless you’ve got something set up to handle updates, don’t do this.

Now let’s do this.

Top ↑

Never Disable Me (by Hiding) Never Disable Me (by Hiding)

To do this, we need to know the folder name and filename of the plugin, such as ‘my-plugin/my-plugin.php. If you want to hide the plugin you've put the code in, you can useplugin_basename( FILE )` instead, which is what I’ve done.

add_action( 'pre_current_active_plugins', 'mysite_hide_my_plugins' );
function mysite_hide_my_plugins() {
	global $wp_list_table;

	$hide_plugins = array(
		plugin_basename( __FILE__ ),
	);
	$curr_plugins = $wp_list_table->items;
	foreach ( $curr_plugins as $plugin => $data ) {
		if (in_array( $plugin, $hide_plugins ) ) {
			unset( $wp_list_table->items[$plugin] );
		}
	}
}

If you were writing a plugin to hide a lot of things, you would change the array to list all of them. But since this is a ‘hide myself’ deal, it’s easier to put it in the plugin itself.

The added bonus to making the file path dynamic is that if someone gets clever and renamed the folder or file, it would still work. Neener.

Top ↑

Stop My Updates Stop My Updates

Now this one again is easier if you put it in the plugin you’re disabling updates for, because again you can use plugin_basename( __FILE__ ) to detect the plugin. If you’re not, then you’ll need to make an array of names. But that should get you started.

add_filter( 'http_request_args', 'mysite_disable_my_plugin_update', 10, 2 );
function mysite_disable_my_plugin_update( $return, $url ) {
	if ( 0 === strpos( $url, 'https://api.wordpress.org/plugins/update-check/' ) ) {
		$my_plugin = plugin_basename( __FILE__ );
		$plugins   = json_decode( $return['body']['plugins'], true );
		unset( $plugins['plugins'][$my_plugin] );
		unset( $plugins['active'][array_search( $my_plugin, $plugins['active'] )] );
		$return['body']['plugins'] = json_encode( $plugins );
	}
	return $return;
}

Top ↑

What Does It Look Like? What Does It Look Like?

Nothing, really. You’ve hidden everything. Congratulations. Now you don’t have to worry about admins or WordPress updating your plugin. Or worse.

4 replies on “Protect My Plugins, Please”

An MU plugin isn’t tied directly to this plugin, which makes it appropriate for preventing updates on multiple plugins and not really one single plugin. If you were, say, deploying your plugin to clients, making it self contained is the wiser option.

Completely agree with you about mu plugin for multiple plugins. Do you see any advantage of this approach other than being self contained over the plugin(Say I am using a loader like https://github.com/bueltge/must-use-loader to keep things more streamlined). This is a very interesting approach, I am a bit curious as it sends the plugin in incognito mode which may be a cause of concern for future developer.
Btw, I do see that your approach is way better on a multisite when only activating for some of the sites.

I wouldn’t use a loader. I write a main ‘mu-plugin’ file (call it my-site-name.php) and in there I include the files in a folder I want to use. Basically I treat it like a giant, single plugin. Loaders make assumptions that may not fit with how other people are using MU plugins, so there’s a higher probability of conflicts.

This site is a multisite and I have a check “If site 1, load this. If site 2, this. ALL sites, these.” Yes in an MU plugin 🙂

Comments are closed.