Q:

Page visible for authenticated user, not custom role

I have a custom module that has type MENU_LOCAL_TASK with path user/%/custom-page.
The page callback is displaying a content and with custom page arguments and access arguments functions, only the author of the content can see that content. So far so good.
I have authenticated users and custom role (editor).
Now my goal is to display the MENU_LOCAL_TASK with the page callback content only for the authenticated users, not the editor.
All authenticated users are with role[3] and the Editor is with role[5].
Because of the role "Editor" is automatically authenticated user I cannot set the custom page to be visible only for the other authenticated users. 
On my page.tpl.php I've managed to display links that will be visible only for authenticated user without user with role[5] (editor) with this code and its working great.
<?php 
if(isset($user->roles[3])){ 
    //visible only for roles[3], the ordinary authenticated users
}

How can I do this with my custom module?
I didn't find an examples in hook_menu for roles. 
Hook_permission() didn't helped, because when I choose the authenticated user in drupal permissions UI, automatically marks the editor role.
I'm using Drupal 7.

A:

When declaring items in hook_menu(), you can specify a custom access callback property. This should be a function that returns TRUE if the user has access to the page.
In this function you can have a look at the global $user object (ie. the currently logged-in user) and determine whether to grant access or not:
/**
 * Implementation of hook_menu()
 */
function hook_menu() {
  $items['user/%/custom-page'] = array(
    'title' => 'Custom Page',
    'type' => MENU_CALLBACK,
    'page callback' => 'your_page_callback',
    'access callback' => 'custom_page_access',
    'access arguments' => array(1),
  );

  return $items;
}

/**
 * Access callback for /user/%/custom-page

 * @param  {[type]} $account [description]
 * @return {[type]}          [description]
 */
function custom_page_access($account) {
  // how do you want to handle role restrictions? if looking at the user
  // whose custom-page is being loaded, use $account, otherwise the global
  // $user object:

  global $user;

  // check that role id 3 IS set, and role id 5 is NOT
  if (isset($user->roles[3]) && !isset($user->roles[5])) {
    return TRUE;
  }

  return FALSE;
}

Don't forget to clear the site's cache (to rebuild the menu registry) after making these changes.

