Assigning user to roles programatically
I'm looking for some way to assign a user to a role programatically. You'd think this would be easy to do, but it isn't: I tried just about every drupal hook you can think of to hook add this to the "user add" and "user edit" screens, and nothing worked. The problem was that node_save really really really wanted to get in there last, and I never found a way to get around this. I even tried to stamp the fields into the database. No use. node_save just went in at the end of the request and changed it back for me :-( Does anyone know how to coerce Drupal 4.6 into doing this? Or sweet talk it into this? It would be nice if there was an API for this, but AFAIK there isn't. What hook should I use, and which 2x4 do I need to apply? Thanks, Rob Thorne Torenware Networks
On 1/26/06, Rob Thorne <rob@torenware.com> wrote:
I'm looking for some way to assign a user to a role programatically. You'd think this would be easy to do, but it isn't: I tried just about every drupal hook you can think of to hook add this to the "user add" and "user edit" screens, and nothing worked. The problem was that node_save really really really wanted to get in there last, and I never found a way to get around this. I even tried to stamp the fields into the database. No use. node_save just went in at the end of the request and changed it back for me :-(
Does anyone know how to coerce Drupal 4.6 into doing this? Or sweet talk it into this? It would be nice if there was an API for this, but AFAIK there isn't. What hook should I use, and which 2x4 do I need to apply?
Here are two functions that I used for a customer project that do just that: function mymodule_role_join($uid, $rid) { db_query("INSERT INTO {users_roles} (rid, uid) VALUES ('%d', '%d')", $rid, $uid); } function mymodule_role_leave($uid, $rid) { db_query("DELETE FROM {users_roles} WHERE rid = %d AND uid = %d", $rid, $uid); }
Khalid B wrote:
On 1/26/06, Rob Thorne <rob@torenware.com> wrote:
I'm looking for some way to assign a user to a role programatically. You'd think this would be easy to do, but it isn't: I tried just about every drupal hook you can think of to hook add this to the "user add" and "user edit" screens, and nothing worked. The problem was that node_save really really really wanted to get in there last, and I never found a way to get around this. I even tried to stamp the fields into the database. No use. node_save just went in at the end of the request and changed it back for me :-(
Does anyone know how to coerce Drupal 4.6 into doing this? Or sweet talk it into this? It would be nice if there was an API for this, but AFAIK there isn't. What hook should I use, and which 2x4 do I need to apply?
Here are two functions that I used for a customer project that do just that:
function mymodule_role_join($uid, $rid) { db_query("INSERT INTO {users_roles} (rid, uid) VALUES ('%d', '%d')", $rid, $uid); }
function mymodule_role_leave($uid, $rid) { db_query("DELETE FROM {users_roles} WHERE rid = %d AND uid = %d", $rid, $uid); }
Khalid, Much thanks. Although... I'm taking it that you don't tie this into the regular user add process, however.... since I've tried that approach already. You write the entry into user_roles, and node_save helpfully deletes your records for you immediately after :-( When do you call these functions? As part of which hook? I had tried to add it to the "user add" admin page using hook_user, but as Yoda once said, "Work it did not". Thanks, Rob
That is the caveat: I did not do it at user signup time, but rather as to assign the user to a role when certain conditions are met. I vaguely remember two modules: one to assign the user a role automatically at signup, and another to assign them to a pre-defined "in limbo" role (something between authenticated user and anonymous user). The idea is to keep them in this role before they are given full privilege so as to weed out the trolls. Can't remember the names though, and my PC is too slow for me to check it. On 1/26/06, Rob Thorne <rob@torenware.com> wrote:
Khalid B wrote:
On 1/26/06, Rob Thorne <rob@torenware.com> wrote:
I'm looking for some way to assign a user to a role programatically. You'd think this would be easy to do, but it isn't: I tried just about every drupal hook you can think of to hook add this to the "user add" and "user edit" screens, and nothing worked. The problem was that node_save really really really wanted to get in there last, and I never found a way to get around this. I even tried to stamp the fields into the database. No use. node_save just went in at the end of the request and changed it back for me :-(
Does anyone know how to coerce Drupal 4.6 into doing this? Or sweet talk it into this? It would be nice if there was an API for this, but AFAIK there isn't. What hook should I use, and which 2x4 do I need to apply?
Here are two functions that I used for a customer project that do just that:
function mymodule_role_join($uid, $rid) { db_query("INSERT INTO {users_roles} (rid, uid) VALUES ('%d', '%d')", $rid, $uid); }
function mymodule_role_leave($uid, $rid) { db_query("DELETE FROM {users_roles} WHERE rid = %d AND uid = %d", $rid, $uid); }
Khalid,
Much thanks. Although...
I'm taking it that you don't tie this into the regular user add process, however.... since I've tried that approach already. You write the entry into user_roles, and node_save helpfully deletes your records for you immediately after :-(
When do you call these functions? As part of which hook? I had tried to add it to the "user add" admin page using hook_user, but as Yoda once said, "Work it did not".
Thanks, Rob
On Thu, 2006-01-26 at 21:50 -0500, Khalid B wrote:
That is the caveat: I did not do it at user signup time, but rather as to assign the user to a role when certain conditions are met.
I vaguely remember two modules: one to assign the user a role automatically at signup, and another to assign them to a pre-defined "in limbo" role (something between authenticated user and anonymous user). The idea is to keep them in this role before they are given full privilege so as to weed out the trolls.
Can't remember the names though, and my PC is too slow for me to check it.
I think logintoboggan is one.
On 27 Jan 2006, at 4:39 AM, Rob Thorne wrote:
When do you call these functions? As part of which hook? I had tried to add it to the "user add" admin page using hook_user, but as Yoda once said, "Work it did not".
The problem with doing it as part of the user hook is that it saves at the very end of the hook. and one of the things the user hook does is delete all the roles and then add only the new ones. You can still modify the $edit variable and change what was 'actually submitted'. function module_user($op, &$edit, &$user) { switch ($op) { case 'insert' : $edit['roles'][_user_get_rid('administrator')] = ''; $edit['roles'] = array_flip(array_keys($edit['roles'])); // I am not sure it's strictly necessary, but it maintains the format that the modules are expecting, so it can't hurt break; } } function _user_get_rid($name) { return db_result(db_query("SELECT rid FROM {role} WHERE name ='%s' limit 1", $name)); } -- Adrian Rossouw Drupal developer and Bryght Guy http://drupal.org | http://bryght.com
It sounds like this would be a valuable asset to core (post 4.7 please :))
function module_user($op, &$edit, &$user) { switch ($op) { case 'insert' : $edit['roles'][_user_get_rid('administrator')] = ''; $edit['roles'] = array_flip(array_keys($edit['roles'])); // I am not sure it's strictly necessary, but it maintains the format that the modules are expecting, so it can't hurt break; } }
Bèr -- [ Bèr Kessels | Drupal services www.webschuur.com ]
These functions should be in core. It would make addressing http://drupal.org/node/40546 trivial. As a general thought, I think roles should be given "first class status" next to users and nodes. Providing a "role API" would allow the graceful improvement of the role system, behind the scenes. In the current scenario roles are usually just treated as attributes of users, not separate and worthy equals. Of course, this is just my $.02. I'll spend some time pondering this - I think 4.8 could make some major gains in this area. -M
Here are two functions that I used for a customer project that do just that:
function mymodule_role_join($uid, $rid) { db_query("INSERT INTO {users_roles} (rid, uid) VALUES ('%d', '%d')", $rid, $uid); }
function mymodule_role_leave($uid, $rid) { db_query("DELETE FROM {users_roles} WHERE rid = %d AND uid = %d", $rid, $uid); }
On 27 Jan 2006, at 4:14 AM, Rob Thorne wrote:
Does anyone know how to coerce Drupal 4.6 into doing this? Or sweet talk it into this? It would be nice if there was an API for this, but AFAIK there isn't. What hook should I use, and which 2x4 do I need to apply?
Just did this recently : ----- snip --- $user = user_load(array('uid' => $uid)); $edit['roles'][] = _user_get_rid('administrator'); user_save($user, $edit); ---- snip --- function _user_get_rid($name) { return db_result(db_query("SELECT rid FROM {role} WHERE name ='%s' limit 1", $name)); } I needed to use the user api since I have more specific rules that I check for. IE: you can be one of the following 3 roles, in a certain order of preference, but never more than one. -- Adrian Rossouw Drupal developer and Bryght Guy http://drupal.org | http://bryght.com
Much thanks to Adrian and Khalid for their help on this. It turns out that both of you are right, but for different code paths in hook_user. Here's what seems to work in 4.6: * On $op == 'update', Adrian is correct: the right way to do this is to stuff the rid into the $edit structure ($edit['roles'][] = $my_rid;) * On $op == 'insert', Adrian approach doesn't work, because user_save has already done everything it will ever do with the user_roles table. So in that case, you need to do what Khalid suggests: INSERT a row into the user_roles table. Now that I'm doing both of these things, I'm getting correct behavior on both registration of new users and update of existing users. Thanks, Rob Adrian Rossouw wrote:
On 27 Jan 2006, at 4:14 AM, Rob Thorne wrote:
Does anyone know how to coerce Drupal 4.6 into doing this? Or sweet talk it into this? It would be nice if there was an API for this, but AFAIK there isn't. What hook should I use, and which 2x4 do I need to apply?
Just did this recently :
----- snip --- $user = user_load(array('uid' => $uid)); $edit['roles'][] = _user_get_rid('administrator');
user_save($user, $edit); ---- snip ---
function _user_get_rid($name) { return db_result(db_query("SELECT rid FROM {role} WHERE name ='%s' limit 1", $name)); }
I needed to use the user api since I have more specific rules that I check for. IE: you can be one of the following 3 roles, in a certain order of preference, but never more than one.
-- Adrian Rossouw Drupal developer and Bryght Guy http://drupal.org | http://bryght.com
On 30 Jan 2006, at 12:39 AM, Rob Thorne wrote:
* On $op == 'insert', Adrian approach doesn't work, because user_save has already done everything it will ever do with the user_roles table. So in that case, you need to do what Khalid suggests: INSERT a row into the user_roles table. Yup. you're correct.
I tracked through the code and found out that userapi $op='insert' is called after the user_save function. Same with node. Reason being user_save and node_save is where they get the $uid / $nid, which is needed for saving the rest of the data. Love these fun inconsistencies =) -- Adrian Rossouw Drupal developer and Bryght Guy http://drupal.org | http://bryght.com
* On $op == 'insert', Adrian approach doesn't work, because user_save has already done everything it will ever do with the user_roles table. So in that case, you need to do what Khalid suggests: INSERT a row into the user_roles table.
Is anyone else bothered that you have to make db call to do this? Where's the API fever when we need it? This code breaks on a data base schema change. Abstracting the call to an API function makes code future compatible. Of course, talk is cheap, code is gold... So I'll shut my big mouth for now. But for those of you going to Vancouver, please, please put roles API on the road map for 4.8. -M
On 30 Jan 2006, at 5:39 PM, Mark Fredrickson wrote:
Of course, talk is cheap, code is gold... So I'll shut my big mouth for now. But for those of you going to Vancouver, please, please put roles API on the road map for 4.8.
nah. what i have in mind is more EverythingAPI. if you can do it from a form, you can do it from code. and vice versa. -- Adrian Rossouw Drupal developer and Bryght Guy http://drupal.org | http://bryght.com
On 1/30/06 10:39 AM, Mark Fredrickson wrote:
* On $op == 'insert', Adrian approach doesn't work, because user_save has already done everything it will ever do with the user_roles table. So in that case, you need to do what Khalid suggests: INSERT a row into the user_roles table.
Is anyone else bothered that you have to make db call to do this? Where's the API fever when we need it? This code breaks on a data base schema change. Abstracting the call to an API function makes code future compatible.
Of course, talk is cheap, code is gold... So I'll shut my big mouth for now. But for those of you going to Vancouver, please, please put roles API on the road map for 4.8.
on that front - a set of hooks for role insert/update/delete would be real handy. -- James Walker :: http://walkah.net/ :: xmpp:walkah@walkah.net
participants (7)
-
Adrian Rossouw -
Bèr Kessels -
Darrel O'Pry -
James Walker -
Khalid B -
Mark Fredrickson -
Rob Thorne