christianwach / civicrm-wp-member-sync

CiviCRM WordPress Member Sync plugin keeps a WordPress user in sync with a CiviCRM membership by granting either a role or capabilities to a WordPress user who has that membership.
https://wordpress.org/plugins/civicrm-wp-member-sync/
GNU General Public License v2.0
17 stars 10 forks source link

Multiple Memberships #13

Closed prdufresne closed 8 years ago

prdufresne commented 8 years ago

On our site we have users with multiple memberships, but only one membership gets synchronized to a role, and only the most recent rule created. For examples, we have club members that are also leaders. Not all club members are leaders, and not all leaders are club members.

The first rule created syncs members, the second rule syncs leaders. For those with only one membership, everything works fine. For users with both memberships, they always get the "leader" role in WordPress, presumably because the rules are run sequentially, but they don't get both roles.

In our environment, we would like them to get both roles since the permissions don't always overlap.

prdufresne commented 8 years ago

I was looking through the code, but I don't know much about PHP. What I believe is happening, based on what I seen in the code below, is that you only sync the last membership entry in the array of memberships..

Below is part of the rule_apply function from the admin file.

public function rule_apply( $user, $membership = false ) { // removed check for admin user - DO NOT call this for admins UNLESS // you're using a plugin that enables multiple roles // kick out if no CiviCRM if ( ! civi_wp()->initialize() ) return false; // kick out if we didn't get membership details passed if ( $membership === false ) return false; // get membership type and status rule

The foreach below is the culprit, it goes through the array of memberships, but only the last one will be stored in the variable, therefore the sync will only happen on the last membership instance.

foreach( $membership['values'] AS $value ) { $membership_type_id = $value['membership_type_id']; $status_id = $value['status_id']; }

I think someone who understand the function more completely than I could modify it so that the rule is applied for each membership type, not just the last one. This is probably a simple matter of nesting the rule application into the foreach above. Even if the site doesn't have a plugin allowing multiple roles, it would probably operate the same way, in that only the last membership in the array would be applied.

christianwach commented 8 years ago

@prdufresne Thanks for the report. I will look into the issue as soon as I have the opportunity.

christianwach commented 8 years ago

@prdufresne Can you test with the latest commit on master?

prdufresne commented 8 years ago

Let me speak with the site administrator and see if we can load this version. We have a couple of ongoing changes scheduled, so it's unclear if we will be able to get to this in the next week.

prdufresne commented 8 years ago

@christianwach The administrator installed the latest commit on the server tonight, and on the first sync, it worked for all but one user. When I went back into CiviCRM, I found that user had a duplicate membership (as a result of an import error). When I removed the duplicate membership, and ran another sync, it worked. All those members that had two memberships had two roles in WordPress.

I consider the issue resolved, but didn't want to close it without hearing from you first.

Thank you!

christianwach commented 8 years ago

@prdufresne Good to hear - thanks for confirming. The tricky bit wasn't syncing multiple roles, but rather what to do when a membership is removed. I think the logic is sound, but if you run into any oddities please open a new issue.

christianwach commented 8 years ago

Closed via 1cb28421534b9b880de42106b394c321b3897846