I maintain Discourse and MemberMouse running on 2 sites. Hopefully this guide will be helpful to people. Your exact specifications may differ from what my desired results were. This guide assumes that you are familiar with MemberMouse hooks, filters and MemberMouse PHP interface. And also assumes you can comfortably add custom code to WordPress via functions.php or your own custom plugin.
This guide below is what we added in order to:
- Activate/deactivate the user in Discourse depending on their membership status in MemberMouse
- Set Discourse groups that represent MemberMouse membership levels
- Sync up username/email changes instantaneously
- And misc other helpful little tweaks
Step 1: Install Discourse and WordPress and wp-discourse WordPress plugin
Get the WordPress and Discourse and wp-discourse WordPress plugin up and running and configured properly with WordPress as the SSO provider. There are lots of threads about this here.
Step 2: Check the box to allow the wp-discourse plugin to create a new user in Discourse when user is created in WordPress
I found that in order for the wp-discourse to actually create a user in Discourse when a user is created in WordPress, I needed to make a code change in the plugin. This is because the plugin relies on the āwp_loginā action but it behaves differently in MemberMouse than regular WordPress behavior. So you need add this line to the file /lib/discourse-sso.php in public function __construct( $wordpress_email_verifier ):
add_action( 'my_mm_account_added', array( $this, 'create_discourse_user' ), 10, 2 );
And in functions.php or your own plugin add:
function add_user_to_discourse($data) {
do_action( 'my_mm_account_added', $data["username"], get_user_by('ID',$data["member_id"]) );
}
add_action('mm_member_add', 'add_user_to_discourse');
Step 3: If you want, make it so new users donāt need to click a Discourse email activation link
By default Discourse will send an activation email to the new user but I chose to turn this off since the user has already jumped through a satisfactory number of hoops in WordPress to join. If your WordPress site has a low barrier to joining, you may not want to skip the activation email. In our case, you have to pay to join so. Add this to functions.php or to a special plugin you create.
add_filter( 'wpdc_auto_create_user_require_activation', 'my_wpdc_auto_create_user_require_activation' );
function my_wpdc_auto_create_user_require_activation( $require_activation ) {
return false;
}
Step 4: Whenever an account change happens to a MemberMouse user:
Map MemberMouse membership levels to Discourse groups
Sync the email address/username
Activate/deactivate user in Discourse as appropriate
You can add this to functions.php or your own plugin.
add_action('mm_member_membership_change', 'run_discourse_sync_based_on_mm_acct_change');
add_action('mm_member_status_change', 'run_discourse_sync_based_on_mm_acct_change');
add_action('mm_member_account_update', 'run_discourse_sync_based_on_mm_acct_change');
In the function run_discourse_sync_based_on_mm_acct_change you want to:
(1) Use the Discourse API to get this userās Discourse username (may be slightly different than their WordPress one due to Discourseās own username rules) and Discourse ID number. (documentation)
(2) Map their MemberMouse membership level ID to the equivalent Discourse group ID and then set their group in Discourse. First you need to delete their old group ID. (documentation). Then you can set the new group. (documentation)
(3) Sync up their username and email if they have been changed in WordPress. We only allow these to be changed in WordPress. I got help with this part here.
(4) Activate/deactivate the user in Discourse depending on their status in MemberMouse. Activate (documentation). Deactivate seems to be missing from the API docs. $url = $url_base.āadmin/users/ā.$discourse_userid.ā/deactivate.json?ā.$api_auth;
Step 5: Auto-redirect back to Discourse when appropriate
(I highly recommend holding off on this part of things until you get a really good feel for how WordPress and Discourse work together.)
If a user is NOT logged into Discourse and NOT logged into WordPress. And they come to a url in Discourse and click the blue Login button, they are taken to WordPress to login but then MemberMouse directs the user to whatever page you have it set to redirect to in MemberMouseās settings. The user doesnāt get redirected back to Discourse unfortunately. So here is how I solved this. You can add this to functions.php or your own plugin. (Thread for more info.)
// If the person came from the discourse forum, push them to exactly where they were after logging in
function my_mm_login_redirect( $infoObj ) {
if ( @$_COOKIE['detected_forum_referal'] != '' ) { // You need take care of setting this temporary cookie if the user just arrived via discourse
$current_user = $infoObj->user;
$user_id = $current_user->ID;
// Payload and signature.
$payload = @$_COOKIE['mm_cookie_sso'];
$sig = @$_COOKIE['mm_cookie_sig'];
// Change %0B back to %0A.
$payload = rawurldecode( str_replace( '%0B', '%0A', rawurlencode( $payload ) ) );
// Validate signature.
$sso_secret = 'YOUR-SSO-SECRET';
$sso = new \WPDiscourse\SSO\SSO( $sso_secret );
if ( ! ( $sso->validate( $payload, $sig ) ) ) {
return '';
}
$nonce = $sso->get_nonce( $payload );
$params = array(
'nonce' => $nonce,
'username' => $current_user->user_login,
'email' => $current_user->user_email,
'external_id' => $user_id,
);
$params = apply_filters( 'wpdc_sso_params', $params, $current_user );
$q = $sso->build_login_string( $params );
do_action( 'wpdc_sso_provider_before_sso_redirect', $user_id, $current_user );
// Redirect back to Discourse.
return('YOUR-FORUM-BASE-URL' . '/session/sso_login?' . $q);
}
return('');
}
add_filter( 'mm_login_redirect', 'my_mm_login_redirect', 10, 1 );