I cannot determine why this will not work for me in hook_menu:
...
'access callback' => 'user_access',
'access arguments' => array('perm1', 'perm2'),
...
Also, these permissions have been declared in hook_perm. I tried clearing cache, etc.
If I use just Array('perm1') it works fine.
"Not work" means I get errors after re-loading the module with the multiple permissions set. From the modules window upon re-loading:
--------
* warning: array_fill() [function.array-fill]: Number of elements must be positive in G:\WampServer\www\site\includes\database.inc on line 241.
* warning: implode() [function.implode]: Invalid arguments passed in G:\WampServer\www\site\includes\database.inc on line 241.
* warning: array_keys() [function.array-keys]: The first argument should be an array in G:\WampServer\www\site\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 G:\WampServer\www\site\modules\user\user.module on line 502.
--------
Comments
user_access parameters
If you look at the user_access function parameters, you'll understand. The second argument in the array, is passed as the $account param.
Make your own access callback instead:
--
The Manual | Troubleshooting FAQ | Tips for posting | How to report a security issue.
custom access check
Thanks. I'm a new Drupal developer and this has taught me to analyze the API better before raising a question. Per your suggestion, I wrote a custom function to do the check:
I can see later adding a 2nd arg to handle whether ALL perms are required or ANY of them (&& vs ||). BTW, how would I pass two args--would I use
Array(Array('perm1','perm2'),'ANY')?quick question (on passing args)
That code snippet I placed above did not work. I'm unable to figure out how to pass multiple args to a custom function. I'm also unable to figure out how to pass a single array. (in the context spoken of above). Please help anyone!
Here is my custom function
I took the core user_access function (Drupal 6) and modified it slightly to check to see if the $string argument was an array. This way I could pass more then 1 value into it.
I haven't had time to test it thoroughly but my initial tests were good.
In your menu item put this:
Multiple menu access arguments
I ran into the same problem, where I wanted to use multiple arguments. I think I figured this out, at least in Drupal 7. Using user_access as the callback didn't work. But looking at the code in menu.inc, I found that it uses the PHP function call_user_func_array(). The call to call_user_func_array() indeed passes the array of permissions as the second argument, but the array doesn't get passed as an array to the callback. Instead, the callback receives a variable number of arguments.
I solved this as follows, using PHP's func_num_args() and func_get_arg() functions:
function my_callback() {
for ($i = 0; $i < func_num_args(); $i++) {
$perm = func_get_arg($i); // get permission
// check permission via user_access
if (user_access($perm)) {
return TRUE; // return TRUE on first success
}
}
return FALSE; // return FALSE if no permission passes
}
This is a general solution for a variable number of arguments. If you know for sure that you only have two arguments, you could code your callback as:
function my_callback($perm1, $perm2)
Multiple menu access arguments
Or slightly more compact:
function my_callback() {
foreach (func_get_args() as $perm) {
if (user_access($perm)) {
return TRUE;
}
}
return FALSE;
}
func_get_args() returns the arguments as an array, so the familiar foreach construct can be used.
Eh, no. You can shortcut on
Eh, no.
You can shortcut on the FALSE (ie !user_access($perm)), but not on the TRUE condition (edited to add) unless you really want to grant access to users with anyone of the permissions, not all of them.
Working for my use case
Yes, in my case, I want to grant access if any one of the permissions are valid for the user. My main point, though, is that you can indeed process multiple permissions-- they just don't come in as an array to the callback function, and you can use the standard PHP functions to pull the arguments.
<?php// Add this in hook_menu