onBeforeSaveUser vs onSaveUser I'm trying to make a very basic plugin that will send an email alert to a User if an Admin changes their User Group.

I thought I could use the onBeforeSaveUser to get the User's current User Group, and then use the onSaveUser event to compare that with the Event's User Group - and then if they differ, do the mail sending.

It doesn't work, and I don't know why. Both events always get the same value for the User Group. What am I not understanding correctly?

private $existingGroups = NULL;

public function init()
{
    craft()-&gt;on('users.onBeforeSaveUser', function(Event $event) {
        $eventUser = $event-&gt;params['user']; // get the user we are editing

        $user = craft()-&gt;users-&gt;getUserById($eventUser-&gt;id); // get that user's existing information, before we edit it

        $this-&gt;existingGroups = $user-&gt;getGroups(); // store the groups the User belongs to
        GroupNotificationPlugin::log("existingGroup: " . $this-&gt;existingGroups[0]-&gt;name, LogLevel::Info);
    });

    craft()-&gt;on('users.onSaveUser', function(Event $event) {
        $user = $event-&gt;params['user']; // get the user we are editing

        GroupNotificationPlugin::log("Was: " . $this-&gt;existingGroups[0]-&gt;name, LogLevel::Info);
        GroupNotificationPlugin::log("Now: " . $user-&gt;getGroups()[0]-&gt;name, LogLevel::Info);

        if($this-&gt;existingGroups[0]-&gt;name != $user-&gt;getGroups()[0]-&gt;name){
            GroupNotificationPlugin::log("Changing group", LogLevel::Info);
        }
    });
}


Was: XXX and Now: XXX are always reporting the same, even when I know that I have changed the User Group (unchecking the old one, checking a new one, saving).
The problem is that both onSaveUser and onBeforeSaveUser get fired from UsersService->saveUser() and user group assignment happens in the UsersController->actionSaveUser() after UsersService-&gt;saveUser() has already been called.

You should probably be using onBeforeAssignUserToGroups and onAssignUserToGroups instead.