1 book.module book_menu_subtree_data($link)

Gets the data representing a subtree of the book hierarchy.

The root of the subtree will be the link passed as a parameter, so the returned tree will contain this item and all its descendants in the menu tree.


$link: A fully loaded menu link.

Return value

A subtree of menu links in an array, in the order they should be rendered.:


core/modules/book/book.module, line 1228
Allows users to create and organize related content in an outline.


function book_menu_subtree_data($link) {
  $tree = &backdrop_static(__FUNCTION__, array());

  // Generate a cache ID (cid) specific for this $menu_name and $link.
  $cid = 'links:' . $link['menu_name'] . ':subtree-cid:' . $link['mlid'];

  if (!isset($tree[$cid])) {
    $cache = cache('menu')->get($cid);

    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('menu')->get($cache->data);

      if ($cache && isset($cache->data)) {
        $data = $cache->data;

    // If the subtree data was not in the cache, $data will be NULL.
    if (!isset($data)) {
      $query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC));
      $query->join('menu_router', 'm', 'm.path = ml.router_path');
      $query->join('book', 'b', 'ml.mlid = b.mlid');
      $query->fields('m', array('load_functions', 'to_arg_functions', 'access_callback', 'access_arguments', 'page_callback', 'page_arguments', 'delivery_callback', 'title', 'title_callback', 'title_arguments', 'type'));
      $query->condition('menu_name', $link['menu_name']);
      for ($i = 1; $i <= MENU_MAX_DEPTH && $link["p$i"]; ++$i) {
        $query->condition("p$i", $link["p$i"]);
      for ($i = 1; $i <= MENU_MAX_DEPTH; ++$i) {
      $links = array();
      foreach ($query->execute() as $item) {
        $links[] = $item;
      $data['tree'] = menu_tree_data($links, array(), $link['depth']);
      $data['node_links'] = array();
      menu_tree_collect_node_links($data['tree'], $data['node_links']);
      // Compute the real cid for book subtree data.
      $tree_cid = 'links:' . $item['menu_name'] . ':subtree-data:' . hash('sha256', serialize($data));
      // Cache the data, if it is not already in the cache.

      if (!cache('menu')->get($tree_cid)) {
        cache('menu')->set($tree_cid, $data);
      // Cache the cid of the (shared) data using the menu and item-specific cid.
      cache('menu')->set($cid, $tree_cid);
    // 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];