menu_tree_all_data($menu_name, $link = NULL, $max_depth = NULL)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.
$menu_name The named menu links to return
$link 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.
$max_depth Optional maximum depth of links to retrieve. Typically useful if only one or two levels of a sub tree are needed in conjunction with a non-NULL $link, in which case $max_depth should be greater than $link['depth'].
An tree of menu links in an array, in the order they should be rendered.
includes/menu.inc, line 965
<?php
function menu_tree_all_data($menu_name, $link = NULL, $max_depth = NULL) {
$tree = &drupal_static(__FUNCTION__, array());
// Use $mlid as a flag for whether the data being loaded is for the whole tree.
$mlid = isset($link['mlid']) ? $link['mlid'] : 0;
// Generate a cache ID (cid) specific for this $menu_name, $link, $language, and depth.
$cid = 'links:' . $menu_name . ':all-cid:' . $mlid . ':' . $GLOBALS['language']->language . ':' . (int)$max_depth;
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 the query using a LEFT JOIN since there is no match in
// {menu_router} for an external link.
$query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC));
$query->addTag('translatable');
$query->leftJoin('menu_router', 'm', 'm.path = ml.router_path');
$query->fields('ml');
$query->fields('m', array(
'load_functions',
'to_arg_functions',
'access_callback',
'access_arguments',
'page_callback',
'page_arguments',
'delivery_callback',
'title',
'title_callback',
'title_arguments',
'theme_callback',
'theme_arguments',
'type',
'description',
));
for ($i = 1; $i <= MENU_MAX_DEPTH; $i++) {
$query->orderBy('p' . $i, 'ASC');
}
$query->condition('ml.menu_name', $menu_name);
if (isset($max_depth)) {
$query->condition('ml.depth', $max_depth, '<=');
}
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[] = $link["p$i"];
}
$args = array_unique($args);
$query->condition('ml.plid', $args, 'IN');
$parents = $args;
$parents[] = $link['mlid'];
}
else {
// Get all links in this menu.
$parents = array();
}
// Select the links from the table, and build an ordered array of links
// using the query result object.
$links = array();
foreach ($query->execute() as $item) {
$links[] = $item;
}
$data['tree'] = menu_tree_data($links, $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];
}
?>