호출하는 함수 hook_menu()
는 menu_rebuild () 에 의해 호출되는 menu_router_build () 입니다. 다음 코드가 포함되어 있습니다.
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);
동일한 경로를 정의하는 두 개의 모듈이있는 경우, 반환 된 배열의 마지막 모듈 module_implements()
은 다른 모듈에서 정의 된 값을 무시합니다.
필요한 두 번째 매개 변수 module_implements()
는 다음과 같이 정의됩니다.
$sort
기본적으로 모듈은 무게와 파일 이름으로 정렬되며이 옵션을로 설정하면 TRUE
모듈 목록은 모듈 이름으로 정렬됩니다.
menu_router_build()
에 두 번째 매개 변수를 전달하지 않기 때문에 menu_implements()
함수는 해당 매개 변수의 기본값을 사용합니다. 이것은 모듈 목록이 무게와 파일 이름으로 정렬됨을 의미합니다. 두 모듈의 무게가 동일한 경우 목록에 나타나는 첫 번째 모듈이 알파벳순으로 가장 먼저 나타납니다.
또한, 모든 모듈 구현 hook_module_implements_alter()
은 후크 호출 순서를 변경할 수 있습니다.
이러한 이유로 후크가 어떤 순서로 호출되는지 알 수 없습니다.
코드의 목적이 다른 모듈에 의해 구현 된 경로를 변경하는 경우, 예를 들어 두 번째 모듈을 설치하고 활성화 할 때 경로를 제거해야하기 때문에 코드는를 사용해야 hook_menu_alter()
합니다. 라우트 충돌의 경우 어떤 모듈이 "승리"하는지 이해하려는 경우에는 이러한 라우트 충돌을 피하고 다른 모듈에서 아직 정의되지 않은 라우트를 정의합니다.
그렇다면을 구현 hook_menu_alter()
하고 있고 경로를 효과적으로 재정의하는 모듈이되기 위해 모듈이 마지막으로 실행되도록하려면 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;
}
}