2

How can I have specific plugins only active for one specific user role (or potentially an array of user roles)?

Is there something I can add to my functions.php in the child theme to only use a specific plugin for a specific user role?

I have tried various answers from here and articles but nothing seems to offer what I need.

Update:

I've tried the below code (as a test) and it works in that if an admin accesses the site it disables the plugin, but once it's disabled it stays disabled for everyone. It needs to asses the current user and activate or reactivate depending on their role.

add_filter( 'option_active_plugins', 'custom_plugin_load_filter' );
function custom_plugin_load_filter( $plugins ) {
    $user = wp_get_current_user();
    if ( in_array( 'administrator', (array) $user->roles ) ) {
        //unset( $plugins['additional-order-confirmation-email/additional-order-confirmation-email.php'] ); // change my-plugin-slug
         $key = array_search( 'additional-order-confirmation-email/additional-order-confirmation-email.php' , $plugins );
            if ( false !== $key ) {
                unset( $plugins[$key] );
            }

    }
    return $plugins;
}   

If I change it to !in_array it remains active for admin users (correct) but also for guests (incorrect).

8
  • Could I use a variation of this answer? wordpress.stackexchange.com/a/160802/117919
    – Lyall
    Jan 17, 2020 at 16:42
  • No. You wouldn't entirely disable the plugin based on the user role. Instead you'd perform that check just before the relevant functionality executes. Judging by the name of the plugin, that would be when the email is triggered. Also keep in mind that if this is for sending confirmation emails, and those emails can be triggered by back-end activity, the 'current user' is not necessarily the customer. So you wouldn't even be checking the user role, it would be the customer role. 3rd-party plugins are off-topic here anyway, so this is something you should ask the original author. Jan 17, 2020 at 16:44
  • @JacobPeattie the name might be misleading - the plugin adds an additional (mandatory) billing field to the checkout which adds an additional recipient to the order confirmation and completed emails. I only want the additional billing email field (added by the plugin along with an additional html area in the checkout page) to be there based on the role of the logged in user. Unfortunately the original author isn't available at the moment so I will try and figure out :)
    – Lyall
    Jan 17, 2020 at 18:57
  • @JacobPeattie Also I didn't realise 3rd-party plugins were off topic as I don't usually post here, should I remove the question? Thanks
    – Lyall
    Jan 17, 2020 at 19:35
  • 1
    @Lyall Just be aware of the way you ask your question, this question is not really off-topic as you are asking about how to conditionally load a plugin in general. But if you were asking for specific changes to within a 3rd party plugin that would be.
    – majick
    Jan 17, 2020 at 22:13

3 Answers 3

2

It's not a good idea to modify plugins if you can help it, as the plugin may be upated and you will lose your changes and need to redo them.

Fortunately, that is not necessary in this case anyway, as you can the filter active plugins option instead. You will need the plugin slug for this:

add_filter( 'option_active_plugins', 'custom_plugin_load_filter' );
function custom_plugin_load_filter( $plugins ) {
    $user = wp_get_current_user();
    if ( !in_array( 'sales_events', (array) $user->roles ) ) {
        unset( $plugins['my-plugin-slug'] ); // change my-plugin-slug
    }
    return $plugins;
}

Note as this will run on the plugins page also, it will probably prevent anyone without the role from disabling the plugin (as it will appear to be inactive to them.)

12
  • Thanks, I will try this!
    – Lyall
    Jan 19, 2020 at 15:12
  • The other way would be to switch the logic around, have the plugin inactive and add the slug to the plugin array if the user has the role. Either should work.
    – majick
    Jan 20, 2020 at 1:26
  • I can't seem to get this to work, for the slug I've tried the folder name, Plugin Name and Text Domain but the plugin features are still visible as a guest. The role ID is definitely sales_events and the role display name is Sales (Events). Any ideas?
    – Lyall
    Jan 20, 2020 at 13:59
  • 1
    it's actually the folder name and filename combined. eg. akismet/akismet.php ... you can mouse over a plugin action link in the admin plugins page and look at the plugin field in the URL. eg. ?action=activate&plugin=akismet%2Fakismet.php because %2F = / when URL-encoded.
    – majick
    Jan 21, 2020 at 6:45
  • Thank you - it still doesn't appear to be working. I changed the role to customer in case that's an issue, but it still shows in checkout for admin users and guests. Example link URL is ...wp-admin/plugins.php?action=deactivate&plugin=additional-order-confirmation-email%2Fadditional-order-confirmation-email.php&plugin_status=all&... so I used the slug additional-order-confirmation-email/additional-order-confirmation-email.php
    – Lyall
    Jan 21, 2020 at 10:34
0

This is an answer based on the term "Executing plugin" in your question title.

If you just want to run/execute a plugin for user roles, you don't need to prevent it from loading. My solution is to let WordPress load your plugin and manage it in your plugin.

So, you could have codes like this:

// In the main plugin file that loads and initiate plugin functionalities.

if ( ! current_user_can( 'manage_options' ) ) {
    return;
}

include 'plugin-file.php';
new myPlugin();

By using this solution, your plugin is active for all users, but it actually works only for users with manage_options capability.

It will not make plugin Inactive for some users, but it is a clean solution to run functionality (Execute) only for some users.

4
  • I like this idea a lot, thanks! But is there a way to use the name of the role rather than current_user_can? The reason I ask is that I have some sites with several different roles all basically copies of the 'Customer' role, but each one can do different things, has different payment gateways, sees different products etc. I only need a plugin to show for one of those roles.
    – Lyall
    Jan 25, 2020 at 15:26
  • @Lyall You can use user role instead of capability in current_user_can function. Like: current_user_can( 'administrator' ).
    – Hector
    Jan 25, 2020 at 18:02
  • Unfortunately you cannot do that, because the current user is set after plugins and themes have already been loaded, so the function current_user_can() would throw and error.
    – d79
    Feb 18, 2022 at 23:45
  • You could do it this way, put only this inside your main plugin file: add_action('init', function(){ current_user_can('manage_options') && require 'main-plugin-functions.php'; });, where main-plugin-functions.php is the file with all your plugin's core functions.
    – d79
    Feb 19, 2022 at 0:58
0

I had a similar problem and used @majick's code after some modification:

add_filter( 'option_active_plugins', 'custom_plugin_load_filter' );
function custom_plugin_load_filter( $plugins ) {
    $user = wp_get_current_user();
    if ( !in_array( 'sales_events', (array) $user->roles ) ) {
        $index = array_search( 'plugin-name/plugin-file.php', $plugins );
        unset( $plugins[ $index ] );
        $plugins = array_values( $plugins );
    }
    return $plugins;
}

To find out the plugin name/path, right-click the activate or deactivate link of the plugin (WP-Admin > Plugins > Installed Plugins list) and paste it in a URL decoder like this one and use the value in the "plugin=" parameter.

Your Answer

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

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