Fungsi hook_menu()
yang dipanggil adalah menu_router_build () , dipanggil oleh menu_rebuild () . Ini berisi kode berikut.
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);
Jika ada dua modul yang mendefinisikan rute yang sama, modul terakhir dalam array yang dikembalikan oleh module_implements()
akan menimpa nilai yang ditentukan dari modul lainnya.
Parameter kedua yang dibutuhkan oleh module_implements()
didefinisikan sebagai:
$sort
Secara default, modul dipesan berdasarkan berat dan nama file, pengaturan opsi ini TRUE
, daftar modul akan dipesan berdasarkan nama modul.
Karena menu_router_build()
tidak meneruskan parameter kedua menu_implements()
, fungsi menggunakan nilai default untuk parameter itu. Ini berarti daftar modul diurutkan berdasarkan berat dan nama file; ketika dua modul memiliki bobot yang sama, modul pertama yang muncul dalam daftar adalah yang memiliki urutan abjad terlebih dahulu.
Selanjutnya, setiap implementasi modul hook_module_implements_alter()
dapat mengubah urutan kait dipanggil.
Untuk alasan ini, Anda tidak boleh berasumsi tahu di mana urutan kait dipanggil.
Jika tujuan kode adalah mengubah rute yang diterapkan oleh modul lain, misalnya karena rute harus dihapus ketika modul kedua diinstal dan diaktifkan, kode tersebut harus digunakan hook_menu_alter()
. Jika Anda mencoba memahami modul mana yang akan "menang" dalam kasus konflik rute, saya lebih suka menghindari konflik rute tersebut, dan menentukan rute yang belum ditentukan dari modul lain.
Jika kemudian Anda menerapkan hook_menu_alter()
, dan Anda ingin memastikan modul Anda dieksekusi terakhir, untuk menjadi modul yang secara efektif menimpa rute, Anda harus menerapkan hook_module_implements_alter()
juga.
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;
}
}