Right now if you want to do something based on the active router item, you have to use hook_init() and then call menu_get_item().
It would be more elegant if one could implement a hook that is called with the router item as an argument.
So, in menu_execute_active_handler():
<?php
if ($router_item = menu_get_item($path)) {
if ($router_item['access']) {
if ($router_item['include_file']) {
require_once DRUPAL_ROOT . '/' . $router_item['include_file'];
}
// Let other modules react on the router item.
module_invoke_all('menu_execute_router_item', $router_item);
$page_callback_result = call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
}
?>The idea is not to alter the router item, but simply to react on it. We can't really guarantee that, since the array may contain objects. But at least we then have a central place for debugging.
We could add another hook invoke before the access check, not sure about that.
-----
Why?
- Avoid menu_get_item() to be called before menu_execute_active_handler(). This makes the system more predictable.
- Reduce the number of modules that have to implement hook_init(), and thus reduce the need for module weight.
- Arguments are nicer than stuff pulled from global state (= static variables, in our case). So, it's one step towards cleaner code.
- Better control of side effects on the router item, as now we know where to look and debug.
-----
D8.
In D8 we could go as far as to always get a fresh router item in menu_execute_active_handler(), and discard the static cache. This way we have better control of side effects.
D7 and D6.
I think it would be safe to add the new hook into D7 and D6, but we should not change the behavior of using the cached router item.
Comments
Comment #1
salvisThere's a D7 patch with an alternative solution at #553944-154: Define hook_menu_get_item_alter() as a reliable hook that runs before the page is doomed. Please consider adding your support there.