Bring over permission level from WordPress MemberPress

We are currently using MemberPress for our membership platform on WordPress. We are going to be launching a ‘free’ membership level on WordPress and would like the ability to have this membership correspond to 1-2 discussions in our Discourse forum (but have the rest of the forum content protected from free members).

Is there a way to bring over membership roles/permissions into Discourse using the SSO plugin?
@simon you helped us with a few things with the WP Discourse plugin in the past. If the above is not possible out of the box, is it something you’d be able to build on a contract basis? If so, maybe we can discuss the details offline.

2 Likes

There are a couple of ways to do it. The easiest way is to add the Discourse group names to the SSO payload. You can do this by hooking into the wpdc_sso_params filter. Setting it up this way will add and remove users from groups when they login to Discourse. You’ll need to figure out the condition to check the user against to know which groups to add or remove them from. Memberpress fires an action when a membership level is added or removed. You could hook into that action and add some user metadata to a user when they are added or removed from a group. You could then test for that with the function below.

add_filter( 'wpdc_sso_params', 'wpdc_custom_sso_params', 10, 2 );
function wpdc_custom_sso_params( $params, $user ) {
    if ( $user /* some condition based on the user to add groups */ ) {
        $params['add_groups'] = 'comma,separated,group,names'; // Don't use spaces between names.
    }

	if ( $user /* some condition based on the user to remove groups */ ) {
		$params['remove_groups'] = 'comma,separated,group,names'; // Don't use spaces between names.
	}

    return $params;
}

The other approach is to use the wp-discourse add_user_to_discourse_group and remove_user_from_discourse_group functions. This way users can be added and removed from Discourse groups without them first having to login to Discourse. There is some information about using the functions here: Managing Discourse group membership with WP Discourse.

I’m working for Discourse now, so I can’t take on any contract work. Setting this up is fairly straightforward. If you find someone to do the work, and they get stuck, have them post on here and we can sort it out.

7 Likes

Thanks for the quick response @simon. I think I am going to try to go with the first option. Because the free membership isn’t setup on the live WordPress site yet, I am having a hard time testing this. Here is the code that I have now:

add_filter( 'wpdc_sso_params', 'wpdc_custom_sso_params', 10, 2 );
function wpdc_custom_sso_params( $params, $user ) {
    if ( current_user_can('mepr-active','memberships:12856') ) {
      $params['add_groups'] = 'Academy_Free'; // Don't use spaces between names.
    } else {
      $params['remove_groups'] = 'Academy_Free'; // Don't use spaces between names.
    }

    return $params;
}

current_user_can('mepr-active','memberships:12856) is a function in MemberPress that checks if a member is active in a specific membership. Does that look right? If so, that code runs every time someone connects to Discourse via SSO, correct? If this looks right, I may wait until we push the free membership live and then test this functionality—unless you have a way we could test it now with a WP staging site.

Thanks!

1 Like

The code looks right to me. It’s tricky to test it with a staging site. Unless you add some code so that the user’s external ids can be guaranteed to be unique between your staging and your production sites it can mess up your SSO records on Discourse.

4 Likes

Just pushed things live and this code works as expected. Thank you!

2 Likes

@simon

Simon, if i want to use this for ALL my membership levels, would it be enough to just say “current_user_can(‘mepr-active’)” or would i have to include all the active ID’s?

There’s five groups and i need the user to enter the group he has paid for.
If they change plans, that should be reflected in their group.

Based on what Andrew used, i have this:
 
44

does that make sense for my situation?

thanks!

The basic idea makes sense. current_user_can is a WordPress function. Its documentation is here. I think that in this case you are fine to call it without the $object_id argument. If MemberPress adds mepr-active as a role or capability to users when they sign up for any membership level, and removes the mepr-active role or capability when the membership expires, then it will do what you are looking for.

Be careful with the comment (// Don't use spaces between names.). Comments in that form need to be included on a single line, or they will cause an error. You can remove the comment from the code.

awesome, thanks so much, Simon!

It is a lot more difficult to set up this kind of code in a live environment than it is in a development environment, because if you make a mistake on the live site, you can break the site. Make sure that you have some way of accessing your site through the backend (using cPanel or the command line.) If you make a mistake you’ll be able to fix it that way.

thanks for the heads up.
if anything does go wrong, is it enough to just remove the code i added? or will i really be up S-creek?

i’m using the plugin “My Custom Functions”

Thanks for the link! If it works as it says it does, then that is a good approach. The worst case scenario is that if you added some code that broke your site, you would need to edit the code through the file manager in your site’s cPanel.

Thanks!

So far, so good, everything’s still working, i ran a test account just now, but then i remembered i read somewhere there’s a 10 minute lag, so i’ll try again in a couple of minutes.

@simon

well, the site didn’t break… but it also didn’t work… :frowning:

it’s close to midnight on this end, so i’m calling it a day. will try again in the morning.

any suggestions will be much appreciated!

thanks!

Edit: i can try adding the membership ID’s. what would be the way to add Numerous ID’s?
Like so: current_user_can(‘mepr-active’,‘memberships:12856,12345,12346’) ?

1 Like

i came up with this:

add_filter( 'wpdc_sso_params', 'wpdc_custom_sso_params', 10, 2 );
function wpdc_custom_sso_params( $params, $user ) {
 if ( current_user_can('mepr-active','memberships:47281,47295,47299,47303,47297,47301,47305,48259,48238’) ) {
$params['add_groups'] = 'Forever_Free,Creative_License,Join_Live,Transform,Transform_Plus';     
} else {
$params['remove_groups'] = 'Forever_Free,Creative_License,Join_Live,Transform,Transform_Plus';     } 
return $params;
}

but the plug-in tells me “This causes a fatal error so it hasn’t been applied.”
i tried with and without spaces: ‘memberships:47281, 47295’ but both options are rejected.

If the code you used is exactly the same as what you posted here, the problem might be the curly quotes in your code. Try this code. I’ve also removed the $user parameter in the function call, since it’s not used:

add_filter( 'wpdc_sso_params', 'wpdc_custom_sso_params' );
function wpdc_custom_sso_params( $params ) {
	if ( current_user_can( 'mepr-active','memberships:47281,47295,47299,47303,47297,47301,47305,48259,48238' )  ) {
        $params['add_groups'] = 'Forever_Free,Creative_License,Join_Live,Transform,Transform_Plus';
    } else {
        $params['remove_groups'] = 'Forever_Free,Creative_License,Join_Live,Transform,Transform_Plus';
	}

	return $params;
}
3 Likes

@simon

Thanks, Simon, indeed, my text editor gives curly quotes, :confused:

unfortunately the code didn’t help. but… not giving up, :slight_smile:

EDIT! It DID work, i had made an error in matching the names between Groups and WP users.
YEEHA!!! couldn’t be happier!!

BUT… they now get added to ALL groups.
so i will have to add the php one-by-one, each to their corresponding group.

like: 47281 leads to “Forever Free”
the next two lead to “Creative License” etc.

RE-EDIT:
I’ve inserted the code through my plugin in various ways. (i tried making a separate entrance for every group, but clearly you can only add one filter and the rest should follow within that one filter)

some of my attempts were directly bounced, so i discarded those.
the code below has been accepted, but it’s not working properly.

the first group works as it should. but then the next don’t, so i’m making a mistake in the code.

RE-EDIT: Turns out i had missed the curly quotes again…
Problem resolved, the below code works. (once you take out the curlies :grinning::grinning::grinning: )

   add_filter( 'wpdc_sso_params', 'wpdc_custom_sso_params' );
function wpdc_custom_sso_params( $params ) {
if ( current_user_can( 'mepr-active','memberships:47281' )  ) {
        $params['add_groups'] = 'ForeverFree';
    } else {
        $params['remove_groups'] = 'ForeverFree';
	}
    if ( current_user_can( 'mepr-active','memberships:47295,47299' )  ) {
        $params['add_groups'] = ‘CreativeLicense’;
    } else {
        $params['remove_groups'] = ‘CreativeLicense’;
	}
    if ( current_user_can( 'mepr-active','memberships:47303,47297' )  ) {
        $params['add_groups'] = ‘JoinLive’;
    } else {
        $params['remove_groups'] = ‘JoinLive’;
	}
if ( current_user_can( 'mepr-active','memberships:47301,47305' )  ) {
        $params['add_groups'] = ‘Transform’;
    } else {
        $params['remove_groups'] = ‘Transform’;
	}
if ( current_user_can( 'mepr-active','memberships:48259,48238' )  ) {
        $params['add_groups'] = ‘TransformPlus’;
    } else {
        $params['remove_groups'] = ‘TransformPlus’;
	}
    
	return $params;
}

thanks for your help!
You have NO idea how happy i am. Just … awesome!

:- D.

POST-EDIT:
to anyone wanting to use this code for their own memberpress/discourse connection: it’s not complete yet!
when a member upgrades or downgrades, they get added to the new group, but they don’t get removed from the old group. still working on that.

Final Edit:
Solution can be found here: Memberpress: how to add users to groups upon Sign up

10 Likes

Dani1,

We are also Memberpress users. Is your site in production and if so can you share a link?

thx!

@simon Coming back to this because we need to have multiple groups added/removed and it seems to only be apply the last group. Essentially I changed the code to check for multiple different memberships (similar to Dani1’s code above). It works except when someone is a member of multiple memberships. In that situation it only applies the last group, which makes sense since it is looking for the latest value of $params. Is there a way to have multiple checks without having to nest conditions, which could start to get pretty messy?

You could try creating arrays for the groups you wish to add and remove. For each condition you check, add to the arrays. Something like the code below could be used inside of your function.

//...

$groups_to_add = [];
$groups_to_remove = [];

if ( /* some condition */ ) {
    $groups_to_add[] = 'group_one'; // $array[] = 'element' adds 'element' to the array.
    } else {
    $groups_to_remove[] = 'group_one';
}

if ( /* another condition */ ) {
    $groups_to_add[] = 'group_two';
    } else {
    $groups_to_remove[] = 'group_two';
}

//...

$params['add_groups'] = join( ',', $groups_to_add ); // Create a string from the array, with ',' as the separator.
$params['remove_groups'] = join( ',', $groups_to_remove );

return $params;

Make sure you are calling join() with no spaces in the separator parameter (',').

3 Likes

Great idea Simon. That worked perfectly. Thank you!

1 Like