You are here

function _patterns_menu_tree_all_data in Patterns 6

Same name and namespace in other branches
  1. 6.2 patterns.module \_patterns_menu_tree_all_data()

Custom implementation of Drupal's menu_tree_all_data()

Removed static caching. New menu items may be created during pattern execution and static caching prevents them from being returned in all subsequent calls to menu_tree_all_data() during the current pattern execution (within current page request)

1 call to _patterns_menu_tree_all_data()
_patterns_menu_parent_options in ./patterns.module
Custom implementation of Drupal's menu_parent_options()


./patterns.module, line 3135
Enables extremely simple adding/removing features to your site with minimal to no configuration


function _patterns_menu_tree_all_data($menu_name = 'navigation', $item = NULL) {
  $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 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(
      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("\n      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.*\n      FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path\n      WHERE ml.menu_name = '%s'" . $where . "\n      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];