I am working on a module that will allow multiple users to have superuser access (uid 1 access).
Eventually, this code will be moved to a module, but for now I am modifying the core to make sure my code is right. PLEASE DO NOT POST HERE TELLING ME THAT CORE HACKING IS A BAD IDEA... I know that... this is temporary.
I added a few lines to user_access() which is in modules/user/user.module. The SQL query there will return a single column and single row with the value "superuser" if the user id in question has been assigned the role "superuser." If not, the SQL query should return an empty set. After adding this code in, I am getting a ton of errors that all say: user warning: Query was empty query: [snip/]. Can anyone tell me how to avoid this error?
function user_access($string, $account = NULL) {
global $user;
static $perm = array();
if (is_null($account)) {
$account = $user;
}
// User #1 has all privileges:
if ($account->uid == 1) {
return TRUE;
}
/********** START MY CODE **********/
// Users with role 'superuser' have all privileges
$is_superuser_query = "SELECT DISTINCT(sr.name) FROM {users_roles} ur, {shared_role} sr WHERE ur.uid=$account->uid and ur.rid = sr.rid and sr.name = 'superuser';";
$is_superuser = db_query($check_if_superuser_query);
if ($is_superuser) {
return TRUE;
}
/********** END MY CODE **********/
// To reduce the number of SQL queries, we cache the user's permissions
// in a static variable.
if (!isset($perm[$account->uid])) {
$result = db_query("SELECT DISTINCT(p.perm) FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid WHERE r.rid IN (%s)", implode(',', array_keys($account->roles)));
$perm[$account->uid] = '';
while ($row = db_fetch_object($result)) {
$perm[$account->uid] .= "$row->perm, ";
}
}
if (isset($perm[$account->uid])) {
return strpos($perm[$account->uid], "$string, ") !== FALSE;
}
return FALSE;
}
Comments
You need to read your own
You need to read your own source. You create a variable called $is_superuser_query with SQL in it but you pass to db_query() $check_if_superuser_query which doesn't exist. Just like the error message says, it's empty (variables that don't exist are instaniated NULL).
Also, this makes no sense:-
If you have a valid return the if() will always validate true. You need to *do something* with the returned result. (like db_fetch_array($is_superuser), db_num_rows($is_superuser), whatever).
Also, I will say it regardless, don't hack core ;)
Ahh, yeah that was an old
Ahh, yeah that was an old version of the code, sorry. The more current version at the time of writing that post used the correct variable name, but still did not work.
Here's the correct version. You have to leave the { }'s out of the SQL query or else Drupal will replace your table names with the appropriate 'shared_' tables (which defeats the whole purpose of this code).
I learned on IRC yesterday that it's actually impossible to override the method user_access() and impossible to hook into it directly. So it looks like I'll be placing a copy of my modified user module in my sites/all/modules folder to override the core code without actually editing the original file. Looks like that's the best that can be done without bringing in PECL or something.
> If you have a valid return the if() will always validate true.
That's what I was going for, in a manner of speaking. I was hoping that db_query('query that returns an empty set') would return 0, null, or false... all of which evaluate to false in an if statement, but apparently that is not the case.