Manage group membership in Discourse with WP Discourse SSO

Holy :cow:! 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.

3개의 좋아요

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.

https://github.com/justindirose/dc-pmp-group-sync

8개의 좋아요

Awesome, anything stopping this being wrapped into a plugin for customers who aren’t confident editing PHP?

1개의 좋아요

No, probably not, but PHP/WP development isn’t my forte, and I don’t plan on personally actively maintaining this code long-term.

3개의 좋아요

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.

1개의 좋아요

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;
}
7개의 좋아요

이것이 샘플 코드라는 것은 알고 있지만, 꽤 치명적인 버그가 있는 것 같습니다.

결제 완료되지 않고 멤버십 상태가 "token"인 경우

그룹이 여전히 discourse 사용자에 추가됩니다 :open_mouth:

나중에 자세히 살펴보겠지만 언급할 가치가 있다고 생각합니다


1개의 좋아요

저는 이 코드를 사용하여 Paid Memberships Pro를 통해 제 Discourse 커뮤니티의 접근을 유료 회원으로만 제한하려고 합니다. 무료 멤버십 레벨 1개와 유료 멤버십 레벨 2개가 있습니다.

다음 코드를 어떻게 수정해야 할까요: Manage group membership in Discourse with WP Discourse SSO

유료 회원만 커뮤니티에 접근할 수 있도록 하고, 그렇지 않은 사용자는 유료 멤버십 가입 페이지로 리다이렉트되게 하려면 어떻게 해야 할까요?

감사합니다.

참고로 수정하려는 코드는 다음과 같습니다:

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;
    }
}

할 일은 코드의 /* some condition */ 주석을 유료 멤버십이 없는 사용자에게 true를 반환하는 조건으로 대체하는 것입니다. 그러면 해당 사용자는 멤버십 가입 페이지로 리다이렉트됩니다.

현재 테스트 사이트에 Paid Memberships Pro 플러그인이 설치되어 있지 않지만, 그들의 문서에 따르면 사용자가 특정 멤버십 레벨을 가지고 있는지 확인하기 위해 pmpro_hasMembershipLevel 함수를 사용할 수 있는 것으로 보입니다: Using the pmpro_hasMembershipLevel() Function.

pmpro_hasMembershipLevel 함수를 사용하려면 두 개의 유료 멤버십 레벨의 ID(또는 이름)를 알아야 합니다. 이 ID는 pmp의 “Membership Levels” 관리자 페이지에서 확인할 수 있습니다. 예를 들어, 두 개의 유료 레벨의 ID가 1과 2라면 다음과 같은 조건을 사용할 수 있습니다:

if (! pmpro_hasMembershipLevel(array(1, 2), $user_id))

이것을 코드에 대입하면 다음과 같습니다:

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;
    }
}

수정해야 할 다른 한 줄은 다음과 같습니다:

wp_safe_redirect( home_url() );

현재 이 코드는 사용자를 사이트의 홈 페이지로 리다이렉트하도록 설정되어 있습니다. 사이트의 가입 페이지 경로 또는 전체 URL로 리다이렉트하도록 변경해야 합니다:

wp_safe_redirect( /* path_to_your_signup_page */ );

이 코드를 테스트해 보지 않았다는 점을 참고하세요. 라이브 사이트의 functions.php 파일을 직접 수정하는 경우, 코드에 오류나 오타가 있을 경우를 대비하여 사이트 백엔드에서 functions.php 파일에 접근할 수 있는지 확인하세요.

4개의 좋아요

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와 관련된 메모를 여기에 남겨둡니다. WP Discourse의 Create or Sync Discourse Users on Login(로그인 시 Discourse 사용자 생성 또는 동기화) 옵션이 활성화되어 있으면, OP에 설명된 방법으로 Discourse 로그인이 차단된 경우라도 WordPress 사이트의 모든 사용자를 위해 Discourse 계정이 자동으로 생성됩니다. 적절한 멤버십 등급을 갖추지 않은 사용자의 계정이 자동으로 생성되지 않도록 방지하는 방법에 대한 세부 사항은 이 게시물의 두 번째 부분에서 확인할 수 있습니다: How to prevent some WP users from being able to login to Discourse - #2 by simon.

간단히 설명하면:

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 ( /* 멤버십 요건을 충족하지 않는 사용자가 true를 반환하는 어떤 조건 */  ) {

        $bypass_sync = true;
    }

    return $bypass_sync;
}

OP에 이러한 세부 사항을 업데이트해야 한다는 것을 잊지 않도록 스스로에게 리마인더를 설정해 둡니다.

2개의 좋아요

시몬, 감사합니다. 당신의 설명에 따라 제 웹사이트에 설정할 수 있었습니다.

1개의 좋아요

정리하자면.

레벨(사용자가 아님): 0
무료 레벨 = 1
유료 레벨 2개: 2, 3

질문자님은 이렇게 말씀하셨습니다.

해야 할 일은 코드의 /* some condition */ 주석을 유료 멤버십이 없는 사용자에게 true를 반환하는 조건으로 교체하는 것입니다. 이렇게 하면 해당 사용자를 멤버십 가입 페이지로 리디렉션할 수 있습니다.

그리고

pmpro_hasMembershipLevel 함수를 사용하려면 두 개의 유료 멤버십 레벨의 ID(또는 이름)를 알아야 합니다. 이 ID는 pmp의 “Membership Levels” 관리 페이지에서 확인할 수 있습니다. 예를 들어 두 유료 레벨의 ID가 1과 2라면 다음 조건을 사용할 수 있습니다:

if (! pmpro_hasMembershipLevel(array(1, 2), $user_id))

이 두 진술은 모순되지 않나요?

제 이해를 정리하면 다음과 같습니다:

유료 멤버십이 없는 사용자를 멤버 가입 페이지로 리디렉션하려면 다음을 사용해야 합니다:

if (! pmpro_hasMembershipLevel(array(0,1), $user_id))

틀린 부분이 있다면 바로잡아 주세요.

감사합니다.

이 조건이 true를 반환하면 사용자는 가입 페이지로 리다이렉트됩니다.

귀하의 경우 가장 안전한 방법은 사용자가 레벨 2 또는 레벨 3 중 어느 하나도 가지고 있지 않을 때 true를 반환하는 조건을 사용하는 것입니다:

if (! pmpro_hasMembershipLevel(array(2, 3), $user_id))

1개의 좋아요

감사합니다. 두 번째 코드 조각에서 “!” 기호를 놓쳤네요.

1개의 좋아요