Delete user from multisite when removed from subsite

But the trick seems to be when to fire it.

This is correct! When remove_user_from_blog fires, the removal has not happened yet, rather it’s about to happen and this is your chance to step in and do things beforehand, e.g. cleanup.

The wpmu_delete_user function should be the one to go i guess.

Yes, that would be my guess too

I looked at the codex but I cannot get it to work

The codex is great, but https://developer.wordpress.org is greater, and gives more information

Some Notes Before Tackling the Issue

  • That action receives 2 parameters, the second being the blog ID, you should check for that
  • There is no super admin check or the current user, you could accidentally delete yourself!
  • This code will need to be in either an MU plugin, or a network activated plugin. It’s possible it could go in a functions.php but that would be very bad practice. It could also cause problems when removing users via WP CLI
  • You didn’t provide any context, so whatever problem this solves, you should have asked about the problem, then proposed your solution as a possible one that you didn’t know how to implement. That way an even better solution you hadn’t thought of might have been given
  • If a user is a member of multiple blogs, this will remove them from all blogs once a user is removed from 1, which would be unexpected

But most importantly, deleting a blog will call remove_user_from_blog deleting every user, including yourself.

So, I would not recommend doing this.

Instead, what is the problem this is trying to solve?

The Hook and Infinite Looping

As mentioned before, the remove_user_from_blog event fires before the removal, so you can’t delete the user on that hook or the rest of the remove_user_from_blog function will fail, and you end up with no cleanup or deletion taking place.

Worse yet, wpmu_delete_user calls remove_user_from_blog internally, so you would end up in an infinite loop where it tries to remove the user from the blog, but then your action calls wpmu_delete_user, which tries to remove the user from the blog, triggering your action yet again indefinitely

Sadly, there is no removed_user_from_blog action that we can hook into. I would recommend adding that via Core Trac for inclusion in the next WP release, it’s a super easy patch, and you’ll appear in the credits for the next WP version on the about page

Alternatives

I’m afraid, you will need to hook into every possible scenario that could remove a user from a blog. You would need to detect the form submissions and URLs for removing them on admin_init, the REST API DELETE calls for users, the WP CLI commands, etc

Put simply, there is no simple filter or action that will let you do this in a foolproof manner. It is not an easy trivial ask, and you will have to add to it as new situations arise, and account for all plugins as and when they change.

If that additional action was added to WP core however, there would be. But again, what problem is it that this is supposed to solve?

Edit: The Real Problem

Thanks to some clarifying comments it’s now revealed that each site is an educational course.

I’m assuming that the check to see if content is visible does not use roles, but instead only checks is_user_logged_in().

So instead:

  • check that the user has the subscriber role or higher. Users who are logged in but aren’t on the site have no role, so they will be unable to pass this check
  • Add a hook on init and admin_init to check if the current user is a member of the current site, and run wp_redirect( '...url...' ) exit; to send them to the root homepage, or a page that explains they have no access to that site
  • Use the same hook but combine it with a wp_die('you do not have access to this' );

Why Deleting The User is a Bad Idea

  • When a site is deleted, all the users are removed from it first, so they’d all be deleted across the entire network. This means any teachers or professors on multiple sites would be deleted, and the other sites they belong to would be broken
  • There’s a high risk that you could self delete and loose the super admin account
  • There’s a fundamental misunderstanding that you can delete a user from a specific site. It’s not deletion, it’s removal, it’s an important distinction.
  • This does not fix the root problem. A user on site 1 can still log in, which means they are logged into the network, not the specific sub-site. If your check only relies on being logged in then that user can see all courses, as can every other user.

So just redirect the user to a place explaining they haven’t got permission, and make sure the permission checks don’t just check if they’re logged in, but their role too.