In hook_menu, if an access callback is in a separate file, the file is not loaded. E.g.

function mymodule_menu() {
$items['node/%/foo'] = array(
'title' => 'Process',
'access callback' => 'mymodule_foo_access',
'access arguments' => array(1),
'page callback' => 'mymodule_foo',
'page arguments' => array(1),
'type' => MENU_LOCAL_TASK,
'file' => 'mymodule.foo.inc',
);
return $items;
}

The page callback functions correctly, loading "mymodule.foo.inc" and then calling "mymodule_foo()". However, the access callback fails -- mymodule.foo.inc is not loaded, and mymodule_foo_access() is not found.

The workaround is to put the access function in the .module, or explicitly include the file. But as long as the file parameter exists, it ought to be used consistently, right?

Comments

eric_a’s picture

Status: Active » Closed (works as designed)

This is the documented behaviour.

Access callbacks are called before page callback files are loaded.
Even if we did load the file before checking access, it would not make to much sense to put them in the same file.
A menu router item page callback function is dependent on path elements/ menu objects, while access callback functions often are not. (The default user_access() is re-used by many router items.) There is no 1-1 relationship, so access callbacks would need a dedicated file key if you really wanted to split these off from the module file.