Skip to: Site menu | Main content

Role Playing: Clear the Cache

Maybe this was covered somewhere on awhile back, but either I wasn't searching using the correct terms or I just plain missed it. I'm talking about how to avoid issues when programmatically modifying user roles.

I was working on a module that automatically adds and removes user roles when certain conditions are met. The code to remove and add a user role is pretty straight-forward:

db_query("DELETE FROM {users_roles} WHERE uid = %d AND rid = %d", $user->uid, $rid_to_delete);
db_query("INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)", $user->uid, $rid_to_add);

I thought this was all I needed to do. My initial testing didn't find anything unexpected, so I moved on to something else.

A short time afterwards, I saw a report of users being granted the new user role, but not being able to immediately use the permissions granted to them via the new role.

I soon figured out that the new permissions would only kick in once the user logged out and then logged back in. What I ended up figuring out was that the user's menu array was being cached - and despite the changes I made to the users_roles table, the user's menu cache was unchanged.

Once I looked in user.module to see how core handles the issue, the solution was simple - clear the user's menu cache right after the role changes and all is well:

db_query("DELETE FROM {users_roles} WHERE uid = %d AND rid = %d", $user->uid, $rid_to_delete);
db_query("INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)", $user->uid, $rid_to_add);
// Delete that user's menu cache:
cache_clear_all($account->uid .':', 'cache_menu', TRUE);

Actually, the user.module also clears the page cache to avoid having any stale data (usernames and profile) in the cache:

// Clear the page cache because pages can contain usernames and/or profile information:

In my case where just the roles had changed, I felt this was unnecessary.

Submitted by michael on Mon, 05/12/2008 - 1:43pm
Filed under: