Auto assign WP Role at registration based on Membership level?

Is there a way to automatically assign WP roles based on the Membership when a new member registers?

We're also using BuddyPress, so if not directly through Membership2 then perhaps through the BuddyPress part of it?

Thanks,
Scott

  • scottmcculloch

    I just found this on the BuddyPress forums:
    https://buddypress.org/support/topic/how-to-assign-a-wp-user-role-based-on-a-registration/

    add_action('bp_core_activated_user', 'bp_custom_registration_role',10 , 3);
    function bp_custom_registration_role($user_id, $key, $user) {
       $userdata = array();
       $userdata['ID'] = $user_id;
       $userdata['role'] = xprofile_get_field_data('Typ konta', $user_id);
    
       if ($userdata['role'] == 'User1')
          $userdata['role'] = 'subscriber';
    
       if ($userdata['role'] == 'User2')
          $userdata['role'] = 'subscriber';
    
       if ($userdata['role'] == 'User3')
          $userdata['role'] = 'contributor';
    
       //only allow if user role is my_role
       if (($userdata['role'] == "subscriber") or ($userdata['role'] == "contributor"))
          wp_update_user($userdata);
    
      }

    So it occurs to me that perhaps I would need to create a function for my needs...
    Is there a variable that's being set at registration related to the Membership level that I could use this way?
    Actually, now that I think of it, I'd need a function that also works when someone adds a membership level when already registered -- I think we may have the possibility of some membership levels that would be allowed as "additional" memberships so members would need to have new WP roles added when they sign up for a new membership whether registering for the site or are already registered.

    Scott

  • scottmcculloch

    Hi Vinod,

    Thanks for your reply.

    I've just tried your suggestion and it doesn't seem to be working quite the way I need it to.

    It appears that when a new member signs up, only the first (alphabetically) role is assigned:

    a.) Only the one role shows up in the user profile (I have WPFront User Role Editor installed so that I can create custom user roles and also assign/edit multiple - i.e., secondary - roles) -- which means I wouldn't be able to identify or filter/order by role in the "user" area.

    b.) Even though it does appear that most of the capabilities of multiple roles are being given, the user isn't fully identified as being in roles other than the first — a plugin we're using for questionnaires/assessments, WatuPRO, uses the WP roles to determine who has access to which assessments... and it's only showing those allowed by the first role assigned to the membership.

    Is it possible I've missed something? Or is assigning "roles" to memberships actually just giving them the same capabilities and not actually assigning them to the role in a way that can be used as identification by other plugins?

    Thanks,
    Scott

  • Ash

    Hello @Ward Ashman

    I hope you are well today.

    Or is assigning "roles" to memberships actually just giving them the same capabilities and not actually assigning them to the role in a way that can be used as identification by other plugins?

    Yes, you got it right, it assigns the capabilities but you won't be able to identify an user by role.

    To assign role based on membership, it will need some custom code. For example, if you want to set editor role for the membership which ID is 1343, then the code is:

    add_action( 'ms_model_relationship_create_ms_relationship_before', 'ms_controller_member_assign_memberships_done_cb', 99, 4 );
    function ms_controller_member_assign_memberships_done_cb( $membership_id, $user_id, $gateway_id, $move_from_id ) {
    	$user = new WP_User( $user_id );
    	switch( $membership_id ){
    		case 1343:
    			$user->set_role( 'editor' );
    			break;
    	}
    }

    To be precise, the following part is need to configure:

    case 1343:
    			$user->set_role( 'editor' );
    			break;

    Like:

    add_action( 'ms_model_relationship_create_ms_relationship_before', 'ms_controller_member_assign_memberships_done_cb', 99, 4 );
    function ms_controller_member_assign_memberships_done_cb( $membership_id, $user_id, $gateway_id, $move_from_id ) {
    	$user = new WP_User( $user_id );
    	switch( $membership_id ){
    		case 1343:
    			$user->set_role( 'editor' );
    			break;
    
    		case 1345:
    			$user->set_role( 'author' );
    			break;
    
    		case 1348:
    			$user->set_role( 'administrator' );
    			break;
    	}
    }

    You can add those codes in your functions.php in the theme, if you think your theme won’t be changed. Otherwise mu-plugins is the best solution. To use mu-plugins, go to /wp-content/ and find the folder with name 'mu-plugins'. If there is no folder in that name, then create a folder, name it 'mu-plugins', create a file inside that, give any name you like and paste the code in there. You don't need to activate that plugin. Mu-plugins means must use plugins, so it will be activated automatically always. If you use mu-plugins then add a php start tag at the beginning of the code.

    Hope it helps :slight_smile: Please feel free to ask more question if you have any.

    Cheers
    Ash

  • scottmcculloch

    Hi Ash,

    Is it possible to rework this code a bit so that 2 things would happen:

    1. If someone is added to multiple membership levels, they could have multiple roles assigned rather than "switching" to roles based on the most recently added membership?

    2. If someone is removed from a membership level, their role associated with that membership level is removed?

    I've installed the WPFront plugin to give the ability for users to have additional ("secondary") roles, so perhaps it could tie into that?
    Also, I'm not stuck with WPFront if there's a better solution to allow multiple roles per user that would work better with this.

    Thanks,
    Scott

  • Vinod Dalvi

    Hi Scott,

    1. If someone is added to multiple membership levels, they could have multiple roles assigned rather than "switching" to roles based on the most recently added membership?

    This is not possible in WordPress currently, as this is how the core role mapping is designed to work to assign one user role to single user to avoid overlapping user role capabilities.

    You can however customize it to your heart's content using a role management plugin such as http://wordpress.org/extend/plugins/user-role-editor/ that you are using by creating a custom role that have capabilities of both roles that you want to assign to the user and then assign this custom role to the user based on the membership level using the above provided custom code.

    2. If someone is removed from a membership level, their role associated with that membership level is removed?

    The role is not assigned to the membership level but to the member / user so if you delete the member / user then role association with that user also gets removed.

    Regards,
    Vinod Dalvi

  • scottmcculloch

    Hi Vinod,

    Thanks for your response.

    Re: #1 -- that's kind of what I expected.

    Re: #2 -- actually, what I meant was not that the role be removed from the system, but rather that the role be removed from the user, or I suppose more accurately stated that when a user is removed from a membership level, the user's role be changed back to "subscriber" or "visitor". It occurs to me that perhaps the way to do that is to have a default membership set up and when we removed someone from a higher membership level we add them to the default, and use the code provided by Ash to set the role to "subscriber" when the user is added to that default membership.

    Thanks,
    Scott

  • scottmcculloch

    Hi Ash,

    Yes, in any of those cases, I suppose. For our current usage, there will be no expiry of memberships, so really it would only be if a user was removed from a membership level by an admin.

    That's why I was thinking we might just add something like this:

    add_action( 'ms_model_relationship_create_ms_relationship_before', 'ms_controller_member_assign_memberships_done_cb', 99, 4 );
    function ms_controller_member_assign_memberships_done_cb( $membership_id, $user_id, $gateway_id, $move_from_id ) {
    	$user = new WP_User( $user_id );
    	switch( $membership_id ){
    		case 1343: //membership level 1
    			$user->set_role( 'client-level1' );
    			break;
    
    		case 1345: //membership level2
    			$user->set_role( 'client-level2' );
    			break;
    
    		case 1348: //membership level "default"
    			$user->set_role( 'visitor' );
    			break;
    	}
    }

    Then we just make sure that any time we remove someone from "membership level1" or "membership level2" we remember to add them to "membership level 'default'". If we're manually removing them from membership anyway, it's no big deal to add them to the "default" level with basically subscriber/visitor level access, etc.

    Of course, this doesn't work if later we decide to add some membership types that do expire (e.g., if we open our platform to the "public" instead of just existing clients).

    Scott

  • James

    Well... I take it back... Here is how I fixed that issue on my end... I went ahead and created the default membership, even though I initially believed I would not need it because I have a free membership available... I then set up the role for a default membership and modified the code above with the Case ID and role for the default membership. Now when someone clicks on a membership and then cancels their payment it does not give them access anymore... And it sets their role to what I want... FREE!!! Hacking back against hackers... This plugin still needs a lot of work.

  • Vinod Dalvi

    Hi Scott,

    Regarding removing user roles from the users when we remove membership from them, we can achieve this using various following membership plugin hooks.

    The following hooks can be used to remove user role on cancelling the user membership.

    ms_model_relationship_cancel_membership_before
    ms_model_relationship_cancel_membership_after

    The following hooks can be used to remove user role on deactivating the user membership.

    ms_model_relationship_deactivate_membership_before
    ms_model_relationship_deactivate_membership_after

    I think the hook ms_model_relationship_cancel_membership_after will be useful for us as it's better to remove the user role after removing the membership and not before removing the membership.

    So to achieve this you can use the following custom code.

    function func_ms_model_relationship_cancel_membership_after( $ms_model_relationship, $generate_event ){	
    
    	$user = new WP_User( $ms_model_relationship->user_id );
    	switch( $ms_model_relationship->membership_id ){
    		case 1343: //membership level 1
    			$user->set_role( 'client-level1' );
    			break;
    
    		case 1345: //membership level2
    			$user->set_role( 'client-level2' );
    			break;
    
    		case 1348: //membership level "default"
    			$user->set_role( 'visitor' );
    			break;
    	}
    }
    add_action('ms_model_relationship_cancel_membership_after', 'func_ms_model_relationship_cancel_membership_after', 10, 2);

    In the above code please change the user role and membership ids appropriately.

    Best Regards,
    Vinod Dalvi

  • scottmcculloch

    Okay, thanks Vinod.

    Let's see if I've got this right...

    If I want to do 2 things:
    1. when a user is added to a membership level, change their role to something other than "visitor"
    2. when a member is removed from a membership level, change their role to "visitor"

    then this code achieves both aims:

    add_action( 'ms_model_relationship_create_ms_relationship_before', 'ms_controller_member_assign_memberships_done_cb', 99, 4 );
    function ms_controller_member_assign_memberships_done_cb( $membership_id, $user_id, $gateway_id, $move_from_id ) {
    	$user = new WP_User( $user_id );
    	switch( $membership_id ){
    		case 1343: //membership level 1
    			$user->set_role( 'client-level1' );
    			break;
    
    		case 1345: //membership level2
    			$user->set_role( 'client-level2' );
    			break;
    
    		case 1348: //membership level "default"
    			$user->set_role( 'visitor' );
    			break;
    	}
    }
    
    function func_ms_model_relationship_cancel_membership_after( $ms_model_relationship, $generate_event ){	
    
    	$user = new WP_User( $ms_model_relationship->user_id );
    	switch( $ms_model_relationship->membership_id ){
    		case 1343: //membership level 1
    			$user->set_role( 'visitor' );
    			break;
    
    		case 1345: //membership level2
    			$user->set_role( 'visitor' );
    			break;
    
    	}
    }
    add_action('ms_model_relationship_cancel_membership_after', 'func_ms_model_relationship_cancel_membership_after', 10, 2);

    I think I'm reading that right.

  • Vinod Dalvi

    Hi Scott,

    1. when a user is added to a membership level, change their role to something other than "visitor"

    Yes according to your shared code it will set the user role to 'client-level1' for the member having membership id as 1343 and the user role 'client-level2' for the member having membership id as 1345 but for the member having membership id as 1348 will have 'visitor' role.

    2. when a member is removed from a membership level, change their role to "visitor"

    Yes but only for the members who have removed from the membership levels having membership id as 1343 or 1345.

    Regards,
    Vinod Dalvi

  • Ash

    Hi @scottmcculloch

    Just adding my 2 cents here :slight_smile:

    If you want to assign subscriber role on removal of all membership, you can use this following code too:

    add_action( 'ms_model_event', 'my_event_handler', 10, 2 );
    
    /**
     * Handles an event and process the correct communication if required.
     *
     * @param  MS_Model_Event $event The event that is processed.
     * @param  mixed $data The data passed to the event handler.
     */
    function my_event_handler( $event, $data ) {
    	$member = false;
    	$subscription = false;
    	$membership = false;
    
    	switch ( $event->type ) {
    		case MS_Model_Event::TYPE_MS_CANCELED:
    			// A membership was cancelled - either by Admin or by the member.
    			// No more payments will be made but member has access until current period ends.
    			$subscription = $data;
    			$membership = $data->get_membership();
    			$member = $subscription->get_member();
    			assign_default_role( $member->id );
    			break;
    		case MS_Model_Event::TYPE_MS_DEACTIVATED:
    			// A membership was permanently deactivated. Member has no access anymore.
    			$subscription = $data;
    			$membership = $data->get_membership();
    			$member = $subscription->get_member();
    			assign_default_role( $member->id );
    			break;
    	}
    
    }
    function assign_default_role( $user_id = 0 ){
    	$user = new WP_User( $user_id );
    	$user->set_role( 'subscriber' );
    }

    I didn't test either of these code, so if in case Vinod's code doesn't work, give the above code a try.

    Cheers
    Ash

  • Vinod Dalvi

    Hi James,

    If it doesn't work for you using latest Membership plugin then to help keep support tickets separate, could you please open a new thread for your new question https://premium.wpmudev.org/forums/#question

    You can also include reference of this thread in your newly created thread if you want to.

    This helps to prevent any confusion (for us) as I'm sure you understand. It also means the member who started this thread or anyone following it isn't inundated with post notifications each time we respond to each other. A lengthy thread could annoy the original.

    We would be more than happy to help you on your new thread :slight_smile:

    Cheers,
    Vinod Dalvi

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.