menu_tree_all_data

Definition

menu_tree_all_data($menu_name = 'navigation', $item = NULL)
drupal/includes/menu.inc, line 827

Description

Get the data structure representing a named menu tree.

Since this can be the full tree including hidden items, the data returned may be used for generating an an admin interface or a select.

Parameters

$menu_name The named menu links to return

$item A fully loaded menu link, or NULL. If a link is supplied, only the path to root will be included in the returned tree- as if this link represented the current page in a visible menu.

Return value

An tree of menu links in an array, in the order they should be rendered.

Related topics

Namesort iconDescription
Menu systemDefine the navigation menus, and route page requests to code based on URLs.

Code

function menu_tree_all_data($menu_name = 'navigation', $item = NULL) {
  static $tree = array();

  // Use $mlid as a flag for whether the data being loaded is for the whole tree.
  $mlid = isset($item['mlid']) ? $item['mlid'] : 0;
  // Generate a cache ID (cid) specific for this $menu_name and $item.
  $cid = 'links:' . $menu_name . ':all-cid:' . $mlid;

  if (!isset($tree[$cid])) {
    // If the static variable doesn't have the data, check {cache_menu}.
    $cache = cache_get($cid, 'cache_menu');
    if ($cache && isset($cache->data)) {
      // If the cache entry exists, it will just be the cid for the actual data.
      // This avoids duplication of large amounts of data.
      $cache = cache_get($cache->data, 'cache_menu');
      if ($cache && isset($cache->data)) {
        $data = $cache->data;
      }
    }
    // If the tree data was not in the cache, $data will be NULL.
    if (!isset($data)) {
      // Build and run the query, and build the tree.
      if ($mlid) {
        // The tree is for a single item, so we need to match the values in its
        // p columns and 0 (the top level) with the plid values of other links.
        $args = array(0);
        for ($i = 1; $i < MENU_MAX_DEPTH; $i++) {
          $args[] = $item["p$i"];
        }
        $args = array_unique($args);
        $placeholders = implode(', ', array_fill(0, count($args), '%d'));
        $where = ' AND ml.plid IN (' . $placeholders . ')';
        $parents = $args;
        $parents[] = $item['mlid'];
      }
      else {
        // Get all links in this menu.
        $where = '';
        $args = array();
        $parents = array();
      }
      array_unshift($args, $menu_name);
      // Select the links from the table, and recursively build the tree.  We
      // LEFT JOIN since there is no match in {menu_router} for an external
      // link.
      $data['tree'] = menu_tree_data(db_query("
        SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, m.description, ml.*
        FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path
        WHERE ml.menu_name = '%s'"
. $where . "
        ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC, p6 ASC, p7 ASC, p8 ASC, p9 ASC"
, $args), $parents);
      $data['node_links'] = array();
      menu_tree_collect_node_links($data['tree'], $data['node_links']);
      // Cache the data, if it is not already in the cache.
      $tree_cid = _menu_tree_cid($menu_name, $data);
      if (!cache_get($tree_cid, 'cache_menu')) {
        cache_set($tree_cid, $data, 'cache_menu');
      }
      // Cache the cid of the (shared) data using the menu and item-specific cid.
      cache_set($cid, $tree_cid, 'cache_menu');
    }
    // Check access for the current user to each item in the tree.
    menu_tree_check_access($data['tree'], $data['node_links']);
    $tree[$cid] = $data['tree'];
  }

  return $tree[$cid];
}