[Drupal] How to create Multiple access callbacks for a menu in Drupal 6

| | 2 min read

Drupal 6 will not allow you to create multiple access callbacks for a menu. In hook menu, the access callback will accept only string value, not an array. But I had a requirement in my project to add a custom access callback without removing the existing access callback. My custom access callback should be executed first. After that if some condition satisfies in my custom function the original access callback should get executed.

I have done this by implementing hook_menu_alter. See the following code.

  
    /**
     * Implements hook_menu_alter().
     *
     * Adds a custom access callback.
     */
    function mymodule_menu_alter(&$items) {
      $path = 'node/%node/edit';
      $items[$path]['access arguments'][] = $items[$path]['access callback'];
      $items[$path]['access callback'] = '_mymodule_content_access'; 
    }
  

The above function alters the existing menu 'node/%node/edit' and adds the original access callback as the next element of the access argument array. And adds our custom access callback as the access callback for the menu.

  
    /**
     * Defines the custom access callback function for the menu 'node/%node/edit'.
     *
     * Checks whether the user is anonymous user then directly returns false.
     * Otherwise calls the original callback function.
     */
    function _mymodule_content_access() {
      global $user;
      $account = $user;
      if ($account->uid == 0) {
        return FALSE;
      }
      $args = func_get_args();
      $access_callback = array_pop($args);
      $original_access = call_user_func_array($access_callback, $args);
      return $original_access; 
    } 
  

The above function checks whether the current user is anonymous user and if yes, then directly returns false. Otherwise get its arguments using the function func_get_args(). And then take the last element from the array which is the original access callback for the menu using the array_pop(). Then invokes original access callback function with its arguments using the function call_user_func_array().

Thus we can execute multiple access call backs for a menu.