Membership roles & capabilities issue

When the Member Capabilities addon is enabled in Membership, and a role assigned to a membership under Protection Rules > User Roles, only the capabilities associated with that role are given to the member, not the actual role itself.

This creates a problem for use as we are using the Dynamic Pricing plugin with WooCommerce to offer discounts to users with a custom role created with User Role Editor. But as Membership dos not actually give that role to the member, they don't get the product discounts to which they are entitled as members.

Is there any way this default behavior can be modified so the role we select can be given to the member instead of just the capabilities?

  • Adam Czajczyk

    Hello Ellis Benus

    I apologize for the delay on our end. Usually we respond much faster but sometimes there are exceptional days of "higher load" when slight delays occur. I'm sorry for keeping you waiting.

    As for the issue. This is actually how the plugin works. The "Member Capabilities" add-on does not change user role but, like you noticed, assigns "role specific" capabilities to a member. The add-on can work in two "modes", which you can switch by going to "Membership 2 -> Add-ons" page and entering "Details" for "Member Capabilities" add-on:

    - the default one where all the capabilities of a selected role are granted to a member
    - the "Advanced Capability protection" which gives you more granular control over specific capabilities to be assigned.

    None of this modes changes user role itself, though.

    However, there's a workaround for this using a small code snippet:

    add_action( 'ms_model_event_' . MS_Model_Event::TYPE_MS_SIGNED_UP, 'wpmu_ms_controller_member_assign_memberships_done_cb', 99, 2 );
    function wpmu_ms_controller_member_assign_memberships_done_cb( $event, $data ) {
        $membership = $data->get_membership();
    	$member = $data->get_member();
    	if ($membership->id == "1234") {
    		$user = new WP_User($member->id);
    		$user->set_role('contributor');
    	}
    }

    To use it:

    1. put that code into the "functions.php" file of your current theme, near the end of it
    2. in this line:

    if ($membership->id == "1234") {

    the number is an ID of a membership. That's the same value that you can see in protection shortcode when you go to "Membership 2 -> Memberships" page and click on "Show" in "Shortcodes" column. You will want to replace that number with an ID of your membership that should assign a specific role to the user.

    In this line

    $user->set_role('contributor');

    you set the role of your choice.

    This code does not require "Membership Capabilities" add-on to be active. In fact I only tested it without it and I'd recommend disabling it.

    The code will assign a real user role to the member upon signup.

    Kind regards,
    Adam

  • Ellis Benus

    This code is not working with Paid Memberships.

    It works for a Free membership, but not one that has a monthly cost.

    Do you know why that might be?

    Also, this code HAS to be in the Functions.php file, but I would rather put it inside a plugin. However, whenever I put the code in a custom plugin, it took down my entire website. Is there a require() function I need to add in my plugin to allow this code to work?

  • Adam Czajczyk

    Hello Ellis Benus

    Thank you for your reply!

    I was testing this snipped on my own test site with a paid (recurring payment) membership and it worked fine there. The membership I tested with is using Stripe for payment and doesn't have any trial so I'm wondering whether gateway and/or other membership settings might be related here.

    However, since you need it to be outside of the "functions.php" file, the code I previously shared needs a small change. Therefore, would you please try it like this (as a plugin - either regular plugin or MU plugin):

    <?php
    add_action( 'ms_model_event_signed_up', 'wpmu_ms_controller_member_assign_memberships_done_cb', 99, 2 );
    function wpmu_ms_controller_member_assign_memberships_done_cb( $event, $data ) {
        $membership = $data->get_membership();
    	$member = $data->get_member();
    	if ($membership->id == "1234") {
    		$user = new WP_User($member->id);
    		$user->set_role('contributor');
    	}
    }

    You'll need to update the membership ID in this code to suit your needs. Please note also that it's using an action hook in a slightly different way so give it a try and let me know if it did help for paid memberships on your site as well.

    Kind regards,
    Adam

  • Predrag Dubajic

    Hi Ellis,

    I also tested this code on my end and it works fine so it seems that something on your end is blocking it from working properly.
    Did you make sure that you have set correct membership ID as Adam mentioned in his first reply?

    If that is correct but you're still having issues please perform conflict test by disabling all the other plugins and switching to default WP theme to see if any of those are interfering with this.

    Best regards,
    Predrag

  • Ellis Benus

    I'm still working to test this, b/c I can't figure out what's blocking the add_role from working on a Paid Subscription sign. However, I also wrote this little blurb to help others.

    It looks like this is exactly what I needed. Thank you. In order to further help others who might find this. I actually wanted to ADD a role to a user instead of CHANGE the role. WordPress allows this through code, but it's NOT supported in the Admin UI.

    $user= new WP_User( $user_id );
    $user->add_role( 'role-1' , 'Role One Name' );
    $user->add_role( 'role-2' , 'Role Two Name' );

    Note that the Wordpress Admin UI does not support multiple roles even though the code does. Thus, if the user is ever saved via the Wordpress Admin UI, only the role selected in the Roles dropdown will be stored, all added roles will be deleted.

    To avoid this, you need to install a 'Multiple Roles' plugin which changes the Admin UI User Role Selection to Check boxes instead of a drop menu: https://wordpress.org/plugins/multiple-roles/

    Probably a better option is you can also use the "User Role Editor" plugin which adds the "Other Roles" section. You will find a checkbox that shows all the user roles assigned. Edit User > Additional Capabilities > Other Roles

  • Ellis Benus

    I'm doing some more testing, but I had to go a completely different route, see below.

    First, I get an error when trying to use this line:

    $membership = $data->get_membership();

    Which means right now, anyone who adds any membership will have that role added.
    Since the get_membership() part doesn't' work, I don't have a way to verify which membership is in the $data

    Second, I cannot figure out when each of the MS_Model_Events are actually used/fired. There is no documentation on these and I've only found a few smatterings of code online. To find all the different TYPE_ pieces I had to search inside the Membership plugin code.

    Update: I had to change the code to not use the get_membership() nor get_member() or any of those functions. Instead I just reference the $data object properties directly.

    add_action( 'ms_model_event', 'mae_membership_event_handler', 20, 2 );
    /**
     * Customizes Events
     *
     * @param  MS_Model_Event $event The event that is processed.
     * @param  mixed $data The data passed to the event handler.
     */
    function mae_membership_event_handler( $event, $data ) {
    	$member = false;
    	$subscription = false;
    	$membership = false;
    
    	switch ( $event->type ) {
    		case MS_Model_Event::TYPE_PAYMENT_PENDING:
    		case MS_Model_Event::TYPE_MS_REGISTERED:
    		case MS_Model_Event::TYPE_UPDATED_INFO:
    		case MS_Model_Event::TYPE_PAID:
    		case MS_Model_Event::TYPE_MS_SIGNED_UP:
    			$membership = $data->membership_id;
    			$user = new WP_User( $data->user_id );
    			$user->add_role( 'mae_subscriber' , 'MAE Member' );
    			break;
    	}
    }
  • Adam Czajczyk

    Hi Ellis Benus

    Thanks for response!

    I must admit I'm not sure why this was giving you an error:

    $membership = $data->get_membership();

    The code I share was reviewed by one of our Membership 2 Pro developers, used before on different setups and both me and Predrag we also tested it on our sandboxes. I believe there's something specific to the site that's "getting in a way". However, it's not the only way to do this and it seems that your way, while a bit more of code, looks "legit" to me as well.

    Keep us updated please and if necessary I'll call out our developers again to lend you a hand with this.

    Best regards,
    Adam

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.