I'm looking for a way to hide/show a link from the main-menu if the current user has a specific permission. The menu item has already been created and the menu item links to a node that is controlled by hook_node_access().
-
To what does the menu item link?– avpaderno ♦Commented Jul 28, 2011 at 13:05
-
It links to a Node but the node access rules are defined in hook_node_access() as I already have node_access rules defined by another module. I'm using hook_node_access() to restrict a node to users that have a specific permission.– CamsoftCommented Jul 28, 2011 at 14:03
3 Answers
By default, Drupal will hide all menu items that the user doesn't have access to, so the easiest thing to do, it to require the selected access for the page that the menu item is linking to.
-
Unfortunately this won't do as the node is not using the node_access table and is using hook_node_access() instead and it seems the menu permissions ignore the hook_node_access() function.– CamsoftCommented Jul 28, 2011 at 14:02
-
Hook_node_access only works for the module defining the node IIRC. Commented Jul 28, 2011 at 14:26
-
In Drupal 7, hook_node_access() can be implemented from any module, not only the ones defining a content type.– avpaderno ♦Commented Jul 28, 2011 at 14:46
-
1hook_node_access() can be implemented from any module and will prevent access to the node if implemented correctly. But unfortunately this doesn't concern the generation of the menu items. If you look at the code of menu_tree_check_access then you see, that it uses a select query with the tag
node_access
in order to retrieve access rights. So simply implementinghook_node_access()
won't do it.– berlinerCommented Aug 1, 2014 at 20:56
What you can do is to alter the access callback associated with "node/%node" using hook_menu_alter(), and then writing the code for your access callback basing on the code of node_access(). There are specific cases that you still want to handle as node_access()
does; for example, users with the "bypass node access" permission would always access the node.
function mymodule_menu_alter(&$items) {
if (isset($items['node/%node'])) {
$items['node/%node']['access callback'] = 'mymodule_node_access';
}
}
Consider that the access callback decides who can see a link, and who can access a page when the user writes the URL directly in the browser address bar.
You might want to consider drupal module menu_item_visibility
To quote the project page:
For example, if you want to create a 'My account' link that points to /user, both anonymous and registered users have access to the /user path, so both will see the link, even if anonymous users do not technically have an account. Using this module will allow you to only have your 'My account' link visible to registered users, and hide it from anonymous users.
The module uses the exact same UI used for block visibility settings for familiarity.
Or the menu_views module - which provides a Views-based approach to menu generation (which I would think includes based on user)