You are here

function admin_menu_output in Administration menu 8.3

Same name and namespace in other branches
  1. 5.3 admin_menu.module \admin_menu_output()
  2. 6.3 admin_menu.module \admin_menu_output()
  3. 7.3 admin_menu.module \admin_menu_output()

Build the administration menu output.

Parameters

bool $complete: (optional) Whether to build to the complete menu including all components and ignore the cache. Defaults to FALSE. Internally used for the settings page.

2 calls to admin_menu_output()
admin_menu_js_cache in ./admin_menu.module
Menu callback; Output administration menu for HTTP caching via AJAX request.
admin_menu_page_bottom in ./admin_menu.module
Implements hook_page_bottom().

File

./admin_menu.module, line 450
Render an administrative menu as a dropdown menu at the top of the window.

Code

function admin_menu_output($complete = FALSE) {
  global $user;
  $cache_server_enabled = !$complete && variable_get('admin_menu_cache_server', TRUE);
  $langcode = language(LANGUAGE_TYPE_INTERFACE)->langcode;
  $cid = 'admin_menu:' . $user->uid . ':' . session_id() . ':' . $langcode;
  $tags = [
    'admin_menu' => TRUE,
    'user' => $user->uid,
    'language' => $langcode,
  ];

  // Try to load and output administration menu from server-side cache.
  // @todo Duplicates the page cache? Page cache ID contains the hash that is
  //   generated at the bottom of this function, which is based on $content,
  //   but logically identical to the $cid. Investigate whether not only the
  //   cache_menu but also the cache_admin_menu could be dropped; the
  //   client-side HTTP cache hash check could be based on a cid lookup in
  //   cache_page instead? (i.e., one cache to rule them all) However,
  //   cache_page is cleared very often.
  if ($cache_server_enabled) {
    $cache = cache('menu')
      ->get($cid);
    if ($cache && isset($cache->data)) {
      $content = $cache->data;
    }
  }

  // Rebuild the output.
  if (!isset($content)) {

    // Retrieve enabled components to display and make them available for others.
    $components = variable_get('admin_menu_components', []);
    $components += [
      'admin_menu.menu' => TRUE,
      'admin_menu.icon' => TRUE,
      'admin_menu.account' => TRUE,
    ];
    $content['#components'] = $components;
    $content['#complete'] = $complete;

    // Add site name as CSS class for development/staging theming purposes. We
    // leverage the cookie domain instead of HTTP_HOST to account for many (but
    // not all) multi-domain setups (e.g. language-based sub-domains).
    $classes = 'admin-menu-site' . drupal_strtolower(preg_replace('/[^a-zA-Z0-9-]/', '-', $GLOBALS['cookie_domain']));

    // Displace overlay.
    // @see Drupal.overlay.create
    // @see toolbar_preprocess_toolbar()
    if (module_exists('overlay')) {
      $classes .= ' overlay-displace-top';
    }

    // @todo Always output container to harden JS-less support.
    $content['#prefix'] = '<div id="admin-menu" class="' . $classes . '"><div id="admin-menu-wrapper">';
    $content['#suffix'] = '</div></div>';

    // Load menu builder functions.
    module_load_include('inc', 'admin_menu');

    // @todo Move the below callbacks into hook_admin_menu_build()
    //   implementations (and $module.admin_menu.inc).
    // Add administration menu.
    if (!empty($components['admin_menu.menu']) || $complete) {
      $content['menu'] = admin_menu_links_menu(admin_menu_tree('admin'));
      $content['menu']['#theme'] = 'admin_menu_links';
      $content['menu']['#wrapper_attributes']['id'] = 'admin-menu-menu';

      // Ensure the menu tree is rendered between the icon and user links.
      $content['menu']['#weight'] = 0;
    }

    // Add menu additions.
    if (!empty($components['admin_menu.icon']) || $complete) {
      $content['icon'] = admin_menu_links_icon();
    }
    if (!empty($components['admin_menu.account']) || $complete) {
      $content['account'] = admin_menu_links_account();
    }
    if (!empty($components['admin_menu.users']) || $complete) {
      $content['users'] = admin_menu_links_users();
    }
    if (!empty($components['admin_menu.search']) || $complete) {
      $content['search'] = admin_menu_links_search();
    }

    // Allow modules to enhance the menu.
    // Uses '_output' suffix for consistency with the alter hook (see below).
    foreach (module_implements('admin_menu_output_build') as $module) {
      $function = $module . '_admin_menu_output_build';
      $function($content);
    }

    // Allow modules to alter the output.
    // The '_output' suffix is required to prevent hook implementation function
    // name clashes with the contributed Admin module.
    drupal_alter('admin_menu_output', $content);
    $content = \Drupal::service('renderer')
      ->render($content);

    // Cache the menu for this user.
    if ($cache_server_enabled) {
      cache('menu')
        ->set($cid, $content, CacheBackendInterface::CACHE_PERMANENT, $tags);
    }
  }

  // Store the new hash for this user.
  if (!$complete) {
    admin_menu_cache_set($cid, md5($content), $tags);
  }
  return $content;
}