When a user receives a new role or loses a role, hook_user('update'...) is invoked. This behavior is not consistent when a role is deleted. In that case, the role is deleted from the database without invoking hook_user on each user with that role.

This can lead to unexpected results for modules that use roles to add functionality. A good example would be user_badges, and a module I am developing to create/manage organic groups based on roles.

To recreate this issue, just create a dummy module (say, testmod) with this function:

function testmod_user($type, &$account, &$edit, $category) {
drupal_set_message("For $account->uid, a $type operation was invoked.");
}

First create a test role and add a user to that role. THe module will indicate that an update has been called.

Now, delete the role. The module is not invoked.

Comments

adrian’s picture

The role deletion would need to run user_save for all the users.

or something similarly.

it would be very expensive most likely.

mfredrickson’s picture

Hmm. Not necessarily. If there is a "user_role_add" and "user_role_delete" function which does not call user_save (as it doesn't touch the user table), I don't see what it would be that expensive. 1 query to get all the users in a group. A loop to call user_role_delete on each user. A basic implementation of user_role_delete would be a single query, with the opportunity to change this later.

I would advocate for an entire role API, standardizing role interactions for the whole system. These two functions would be the beginning.

mfredrickson’s picture

I should reread my own issues. I am asking that hook_user get called. Yes, that would be expensive, but I'm not sure this is a convincing argument against doing it. Role deletion is infrequent (I suspect), but the results are very beneficial to role related modules.

-M

killes@www.drop.org’s picture

Status: Active » Closed (won't fix)

There is no sane way of doing this. We have 60000 uses here on drupal.org. I've no idea how long loading and saving each would take, but i am afraid this would exhaust the php time limit.