Take the 2-minute tour ×
Drupal Answers is a question and answer site for Drupal developers and administrators. It's 100% free, no registration required.

I am using Content Access module with Drupal 7. when i restrict node access from a specific role, it also hide link in menu.

is there any way to show restricted links in main menu?

share|improve this question
    
how are you creating the menu? programatically? or using admin UI at admin/structure/menu/manage/main-menu/add? –  AjitS Dec 6 '12 at 14:07
    
i am adding menu when content create. an option at bottom 'Provide a menu link'. –  monymirza Dec 7 '12 at 4:52

4 Answers 4

up vote 4 down vote accepted

I have did this via custom module:

function mymodule_form_menu_edit_item_alter(&$form, &$form_state, $form_id) {
     if ($form_state['build_info']['args'][0] == 'edit') {
       $item = $form_state['build_info']['args'][1];

       $form['ignore_access_roles'] = array(
         '#type' => 'checkboxes',
         '#multiple' => TRUE,
         '#title' => t("Ignore access"),
         '#options' => user_roles(),
         '#description' => t("If a user with one of the selected roles has no access to the menu item's path, the menu item is <strong>not</strong> hidden."),
         '#default_value' => empty($item['options']['ignore_access_roles']) ? array() : $item['options']['ignore_access_roles'],
       );

       $form['#validate'][] = 'mymodule_form_menu_edit_item_validate';
     }
   }

   function mymodule_form_menu_edit_item_validate(&$form, &$form_state) {
     if (isset($form_state['values']['ignore_access_roles'])) {
       $form_state['values']['options']['ignore_access_roles'] = $form_state['values']['ignore_access_roles'];


       $form_state['values']['options']['alter'] = TRUE;
     }
   }


   function mymodule_translated_menu_link_alter(&$link, $map) {
     if (!empty($link['options']['ignore_access_roles']) && empty($link['access'])) {

       global $user;

       // Get role ids for which the ignore access option applies.
       $rids = array_values($link['options']['ignore_access_roles']);

       $matching_rids = array_intersect(array_keys($user->roles), $rids);

       if (!empty($matching_rids)) {
         // User has one of the specified roles: override menu link access.
         $link['access'] = TRUE;

         // Localize. This must be done because it is only done for links with
         // access TRUE in _menu_link_translate.
         _menu_item_localize($link, $map, TRUE);
       }
     }
   }
share|improve this answer

The main purpose of the access content system is to have control of what every user can see and avoid every possible security issue. This is the desired behavior and almost every module or general ApI uses it, so you won't find default solutions for this.

I've been in the same situation and the only solution I found was to create a custom modules and, in my case, query directly to the menu table to get all the elements I want, and check the permissions myself to either display a link, or simply a title of the content when the user don't have permissions to see it.

share|improve this answer
    
will i have to use content access module with it or not? –  monymirza Dec 10 '12 at 8:23
    
The menu by itself will never display the blocked nodes. I would create a module to fetch the nodes of the menu. Then you can choose to display a link for every node (if the user don't have access he will see a 403 page), or check the content access module permissions for each node, and don't display a link if the user don't have access. –  david ruiz Dec 10 '12 at 8:37

I'm pretty sure you will have to write a custom module to deal with this. Here's my idea: relax Content Access restrictions, i.e. let users view your content. Then your custom module has to implement hook_node_load() and output a 403 HTTP response when loading nodes your users should not see. Also hook_permission() should be implemented, so you will be able to configure access easily at the permission page.

Here's a quick example hiding the entire node and filtering by content type and permission:

function mymodule_permission() {
  return array('access reserved content');
}

function mymodule_node_load($nodes, $types) {
  if (in_array('my_reserved_content_type', $types)) {
    if (!user_access('access reserved content')) {
      drupal_access_denied();
    }
  }
}

Or you can hide some of the node fields, instead of returning a 403. But this is discouraged according to API documentation for hook_node_load()

share|improve this answer
    
i am adding menu when content create. an option at bottom 'Provide a menu link'. –  monymirza Dec 8 '12 at 11:58
    
will i have to use content access module with it or not? –  monymirza Dec 10 '12 at 8:22

You can use "Always visible" module.

More detailed answer on your question is here http://drupal.stackexchange.com/a/52149/7313

share|improve this answer
    
i used but no solution. –  monymirza Dec 11 '12 at 10:06
    
What do you mean "no solution"? Do you have installed that module? –  Eugene Fidelin Dec 11 '12 at 10:26
    
yes i used this module. and this not works for me... –  monymirza Dec 12 '12 at 6:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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