欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

hook_menu and multiple access arguments array two 两个参数 用法 自定义 有大用 有大大用 有大大大用

shiping1 的头像

hook_menu, access arguments; cannot use multiple, like: Array('perm1','perm2')

 

// Add this in hook_menu
'access arguments' => array(array('role1', 'role2')), // passing roles
'access callback' => 'custom_permission_access', // callback custom method for granting permission

//callback method
function custom_permission_access($roles){
    if (user_is_logged_in()) {
global $user;  if($user->uid==1){  return TRUE;  }  foreach ($roles as $role) {  if (in_array($role, $user->roles)) {  return TRUE;  }  }  }  return FALSE;
}
 
 

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

 

dawehner’s picture

 

 

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:

 

function my_access_check($arr_perms) {
	$bool = true; //Must init to true.
	
	for($i=0; $i<sizeof($arr_perms); $i++){
		$bool = $bool && user_access($arr_perms[$i]);
		if($bool===false){
			return false;
		}
	}
	
	//Passed all checks.
	return true;
}

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')?

dawehner’s picture

 

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.

 

function MODULENAME_user_access($string, $account = NULL, $reset = FALSE) {
  global $user;
  static $perm = array();

  if ($reset) {
    $perm = array();
  }

  if (is_null($account)) {
    $account = $user;
  }

  // User #1 has all privileges:
  if ($account->uid == 1) {
    return TRUE;
  }

  // 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 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));

    $perms = array();
    while ($row = db_fetch_object($result)) {
      $perms += array_flip(explode(', ', $row->perm));
    }
    $perm[$account->uid] = $perms;
  }

  // If $string is an array, then check each one.
  if( is_array( $string ) ) {
    
	// Loop through each value in the array and return true if there are any matches
	foreach( $string as $value ) {
	  $has_access = isset($perm[$account->uid][$value]);
	  if( $has_access ) return $has_access;
	}
  } else {
    return isset($perm[$account->uid][$string]);
  }
}

I haven't had time to test it thoroughly but my initial tests were good.

In your menu item put this:

  'access callback' => 'MODULENAME_user_access',
  'access arguments' => array( array( 'PERM1', 'PERM2') ),
dawehner’s picture

 

 

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.

dawehner’s picture

 

 

 


// Add this in hook_menu
'access arguments' => array(array('role1', 'role2')), // passing roles
'access callback' => 'custom_permission_access', // callback custom method for granting permission

//callback method
function custom_permission_access($roles){
    if (user_is_logged_in()) {
        global $user;  
        foreach ($roles as $role) {
            if (in_array($role, $user->roles)) {
                return TRUE;
            }
        }
    }
    else {
        return FALSE;
    }
}


来自  https://www.drupal.org/node/368584
 


hook_menu and multiple access arguments

I have created a menu hook. I want to have the page available to anyone with either access level A or access level B. Both have been defined in hook_perm and hook_access.

But, I keep getting errors when I try to add the second access argument. Does anybody know if this is possible, and if it is, can you show me the syntax that I use to do it? Thank you.

Comments

dawehner’s picture

Well without an example of the code you are trying to use the best I have is this:

From here --> http://api.drupal.org/api/function/hook_menu/6

"access arguments": An array of arguments to pass to the access callback function. Integer values pass the corresponding URL component.

It says the arguments are an array. Sample code from that same page shows:

  $items['blog'] = array(
    'title' => 'blogs',
    'page callback' => 'blog_page',
    'access arguments' => array('access content'),
    'type' => MENU_SUGGESTED_ITEM,
  );

So to have 2 arguments it would look like this:
  $items['blog'] = array(
    'title' => 'blogs',
    'page callback' => 'blog_page',
    'access arguments' => array('access content', 'new argument'), // <-- notice the comma and the new argument added to the array.
    'type' => MENU_SUGGESTED_ITEM,
  );
Jaypan’s picture

That's exactly what I was looking for. Thank you.

Think the Drupal forums suck? Add your agreement here:https://www.drupal.org/node/2641072

dawehner’s picture

Check out the API it will help you a lot.

dawehner’s picture

Very strange, I exactly do it like you said and I get SQL errors. Here is the code hook_menu:

 

'access arguments' => array('create article content', 'create event content'),

And that are the SQL errors I get:

  • 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 /REMOVED/modules/user/user.module on line 502.

  • array_keys() [function.array-keys]: The first argument should be an array in /REMOVED/modules/user/user.module on line 502.

  • implode() [function.implode]: Invalid arguments passed in /REMOVED/includes/database.inc on line 241.

  • array_fill() [function.array-fill]: Number of elements must be positive in /REMOVED/includes/database.inc on line 241.

If I remove the second permission from the statement above, it works fine. Any ideas what is going wrong?

karenann’s picture

Found this thread while trying to do this. Wanted to post the solution for others who stumble on this.

Despite what's said above, you can't pass multiple access arguments like this. Also, don't bother trying array(array('perm 1', 'perm 2')).

By design, the access arguments's 2nd parameter is the $account param. That's why you can't pass 2 permissions that way.

You have to use 'access calback' instead and create a function that way.

Check out this post (it's right on):http://drupal.org/node/368584#comment-1236208

dawehner’s picture

'access arguments' => array('edit own blah content, edit any blah content')

Notice that the two arguments are in the same quotes separated by a comma.

It works for me.

dawehner’s picture

only works for admin

dawehner’s picture

Don't use 'access arguments' => array('edit own blah content, edit any blah content'), that won't work unless you're the admin or you have a permission specifically defined in hook_perm called 'edit own blah content, edit any blah content'. The only way to accomplish this is to use your own access callback function then you can do whatever you want. karenann has the correct answer...


来自  https://www.drupal.org/node/327967
 

 


普通分类: