Managing plugins in a WordPress Multisite setup can be a bit tricky, especially when you need certain plugins to be available only to superadmins. This guide will walk you through the steps to disable specific plugins for non-admin users while keeping them active for superadmins.
Why Would You Want to Disable Plugins for Non-Admin Users?
In a WordPress Multisite environment, you might have plugins like file managers or backup tools that are essential for site maintenance but not necessary for regular users. Restricting access to these plugins can enhance security and prevent accidental changes.
Understanding WordPress Hooks
WordPress hooks, comprising actions and filters, are a powerful feature that allows developers to modify the default behavior of WordPress. These hooks can be leveraged to load or disable plugins conditionally.
Key Hooks for Plugin Management
- Regular WordPress site:
option_active_plugins
- WordPress Multisite:
site_option_active_sitewide_plugins
Creating the Deactivation Plugin
To deactivate certain plugins for non-admin users, you need to create a mu-plugin. MU-plugins (Must Use plugins) are automatically enabled on all sites in the network and cannot be deactivated from the WordPress admin dashboard.
Step-by-Step Guide:
- Create the Plugin File:
- Create a file named
000_wpsandbox_dyn_plugin_deactivator.php
. - Place this file in the
/wp-content/mu-plugins/
directory. If themu-plugins
directory does not exist, you need to create it.
- Create a file named
- Add the Following Code to the Plugin File:
<?php
/**
* Plugin Name: WPSandbox Dynamic Plugin Deactivator for Non-SuperAdmin Users
* Plugin URI: https://wpsandbox.net/1195
* Description: This system plugin dynamically/temporarily deactivates some plugins for non-admin users. Important: Must be installed in the mu-plugins folder in order to start early.
* Version: 1.0.0
* Author: Svetoslav Marinov (Slavi)
* Author URI: http://WPSandbox.net
* Text Domain: wpsandbox
*/
$plugin_deactivator_obj = new WPSandbox_Dynamic_Plugin_Deactivator();
add_action('plugins_loaded', [ $plugin_deactivator_obj, 'installHooks' ] );
/**
* @author Svetoslav Marinov | https://WPSandbox.net
*/
class WPSandbox_Dynamic_Plugin_Deactivator {
// List of SuperAdmin users that are allowed to access all plugins
// specify which usernames are allowed to access the plugins in the array below OR leave empty to check for super admin access
private $super_admin_users_arr = [
// add a username here
];
private $allowed_plugins_for_admins_users_only = [
'akismet/akismet.php',
'hello-dolly/hello.php',
];
function installHooks() {
if (is_multisite()) {
add_filter('site_option_active_sitewide_plugins', [ $this, 'maybeDeactivatePlugin' ] );
} else {
add_filter('option_active_plugins', [ $this, 'maybeDeactivatePlugin' ] );
}
}
/**
* This method does the actual work to determine which plugins to deactivate.
* You need to
* @param array $plugins_arr
* @return array
*/
function maybeDeactivatePlugin($plugins_arr) {
static $mem_data = [];
if (!function_exists('wp_get_current_user')) {
return $plugins_arr;
}
$user_obj = wp_get_current_user();
if (empty($user_obj->user_login)) { // can't find username for some reason
return $plugins_arr;
}
try {
$cur_username = $user_obj->user_login;
$plugins_copy = $plugins_arr;
ksort($plugins_copy); // ensure consistency by sorting by keys JIC
$hash_inp = [ 'u' => $cur_username, 'p' => $plugins_copy, ];
$hash = sha1(serialize($hash_inp));
// this function is called multiple times, so we cache the result in memory because we like speed.
if (isset($mem_data[$hash])) {
$plugins_arr = $mem_data[$hash];
return $mem_data[$hash];
}
// If current user is in the list, return plugins as is
// Superadmins are allowed to access all plugins
if ( empty( $this->super_admin_users_arr ) ) { // no users defined so checking for super admin
if ( is_super_admin() ) {
return $plugins_arr;
}
} else if ( in_array($cur_username, $this->super_admin_users_arr ) ) {
return $plugins_arr;
}
// Plugins to be allowed for admin users only (from array above)
$allowed_plugins_for_admins_users_only = $this->allowed_plugins_for_admins_users_only;
if (empty($allowed_plugins_for_admins_users_only)) {
return $plugins_arr;
}
// Unset plugins if conditions are met
foreach ($allowed_plugins_for_admins_users_only as $plugin) {
if (isset($plugins_arr[$plugin])) {
unset($plugins_arr[$plugin]);
}
}
} finally {
$mem_data[$hash] = $plugins_arr;
}
return $plugins_arr;
}
}
Code Explanation
The provided PHP code is a WordPress Must-Use (MU) Plugin designed to dynamically deactivate specific plugins for non-superadmin users or those not present in a specific list (don’t have to be superadmins). This ensures that only superadmins have access to certain plugins, enhancing security and control within a WordPress Multisite environment.
Explanation of the Class and Methods
Properties:
$super_admin_users_arr: An array of usernames who are allowed to access all plugins. If left empty, the script checks for super admin status.
$allowed_plugins_for_admins_users_only: An array of plugin paths that should be deactivated for non-superadmin users.
Caching: The results are cached in memory to avoid redundant processing and improve performance