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.

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!