4

I'm trying to add a menu link (admin/people/create?operator=1) to the Main Menu only for the user role of 'Supervisor.'

I have tried to do this:

function mymodule_menu_alter(&$items) {

 if(in_array('Supervisor', array_values($user->roles)))
   $items['admin/people/create?operator=1']['type'] = {idk what goes here};

}

But I'm not sure I am on the right track.

2 Answers 2

11

I take you added a link to the main menu, and you want to make it appear only when the user has the right permission. In that case, hook_menu_alter() is not the right hook to implement because:

  • It is not used to override the links added to that menu
  • It is not possible to use admin/people/create?operator=1 as path for the menu link in hook_menu() or hook_menu_alter()

What you should do, after you added the link to the main menu, is to enable a module that contains the following code.

function mymodule_menu_link_alter(&$link) {
  if ($link['link_path'] == 'admin/people/create?operator=1' && $link['module'] == 'menu') {
    $link['options']['alter'] = TRUE;
  }    
}

function mymodule_translated_menu_link_alter(&$link) {
  if ($link['link_path'] == 'admin/people/create?operator=1' && $link['module'] == 'menu' && user_access('use advanced user creation link')) {
    $link['hidden'] = 1;
  }
}

function mymodule_permission() {
  return array(
    'use advanced user creation link' => array(
      'title' => t('Use advanced user creation link'), 
    ),
  );
}

The $link['module'] == 'menu' part allows to alter the link that you manually added in the main menu, and not other links (i.e. added from a module). In the first function, $link['options']['alter'] = TRUE tells Drupal to invoke hook_translated_menu_link_alter() for that link; in the second function, which is actually an implementation of hook_translated_menu_link_alter(), while the first function is the implementation of hook_menu_link_alter(), $link['hidden'] = 1 actually hides the menu to the currently logged-in user.
Instead of "use advanced user creation link," you can use another permission string; as long as the permission is only given to the roles that need it, and it is unique, you can use any string you want.

I didn't find one, but if there is a module that makes the links added to the main menu visible to users with specific roles, I would use that, instead.

As side note, checking for a permission is preferable to checking for the roles the logged-in user has. The reason is that when you check for permissions, the code is always similar to if (user_access('permission to check')) {} whatever roles have that permission, while when you check for roles, the code could change from if (in_array('supervisor', array_values($user->roles))) {} to if (in_array('supervisor', array_values($user->roles)) || in_array('another role', array_values($user->roles))) {}; in other words, you are hardcoding something that you could change in the future.

8
  • The problem is that Operators and Supervisors both need to have access to admin/people/create. So they both have the permission to create users. Only Supervisors should have a menu item admin/people/create?operator=1. I don't know what permission to put in the user_access() function such that only Supervisors have that menu item.
    – Mike
    May 23, 2012 at 16:17
  • otherwise this would be what I need. Do you have any idea on what I could put in user_access(). Also, even though it is not prefered, could I replace the user_access() call with in_array('Supervisor', array_values($user->roles))?
    – Mike
    May 23, 2012 at 16:19
  • I made a design compromise and just put the link into a block and added the block to a page that only supervisors have access to. I don't see ever running into this problem again as it was such a unique situation.
    – Mike
    May 23, 2012 at 16:32
  • 1
    You can check for the roles the logged-in user has, as long as you know the limits of what you are doing (see the updated answer). I have forgotten the part about the permission; I added the code for that.
    – apaderno
    May 23, 2012 at 16:39
  • Very good point about hard coding for checking roles.
    – Mike
    May 23, 2012 at 16:45
0

There is the Menu Per Role module which allows you to define the roles allowed to see each menu item. You either define for which roles to show it, or for which roles to hide it. For other roles, it stays with the default. Here is a screenshot of the settings screen:

Menu item settings screen

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.