diff --git a/admin_menu.inc b/admin_menu.inc index c65f5d3..31cbab1 100644 --- a/admin_menu.inc +++ b/admin_menu.inc @@ -4,8 +4,19 @@ * The key function that builds the menu links whenever there is a menu rebuild. */ function _admin_menu_rebuild_links() { - // Get the newly rebuilt menu. - $menu = menu_router_build(); + $menu = NULL; + // Since it's possible this core function might change, check + // that it exists. We do this instead of calling menu_router_build() + // since that may trigger another menu rebuild that is not protected + // by the lock API. + if (function_exists('_menu_router_cache')) { + // Get the newly rebuilt menu. + $menu = _menu_router_cache(); + } + if (!$menu) { + // Something went wrong. Don't risk triggereing another menu rebuild. + return; + } // Add normal and suggested items as links. $menu_links = array(); foreach ($menu as $path => $item) { diff --git a/admin_menu.module b/admin_menu.module index 40926f0..e7d87b8 100644 --- a/admin_menu.module +++ b/admin_menu.module @@ -125,23 +125,12 @@ function admin_menu_suppress($set = TRUE) { * Admin menu was previously output via hook_block(), but suffered from * theme-specific stylesheets that may be applied to layout blocks. We now * output Admin menu in the footer to circumvent this. - * - * @todo Since admin_menu is rebuilt in the same request, we should be able - * to use a helper function instead of a variable to remind us to rebuild - * (variable_set() is slow). */ function admin_menu_footer($main = 0) { if (!user_access('access administration menu') || admin_menu_suppress(FALSE)) { return; } - // Check for the flag indicating that we need to rebuild. - if (variable_get('admin_menu_rebuild_links', FALSE)) { - module_load_include('inc', 'admin_menu'); - _admin_menu_rebuild_links(); - variable_del('admin_menu_rebuild_links'); - } - $content = '
'; $content .= admin_menu_tree_output(menu_tree_all_data('admin_menu')); $content .= '
'; @@ -149,6 +138,17 @@ function admin_menu_footer($main = 0) { } /** + * Implementation of hook_exit(). + */ +function admin_menu_exit() { + // Check for the flag indicating that we need to rebuild. + if (admin_menu_rebuild_links()) { + module_load_include('inc', 'admin_menu'); + _admin_menu_rebuild_links(); + } +} + +/** * Returns a rendered menu tree. * * @param $tree @@ -228,14 +228,23 @@ function admin_menu_form_devel_admin_settings_alter(&$form, $form_state) { * Implementation of hook_enable(). */ function admin_menu_enable() { - variable_set('admin_menu_rebuild_links', TRUE); + admin_menu_rebuild_links(TRUE); } /** * Implementation of hook_menu_alter(). */ function admin_menu_menu_alter() { - variable_set('admin_menu_rebuild_links', TRUE); + admin_menu_rebuild_links(TRUE); +} + +function admin_menu_rebuild_links($new_value = NULL) { + static $rebuild = FALSE; + + if (isset($new_value)) { + $rebuild = $new_value; + } + return $rebuild; } /**