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;
}
}
hook_menu_alter()
tidak digunakan untuk menentukan menu baru, tetapi untuk mengubah yang sudah ada. Jika dua modul mengubah menu yang sama, perubahan yang bertahan adalah yang dari modul yang dieksekusi untuk yang terakhir.Modul mana pun yang memiliki
weight
nilai lebih rendah dalamsystem
tabel akan dipanggil pertama, sehingga modul dengan nilai lebih tinggiweight
akan 'menang' dalam kasus ini.Jika bobotnya sama untuk dua (atau lebih) modul, saya yakin tidak ada pemesanan khusus yang dilakukan selain pemesanan yang datang langsung dari tabel MySQL (saya bisa salah tentang itu).
Karena hasil pengembalian dari pemanggilan
hook_menu
hanya dimasukkan ke dalam array tunggal dari item menu tidak akan pernah ada 'konflik' seperti itu, hasil dari panggilan kemudianhook_menu
hanya akan menimpa mereka dari panggilan sebelumnya.sumber
module_implements()
mendapatFALSE
sebagai parameter kedua, tetapi fungsi sepertimodule_invoke_all()
memanggilnya hanya dengan parameter.