diff --git a/admin_menu.api.php b/admin_menu.api.php index 2d212fb..f3765d9 100644 --- a/admin_menu.api.php +++ b/admin_menu.api.php @@ -162,3 +162,43 @@ function hook_admin_menu_cache_info() { ); return $caches; } + +/** + * Alter the Cache ID used to cache a rendered admin_menu. + * + * By default the admin menu is cached by: + * - The User ID. + * - The session ID. + * - The current language. + * + * Some implementations will add extra items to the menu (or alter it) based on + * the context of the page (e.g. Extra menu items when in an Organic Group). + * As the admin menu is by default generated and cached once, the context + * specific items will be missing/out of place unless the cache is cleared. + * + * This hook allows to alter the Cache ID based on a context. + * + * A cache id is by default: + * + * admin_menu:uid:session_id:language + * + * + * Where: + * - admin_menu : Fixed cache id prefix. + * - uid : The current User ID. + * - session_id : The PHP session ID. + * - language : The current language code (eg. en, fr, ...). + * + * WARNING: The cid will always start with "admin_menu:uid:". + * This because of the functionality to clear the admin_menu cache. + * + * @param string $cid + * The Cache ID to be altered. + */ +function hook_admin_menu_cache_id_alter(&$cid) { + // Add the Group ID to the Cache ID. + $context = og_context('node'); + if ($context) { + $cid .= ':' . $context['gid']; + } +} diff --git a/admin_menu.module b/admin_menu.module index 21bff9f..0eafc10 100644 --- a/admin_menu.module +++ b/admin_menu.module @@ -154,7 +154,7 @@ function admin_menu_page_build(&$page) { if (strpos($_GET['q'], 'js/') === 0) { return; } - global $user, $language; + global $user; $path = drupal_get_path('module', 'admin_menu'); $page['page_bottom']['admin_menu'] = array( @@ -184,7 +184,8 @@ function admin_menu_page_build(&$page) { // If the client supports JavaScript and we have a cached menu for the current // user, only output the hash for the client-side HTTP cache callback URL. - $cid = 'admin_menu:' . $user->uid . ':' . session_id() . ':' . $language->language; + $cid = admin_menu_cache_id(); + if (!$complete && !empty($_COOKIE['has_js']) && ($hash = admin_menu_cache_get($cid))) { $settings['hash'] = $hash; // The base path to use for cache requests depends on whether clean URLs @@ -276,6 +277,38 @@ function admin_menu_js() { } /** + * Get the Cache ID to store rendered admin menu in cache. + * + * Some implementations will add extra items to the menu (or alter it) based on + * the context the page is in (e.g. Extra menu items when in an Organic Group). + * + * The admin_menu is by default cached by: + * - The User ID. + * - The session ID. + * - The current language. + * + * So once a menu is cached for one context, it will shown like even if there is + * another context. Unless the cache is cleared. + * + * This function will create a default cache ID but this one can be altered by + * implementing hook_admin_menu_cache_id_alter(). + * + * WARNING: The cid must always start with "admin_menu:UID". + * This because of the functionality to clear the admin_menu cache. + * + * @return string + * The Cache ID. + */ +function admin_menu_cache_id() { + global $user, $language; + + $cid = 'admin_menu:' . $user->uid . ':' . session_id() . ':' . $language->language; + drupal_alter('admin_menu_cache_id', $cid); + + return $cid; +} + +/** * Retrieve a client-side cache hash from cache. * * The hash cache is consulted more than once per request; we therefore cache @@ -451,10 +484,8 @@ function admin_menu_session_count($timestamp = 0, $anonymous = TRUE) { * page. */ function admin_menu_output($complete = FALSE) { - global $user, $language; - $cache_server_enabled = !$complete && variable_get('admin_menu_cache_server', TRUE); - $cid = 'admin_menu:' . $user->uid . ':' . session_id() . ':' . $language->language; + $cid = admin_menu_cache_id(); // Try to load and output administration menu from server-side cache. // @todo Duplicates the page cache? Page cache ID contains the hash that is