WordPress Admin Plugins

How to Disable Some WordPress Plugins for Non-Admin Users in WordPress (Multisite)

Do you need a learn WordPress? Learn by doing now!

Sharing is caring!

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:

  1. 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 the mu-plugins directory does not exist, you need to create it.
  2. 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

Sharing is caring!

Do you need a learn WordPress? Learn by doing now!
This code shared in this post/site is provided "AS IS" without any warranties or guarantees of any kind. The authors and distributors of this code cannot be held responsible for any damage, data loss, or other issues that may arise from its use. It is strongly recommended that you test this code in a staging environment before deploying it to a live site. Always ensure you have proper backups and understand the implications of running this code on your WordPress installation. Use at your own risk.

Leave a Comment

Your email address will not be published. Required fields are marked *