A função que chamahook_menu()
é menu_router_build () , chamada por menu_rebuild () . Ele contém o seguinte código.
foreach (module_implements('menu') as $module) {
$router_items = call_user_func($module . '_menu');
if (isset($router_items) && is_array($router_items)) {
foreach (array_keys($router_items) as $path) {
$router_items[$path]['module'] = $module;
}
$callbacks = array_merge($callbacks, $router_items);
}
}
// Alter the menu as defined in modules, keys are like user/%user.
drupal_alter('menu', $callbacks);
Se houver dois módulos definindo a mesma rota, o último módulo na matriz retornado por module_implements()
substituirá o valor definido dos outros módulos.
O segundo parâmetro exigido por module_implements()
é definido como:
$sort
Por padrão, os módulos são ordenados por peso e nome do arquivo, as configurações dessa opção para TRUE
, lista de módulos serão ordenadas pelo nome do módulo.
Como menu_router_build()
não passa o segundo parâmetro para menu_implements()
, a função está usando o valor padrão para esse parâmetro. Isso significa que a lista de módulos é ordenada por peso e nome de arquivo; quando dois módulos têm o mesmo peso, o primeiro módulo que aparece na lista é o primeiro em ordem alfabética.
Além disso, qualquer módulo implementado hook_module_implements_alter()
pode alterar a ordem em que os ganchos são chamados.
Por esse motivo, você não deve saber em qual ordem os ganchos são chamados.
Se o objetivo do código for alterar a rota implementada por outro módulo, por exemplo, porque uma rota deve ser removida quando um segundo módulo é instalado e ativado, o código deve ser usado hook_menu_alter()
. Se você está tentando entender qual módulo "venceria" no caso de conflitos de rota, prefiro evitar esse conflito de rota e definir uma rota que ainda não esteja definida em outro módulo.
Se você está implementando hook_menu_alter()
e deseja garantir que seu módulo seja executado por último, para ser o módulo que efetivamente substitui uma rota, você deve implementar hook_module_implements_alter()
também.
function mymodule_module_implements_alter(&$implementations, $hook) {
if ($hook == 'menu_alter') {
// Move mymodule_menu_alter() to the end of the list. module_implements()
// iterates through $implementations with a foreach loop which PHP iterates
// in the order that the items were added, so to move an item to the end of
// the array, we remove it and then add it.
$group = $implementations['mymodule'];
unset($implementations['mymodule']);
$implementations['mymodule'] = $group;
}
}