diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 92bb8c0..a5d6a29 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -5,7 +5,7 @@ Admin Menu x.x-x.x, xxxx-xx-xx Admin Menu 6.x-1.x, xxxx-xx-xx ------------------------------ - +#1189532 by pwolanin: fix rebuild logic to avoid an extra menu rebuild. Admin Menu 6.x-1.6, 2010-09-03 ------------------------------ diff --git a/admin_menu.inc b/admin_menu.inc index c65f5d3..cdf2da0 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) { @@ -410,7 +421,7 @@ function admin_menu_theme_settings() { function admin_menu_wipe() { db_query("DELETE FROM {menu_links} WHERE menu_name = 'admin_menu'"); menu_cache_clear('admin_menu'); - variable_set('admin_menu_rebuild_links', TRUE); + menu_rebuild(); } /** @@ -516,7 +527,7 @@ function admin_menu_flush_cache($name = NULL) { break; case 'menu': - module_invoke('menu', 'rebuild'); + menu_rebuild(); break; case 'requisites': 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; } /** diff --git a/tests/admin_menu.test b/tests/admin_menu.test index e4ad3d6..a46db00 100644 --- a/tests/admin_menu.test +++ b/tests/admin_menu.test @@ -8,11 +8,24 @@ * the PCRE pattern, since admin menu's output spans over multiple lines. */ +class AdminMenuWebTestCase extends DrupalWebTestCase { + function setUp() { + parent::setUp('admin_menu', 'contact'); + // Create and log in a full-blown administrative user. + $permissions = module_invoke_all('perm'); + $this->admin_user = $this->drupalCreateUser($permissions); + $this->drupalLogin($this->admin_user); + // Forcing a menu rebuild via the UI seems to be required for + // the tests to work. + $this->drupalPost('admin/settings/performance', array(), t('Clear cached data')); + $this->drupalLogout(); + } +} /** * Test menu links depending on user permissions. */ -class AdminMenuPermissionsTestCase extends DrupalWebTestCase { +class AdminMenuPermissionsTestCase extends AdminMenuWebTestCase { public static function getInfo() { return array( 'name' => t('Menu link permissions'), @@ -21,10 +34,6 @@ class AdminMenuPermissionsTestCase extends DrupalWebTestCase { ); } - function setUp() { - parent::setUp('admin_menu'); - } - /** * Test that the links are added to the page (no JS testing). */ @@ -56,7 +65,7 @@ class AdminMenuPermissionsTestCase extends DrupalWebTestCase { /** * Test menu links depending on installed modules. */ -class AdminMenuModulesTestCase extends DrupalWebTestCase { +class AdminMenuModulesTestCase extends AdminMenuWebTestCase { public static function getInfo() { return array( 'name' => t('Module menu links'), @@ -65,10 +74,6 @@ class AdminMenuModulesTestCase extends DrupalWebTestCase { ); } - function setUp() { - parent::setUp('admin_menu', 'contact'); - } - /** * Test that the links are added to the page (no JS testing). */ @@ -95,7 +100,7 @@ class AdminMenuModulesTestCase extends DrupalWebTestCase { /** * Test contained links in administration menu. */ -class AdminMenuLinksTestCase extends DrupalWebTestCase { +class AdminMenuLinksTestCase extends AdminMenuWebTestCase { public static function getInfo() { return array( 'name' => t('Menu links'), @@ -104,19 +109,11 @@ class AdminMenuLinksTestCase extends DrupalWebTestCase { ); } - function setUp() { - parent::setUp('admin_menu'); - - // Create and log in a full-blown administrative user. - $permissions = module_invoke_all('perm'); - $admin_user = $this->drupalCreateUser($permissions); - $this->admin_user = $this->drupalLogin($admin_user); - } - /** * Test link contents. */ function testLinkContents() { + $this->drupalLogin($this->admin_user); // Create a content-type with special characters. $info = array( 'type' => 'special', @@ -126,7 +123,7 @@ class AdminMenuLinksTestCase extends DrupalWebTestCase { ); $info = (object)_node_type_set_defaults($info); node_type_save($info); - drupal_flush_all_caches(); + $this->drupalPost('admin/settings/performance', array(), t('Clear cached data')); // Fetch a page. $this->drupalGet('node');