This code:
$result = db_query("SELECT p.perm FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid WHERE r.rid IN (". db_placeholders($account->roles) .")", array_keys($account->roles));
will throw errors if $account->roles is not an array yet there is no test to verify that it is an array before running the query.
The errors will be similar to:
warning: array_fill() [function.array-fill]: Number of elements must be positive in /var/www/html/drupal/includes/database.inc on line 253.
warning: implode() [function.implode]: Invalid arguments passed in /var/www/html/drupal/includes/database.inc on line 253.
warning: array_keys() [function.array-keys]: The first argument should be an array in /var/www/html/drupal/modules/user/user.module on line 502.
user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1 query: SELECT p.perm FROM role r INNER JOIN permission p ON p.rid = r.rid WHERE r.rid IN () in /var/www/html/drupal/modules/user/user.module on line 502.
One solution would be to test $account->roles before running the query:
if (!isset($perm[$account->uid]) && isset($account->roles)) {
$result = db_query("SELECT p.perm FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid WHERE r.rid IN (". db_placeholders($account->roles) .")", array_keys($account->roles));
Another solution would be to set $account->roles in the event that it's not set:
if (!isset($perm[$account->uid])) {
if (!isset($account->roles)) {
$account->roles[1] = 'anonymous user';
}
$result = db_query("SELECT p.perm FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid WHERE r.rid IN (". db_placeholders($account->roles) .")", array_keys($account->roles));
Either solution eliminates the warnings. Not sure which (if either) is preferable.
Comments
Comment #1
najibx commentedi'm bumping into this same error when running drush. would it be in drush issue?
"The problem with both this and the other issue may be that the Anonymous user is not in the database. Since there is no anonymous user in the database (in the "users" table) the user information can never be loaded." similar to http://drupal.org/node/377396
Comment #2
pneumatic commentedThanks - your first solution fixed my problem which was that the NTLM single sign on would trigger this error because it was checking permissions before the account was created. I am posting my error log so that others can search for this solution.
Comment #3
danzsmith commentedFirst of all - thanks very much for this! This solution really helped me in a bind...
Secondly, I can now tell you from experience, the second solution, this one:
was prefereable in my scenario. I was using a combination of the webserver_authentication and user_selectable_roles modules and the first solution gave me a white screen with no way to log back in whereas the second solution, dictated above, worked perfectly.
Just wanted to pass that on to everyone...
Thanks again!
Comment #4
mikeytown2 commentedhttp://api.drupal.org/api/function/user_access/6
Because $account is an object assigning it the role of "anonymous user" is not a good idea. Objects are passed by reference so this change will propagate back.
Comment #5
hymanroth commentedIf a user object has no roles then it can't have permissions, right?
So I added one line:
The key thing is not to touch $account or $perm.
If user_access is called again on the same account, but this time with ->roles populated, then the function will still work normally.
Comment #6
j0nathan commentedSame error messages. Subscribing.
Comment #7
verta commentedI am getting this as user 1, on creating a new page. I am testing several modules, so I can't tell yet which one started this, but I am using PHP 5.3.
Page new page has been created.
# warning: array_fill() [function.array-fill]: Number of elements must be positive in includes\database.inc on line 253.
# warning: implode() [function.implode]: Invalid arguments passed in includes\database.inc on line 253.
# warning: array_keys() expects parameter 1 to be array, null given in modules\user\user.module on line 513.
# user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1 query: SELECT p.perm FROM role r INNER JOIN permission p ON p.rid = r.rid WHERE r.rid IN () in modules\user\user.module on line 513.
Edit: turns out cron had not run after enabling Actions. No more error messages.
Comment #8
ppc.coder commentedI was experiencing a similiar problem.
In my case, the problem was for my menu, I passed in 2 permissions like so:
'access arguments' => array('perm1', 'perm2')
What then happens is that in the user_access function
'perm1' is picked up as the permission to test for and 'perm2' is picked up as the $account argument!
Comment #9
qmhao99 commentedI was having the same problem. It appears that the problem went away after I inserted a row in users table with uid=0 and name=anonymous.
Comment #11
chissy commentedSame problem. Occurred when I deleted some users before deleting the content they had created, resulted because anonymous users can't create content. Second solution eliminated the error message but I still have spaces on the page that say "n/a" where the content created by the deleted users would have been, anyone know of a way to get rid of this?
Comment #12
HydroZ commentedHi to all,
please check this post, for my solution, that is possibly fitting to your situations:
http://drupal.org/node/988216
Comment #13
HydroZ commentedHi to all,
please check this post, for my solution, that is possibly fitting to your situations:
http://drupal.org/node/988216
Comment #14
mikedotexe commentedthe
&& isset($account->roles)part was the only piece missing from my user.module. I added that and it works.
You just saved my hindquarters. Thank you.
Comment #15
anarcat commentedWhile I believe that this is a data corruption issue that should be resolved in those specific installs, it doesn't hurt to not *crash* over the wrong data. "Be tolerant in what you receive and conservative in what you send."
I rerolled the patch to have the right suffix and to make sure we actually deny access to those evil corrupted users.
Maybe a warning should be in order here?
Comment #16
anarcat commentedNote that this also applies to Drupal 7, another patch applied just for this, which should apply on 7.x...
Comment #17
droplet commentedComment #18
droplet commented#16: 777116-no-roles-error.patch queued for re-testing.
Comment #19
rasskull commented#15 worked great for me an solved a big problem we were having, thanks!
Comment #20
SchwebDesign commentedThanks a million for this patch #15. that worked for me as well. This issue was very hard to debug on my site and this post was a HUGE help, thanks everyone.
Comment #21
fugazi commentedpatch # 15 works well for me many thanks to Drupal 6
Comment #22
anarcat commentedComment #23
xjmThanks for the patch!
It looks like #16 won't apply to Drupal 8. Also, I think we should add an automated test for this.
Tagging as novice to reroll for D8 and add an automated test.
Comment #24
emclaughlin commentedHere's a reroll at least. If I figure out how to add an automated test I'll come back and do that, but fair game for now.
Comment #25
xjmThanks @emclaughlin! Setting to Needs Review so that the bot tests it.
Comment #26
xjmAlright, back to NW for an automated test.
Comment #27
oriol_e9gTest added.
Comment #28
oriol_e9gComment #29
xjmThanks @oriol_e9g! Sending to testbot.
Comment #31
xjmCool, the test-only patch fails and the combined patch passes, as expected.
Comment #32
virtuali1151 commented# 15 fixed my error as well... TK U!!!
Comment #33
oriol_e9g@virtuali1151 Reviewed & tested by the community?
Comment #34
oriol_e9gcrosspost :/
Comment #35
virtuali1151 commentedShouldnt this be commited core..? Just ran across the same prob again when upgrading to 6.25.....
Comment #36
xjm@virtuali1151, the patch needs to be reviewed before it can be committed.
I've gone back and forth over whether this patch is babysitting broken code. In the end, I think
$account->rolesbeing set as an empty array is actually the correct behavior for a "roleless" user (whatever that means), so we should respond to that sensibly. The fix is also nice and clean.Comment #37
catchI'm not sure about this at all. As far as I know there's no valid situation where a user has no roles at all - since every user has either the authenticated or anonymous role which are hard-coded. There are no links to bugs in the contrib modules that are hitting this error from this issue, and the patch means that they'll just fail silently rather than throwing a useful error message, meaning there's no incentive at all to track down the actual cause of the problem once this goes in.
Comment #38
xjmSo I guess then the solution is instead to try to determine which users are missing roles, and what code (probably a contributed module) is creating or altering them?
Comment #39
Dthorndyke commentedAt last! A solution to my issues! Thank you tons ppc.coder : )
Specifying only a single permission to access arguments cleared up these error messages as well as properly displaying my module tabs, which I had spent considerable time looking into.
Just wanted to second this solution to the problem for any other weary souls that haven't found a suitable solution for their situation.
'access arguments' => array('perm1')Worked for me!
Comment #40
James Marks commentedHydroZephalus (Comment #12) found the same thing: http://drupal.org/node/988216
Are these errors related to/caused by the situation where UID 0 is missing from the users table? (http://drupal.org/node/1029506, http://drupal.org/node/204411)
Comment #41
emclaughlin commentedYes, they appear to be.
Comment #42
ailgm commentedI'm hitting these errors (in D6.26) and do have UID 0 in the users table. There is no row for that user in the users_roles table, but that appears to be normal.
Comment #43
kenorb commentedI've the same errors in Pressflow 6.22 while running simpletests.
The following code:
expects that user has always some role.
Please backport it into 6.x as well.
Comment #44
kenorb commentedAfter debugging, my case was related to simpletest_clone module.
So simply my table didn't have UID = 0 and 1. Also global $user variable was NULL.
Link: #1784638: Simpletest: User created with errors (array_fill, implode, array_keys, SQL error)
If any of you have this error, make sure that:
- you have user with UID = 0 in your
userstable (sometimes it's removed by some weird modules containing bugs),- you have user with UID = 1 in your
userstable,- before calling user_access(), make sure that your global $user is not empty or overriden by some other code,
Comment #47
dpiThis will no longer happen in D8 since
$user->getRoles()is guaranteed to return an array.The problematic query no longer exists in D7, and it also appears that role is always an array in D7, and it is prepopulated with authenticated or anonymous roles (See
\UserController::attachLoad)