Preserving user role editor 'other roles' with during_demote function

I’m using the action ws_plugin__s2member_during_auto_eot_system_during_demote to run some custom functions on user demotion.

This seems to be working, however any ‘Other Roles’ assigned in the profile by way of User Role Editor are getting dropped when the user is demoted.

I’d like to keep those roles but am struggling to find a way to preserve them when demoting my users to subscriber.

Seems you are a developer? In this case, I would suggest you to “hunt” and detach all the functions that runs to clear those additional user roles, “Other roles” that you need. This can be hooks in “User role editor” or something else. Not easy to track. I can help, if needs, I am did this in some of my plugins.

1 Like

If it’s any help the data in question seems to be stored in the user_meta table under the wp_capabilities key.

I have set Membership EOTs also Remove all Custom Capabilities to No in the Stripe options

I also tried commenting out “$user->remove_cap($ccap = $cap);” from auto-etos.inc.php but it still strips out any additional capabilities/roles and replaces them with subscriber data “a:2:{s:15:“s2member_level0”;b:1;s:10:“subscriber”;b:1;}”

Finaly I’m using the following for the demotion:

$user->remove_role( ‘s2member_level3’ );
$user->add_role( ‘subscriber’ );

I feel like I’m zeroing in a bit…

In the logs I can see that something is actively removing all roles, for example:

auditor:event=remove_user_role {“user_id”:12345,“role”:“s2member_level3”,“blog_id”:1,“event”:“remove_user_role”,“current_user_id”:0,“remote_addr”:“123.123.123.123”}

auditor:event=remove_user_role {“user_id”:12345,“role”:“second_role”,“blog_id”:1,“event”:“remove_user_role”,“current_user_id”:0,“remote_addr”:“123.123.123.123”}

auditor:event=remove_user_role {“user_id”:12345,“role”:“third_role”,“blog_id”:1,“event”:“remove_user_role”,“current_user_id”:0,“remote_addr”:“123.123.123.123”}

I can see that ws_plugin__s2member_during_auto_eot_system_during_demote fires because I’m having it send an email, however when removing my remove_role and add_role lines it still removes all roles on EOT.

OK, the problem appears to be here in auto-etos.inc.php

if($existing_role !== $demotion_role /* Only if NOT the existing Role. /)
$user->set_role($demotion_role /
Give User the demotion Role. */);

the set_role function removes all other roles. If I change this to add_role instead I can see that it keeps all “other roles” so I could piggy pack add_role with a function to remove_role for their s2member roles while keeping the others.

So I think now my challenge is to find out how to do this without over-writing any s2member plugin files.

Well, I don’t feel great about it, but I went ahead and dropped the entire c_ws_plugin__s2member_auto_eots class into a MU plugin and added in my custom logic to reassign the additional roles after the set_role function does its thing.

This will work fine until an upgrade affects that class, so I welcome alternative approaches, thank you!

That’s a good enough solution for a cutomization, Craig.

If you don’t have an action/filter that lets you do it, then I’ve customized things just copying the whole class file to the mu-plugins dir and working there.

s2 Checks first if the already exists before creating it, and mu-plugins load first, so your custom class will come before the one in s2.

Since it’s outside of the s2 directory, it won’t be overwritten by updates.

You’d just need to update your file if something got improved in the release one that you need/want in your customized one.

:slight_smile:

Thanks Cristián, very much appreciate all your help and insight over the years!