diff includes/menu.inc @ 5:2427550111ae 6.2

Drupal 6.2
author Franck Deroche <webmaster@defr.org>
date Tue, 23 Dec 2008 14:30:08 +0100
parents 165d43f946a8
children fff6d4c8c043
line wrap: on
line diff
--- a/includes/menu.inc	Tue Dec 23 14:29:21 2008 +0100
+++ b/includes/menu.inc	Tue Dec 23 14:30:08 2008 +0100
@@ -1,5 +1,5 @@
 <?php
-// $Id: menu.inc,v 1.255.2.9 2008/02/27 12:12:01 goba Exp $
+// $Id: menu.inc,v 1.255.2.11 2008/04/09 21:11:44 goba Exp $
 
 /**
  * @file
@@ -772,16 +772,22 @@
 
   // Use $mlid as a flag for whether the data being loaded is for the whole tree.
   $mlid = isset($item['mlid']) ? $item['mlid'] : 0;
-  // Generate the cache ID.
-  $cid = 'links:'. $menu_name .':all:'. $mlid;
+  // 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)) {
-      $data = $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;
+      }
     }
-    else {
+    // 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
@@ -813,8 +819,13 @@
         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.
-      cache_set($cid, $data, 'cache_menu');
+      // 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']);
@@ -844,16 +855,22 @@
 
   // Load the menu item corresponding to the current page.
   if ($item = menu_get_item()) {
-    // Generate the cache ID.
-    $cid = 'links:'. $menu_name .':page:'. $item['href'] .':'. (int)$item['access'];
+    // Generate a cache ID (cid) specific for this page.
+    $cid = 'links:'. $menu_name .':page-cid:'. $item['href'] .':'. (int)$item['access'];
 
     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)) {
-        $data = $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;
+        }
       }
-      else {
+      // 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 ($item['access']) {
           // Check whether a menu link exists that corresponds to the current path.
@@ -909,8 +926,13 @@
           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.
-        cache_set($cid, $data, 'cache_menu');
+        // 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 page-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']);
@@ -923,6 +945,13 @@
 }
 
 /**
+ * Helper function - compute the real cache ID for menu tree data.
+ */
+function _menu_tree_cid($menu_name, $data) {
+  return 'links:'. $menu_name .':tree-data:'. md5(serialize($data));
+}
+
+/**
  * Recursive helper function - collect node links.
  */
 function menu_tree_collect_node_links(&$tree, &$node_links) {
@@ -2246,9 +2275,10 @@
         if (!isset($item['tab_root']) && !$parent['_tab']) {
           $item['tab_root'] = $parent_path;
         }
-        // If a callback is not found, we try to find the first parent that
-        // has a callback.
-        if (!isset($item['access callback']) && isset($parent['access callback'])) {
+        // If an access callback is not found for a default local task we use
+        // the callback from the parent, since we expect them to be identical.
+        // In all other cases, the access parameters must be specified.
+        if (($item['type'] == MENU_DEFAULT_LOCAL_TASK) && !isset($item['access callback']) && isset($parent['access callback'])) {
           $item['access callback'] = $parent['access callback'];
           if (!isset($item['access arguments']) && isset($parent['access arguments'])) {
             $item['access arguments'] = $parent['access arguments'];