Holy ! Howād you manage to find it!? Nice work.
By adding log statments to my development site. This should be an easy fix, but Iād rather not push the change to WordPress before I test it out some more.
Sure you have a reasonable development environment. Like a real developer. That I understand (in spite of my not having such!) But even thinking to try usernames that had changedā¦ I guess the 2 was the clue.
Hereās a slightly different method to handle Paid Memberships Pro group sync. Pop this into your functions.php
file. Expected behavior is add upon subscribe and remove upon cancellation. Thanks to @dfriestedt for sponsoring.
Awesome, anything stopping this being wrapped into a plugin for customers who arenāt confident editing PHP?
No, probably not, but PHP/WP development isnāt my forte, and I donāt plan on personally actively maintaining this code long-term.
I am implementing the PMPro code above and am hung up on something. My understanding is that this code only fires when users buy subscription or cancel a subscription.
Is there a way that I can auto-sync users as they are created on Discourse? In my case, I have some users who are subscribers but donāt have a Discourse accounts (will be created via SSO).
If wordpress is the SSO master then you can have it update groups at every login.
Is there a code snippet that shows an example of updating groups on WP login?
The add_user_to_discourse_groups
function will create a Discourse user if it doesnāt already exist. If that function is being called for your users, then you should be fine. Where you might run into problems will be for existing WordPress users who got their membership before the code was added to your site. If that is the case, you will probably need to add the users to Discourse groups through the SSO parameters that are passed to Discourse on login.
To pass additional SSO parameters with the WP Discourse plugin, you can hook into the 'wpdc_sso_params'
filter. The parameter you need to use to add users to a Discourse group is called add_groups
. You can use it with something like this:
add_filter( 'wpdc_sso_params', 'wpdc_custom_sso_params', 10, 2 );
function wpdc_custom_sso_params( $params, $user ) {
if ( /* some condition that returns true if groups should be added for the user */ ) {
$params['add_groups'] = 'comma,separated,group,names'; // Don't use spaces between names.
}
return $params;
}
I realise this is only sample code but it appears to have a pretty critical bug.
If the payment isnāt completed and the status of the membership is ātokenā
The group is still added to the discourse user
Iāll look in to this at a later date but i think itās worth mentioning
I wish to use this code to restrict my Discourse community ONLY to paid members using Paid Memberships Pro. I have a free membership level and two paid membership levels.
How can I modify this code: Manage group membership in Discourse with WP Discourse SSO
so that ONLY the paid members are able to access the community. Otherwise, they will be redirected to the paid memberships sign-up page.
Thank you.
For my own reference, hereās the code you are wanting to modify:
add_action( 'wpdc_sso_provider_before_sso_redirect', 'wpdc_custom_check_user_membership', 10, 2 );
function wpdc_custom_check_user_membership( $user_id, $user ) {
if ( /* some condition */ ) {
wp_safe_redirect( home_url() );
exit;
}
}
What you need to do is replace the codeās /* some condition */
comment with a condition that will return true
for users who do not have paid memberships. These users can then be redirected to your membership signup page.
I donāt currently have the Paid Memberships Pro plugin installed on my test site, but from their documentation, it looks like you can use their pmpro_hasMembershipLevel
function to check if a user has a given membership level: https://www.paidmembershipspro.com/documentation/content-controls/require-membership-function/.
To use the pmpro_hasMembershipLevel
function, you need to know the IDs (or the names) of your two paid membership levels. You can get those ids from the pmp āMembership Levelsā admin page. For example, if the IDs of your two paid levels are 1 and 2, you could use the following condition:
if (! pmpro_hasMembershipLevel(array(1, 2), $user_id))
Substituted into the code, that would be:
add_action( 'wpdc_sso_provider_before_sso_redirect', 'wpdc_custom_check_user_membership', 10, 2 );
function wpdc_custom_check_user_membership( $user_id, $user ) {
if (! pmpro_hasMembershipLevel( array( 1, 2 ), $user_id ) ) {
wp_safe_redirect( home_url() );
exit;
}
}
The other line you will need to change is:
wp_safe_redirect( home_url() );
It is currently set to redirect users to the siteās homepage. You will need to change it to redirect to either the path or the full URL of your siteās sign-up page:
wp_safe_redirect( /* path_to_your_signup_page */ );
Note that I havenāt tested this code. If you are making changes directly to your live siteās functions.php
file, make sure that you are able to access the siteās functions.php
file from the siteās backend, just in case there are any mistakes or typos in the code.
Leaving myself a note here related to https://meta.discourse.org/t/manage-group-membership-in-discourse-with-wp-discourse-sso/74724#restricting-access-to-discourse-when-a-membership-doesnt-exist-4. If the WP Discourse Create or Sync Discourse Users on Login option is enabled, Discourse accounts will be automatically created for all users on the WordPress site, even if they are prevented from logging into Discourse via the method outlined in the OP. Details about how to prevent accounts from being automatically created for users who do not have the appropriate membership level are in the second part of this post: How to prevent some WP users from being able to login to Discourse - #2 by simon.
Basically:
add_filter( 'wpdc_bypass_sync_sso', 'wpdc_custom_bypass_sync_sso', 10, 3 );
function wpdc_custom_bypass_sync_sso( $bypass_sync, $user_id, $user ) {
if ( /* Some condition that returns true if the user doesn't meet the membership requirement */ ) {
$bypass_sync = true;
}
return $bypass_sync;
}
Iām setting myself a reminder to update the OP with those details.
Thank you, Simon. I was able to set this for my website using your instructions.
A clarification.
No level (not a user) : 0
Free level = 1
I have two paid levels: 2,3
You said
What you need to do is replace the codeās
/* some condition */
comment with a condition that will returntrue
for users who do not have paid memberships. These users can then be redirected to your membership signup page.
And
To use the
pmpro_hasMembershipLevel
function, you need to know the IDs (or the names) of your two paid membership levels. You can get those ids from the pmp āMembership Levelsā admin page. For example, if the IDs of your two paid levels are 1 and 2, you could use the following condition:
if (! pmpro_hasMembershipLevel(array(1, 2), $user_id))
Are these statements contradicting?
In my understanding :
I should use the following:
if (! pmpro_hasMembershipLevel(array(0,1), $user_id))
to redirect users who DO NOT have a paid membership to the member sign-up page.
Please correct me if I am wrong.
Thanks.
If the condition returns true
, users will be redirected to your signup page.
I think the safest thing to do for your case would be to use a condition that returns true
if the user doesnāt have either level 2 or 3:
if (! pmpro_hasMembershipLevel(array(2, 3), $user_id))
Thank you. I missed the ā!ā mark in your second snippet.