La función que invoca hook_menu()
es menu_router_build () , llamada por menu_rebuild () . Contiene el siguiente 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);
Si hay dos módulos que definen la misma ruta, el último módulo en la matriz devuelto por module_implements()
anulará el valor definido de los otros módulos.
El segundo parámetro requerido por module_implements()
se define como:
$sort
Por defecto, los módulos se ordenan por peso y nombre de archivo, la configuración de esta opción TRUE
, la lista de módulos se ordenará por nombre de módulo.
Como menu_router_build()
no pasa el segundo parámetro a menu_implements()
, la función está usando el valor predeterminado para ese parámetro. Esto significa que la lista de módulos está ordenada por su peso y nombre de archivo; cuando dos módulos tienen el mismo peso, el primer módulo que aparece en la lista es el que aparece alfabéticamente primero.
Además, la implementación de cualquier módulo hook_module_implements_alter()
puede alterar el orden en que se invocan los ganchos.
Por este motivo, no debe suponer que sabe en qué orden se invocan los ganchos.
Si el propósito del código es alterar la ruta implementada por otro módulo, por ejemplo, porque una ruta debe eliminarse cuando se instala y habilita un segundo módulo, el código debe usarse hook_menu_alter()
. Si está tratando de entender qué módulo "ganaría" en el caso de conflictos de ruta, prefiero evitar dicho conflicto de ruta y definir una ruta que no esté definida desde otro módulo.
Si luego está implementando hook_menu_alter()
, y desea asegurarse de que su módulo se ejecute en último lugar, para ser el módulo que anule efectivamente una ruta, también debe implementar hook_module_implements_alter()
.
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;
}
}