La fonction appelanthook_menu()
est menu_router_build () , appelée par menu_rebuild () . Il contient le code suivant.
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);
S'il y a deux modules définissant la même route, le dernier module du tableau renvoyé par module_implements()
remplacera la valeur définie à partir des autres modules.
Le deuxième paramètre requis par module_implements()
est défini comme:
$sort
Par défaut, les modules sont classés par poids et par nom de fichier, les paramètres de cette option sur TRUE
, la liste des modules seront classés par nom de module.
Puisque menu_router_build()
ne transmet pas le deuxième paramètre à menu_implements()
, la fonction utilise la valeur par défaut pour ce paramètre. Cela signifie que la liste des modules est classée selon leur poids et leur nom de fichier; lorsque deux modules ont le même poids, le premier module qui apparaît dans la liste est celui qui vient en premier par ordre alphabétique.
De plus, tout module implémentant hook_module_implements_alter()
peut modifier l'ordre d'appel des hooks.
Pour cette raison, vous ne devez pas supposer de savoir dans quel ordre les hooks sont appelés.
Si le but du code est de modifier l'itinéraire implémenté par un autre module, par exemple parce qu'un itinéraire doit être supprimé lorsqu'un deuxième module est installé et activé, le code doit utiliser hook_menu_alter()
. Si vous essayez de comprendre quel module gagnerait dans le cas de conflits de route, je préfère éviter un tel conflit de route et définir une route qui n'est pas déjà définie à partir d'un autre module.
Si vous implémentez hook_menu_alter()
, et que vous voulez être sûr que votre module est exécuté en dernier, pour être le module qui remplace efficacement un itinéraire, vous devez hook_module_implements_alter()
également l' implémenter .
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;
}
}