Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.185
diff -u -p -r1.185 menu.inc
--- includes/menu.inc	5 Jul 2007 08:48:57 -0000	1.185
+++ includes/menu.inc	5 Jul 2007 21:07:13 -0000
@@ -645,7 +645,7 @@ function menu_tree_all_data($menu_name =
       // later exclude all the children of a hidden item.
       // No need to order by p6 - there is a sort by weight later.
       $tree[$cid] = menu_tree_data(db_query("
-        SELECT m.*, ml.menu_name, ml.mlid, ml.plid, ml.link_path, ml.router_path, ml.hidden, ml.external, ml.has_children, ml.expanded, ml.weight + 50000 AS weight, ml.depth, ml.p1, ml.p2, ml.p3, ml.p4, ml.p5, ml.p6, ml.module, ml.link_title, ml.options
+        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, ml.*
         FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path
         WHERE ml.menu_name = '%s'". $where ." AND ml.hidden >= 0
         ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC", $args), $parents);
@@ -731,7 +731,7 @@ function menu_tree_page_data($menu_name 
         // later exclude all the children of a hidden item.
         // No need to order by p6 - there is a sort by weight later.
         $tree[$cid] = menu_tree_data(db_query("
-          SELECT m.*, ml.menu_name, ml.mlid, ml.plid, ml.link_path, ml.router_path, ml.hidden, ml.external, ml.has_children, ml.expanded, ml.weight + 50000 AS weight, ml.depth, ml.p1, ml.p2, ml.p3, ml.p4, ml.p5, ml.p6, ml.module, ml.link_title, ml.options
+          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, ml.*
           FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path
           WHERE ml.menu_name = '%s' AND ml.plid IN (". $placeholders .") AND ml.hidden >= 0
           ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC", $args), $parents);
@@ -751,17 +751,44 @@ function menu_tree_page_data($menu_name 
  * Check access and perform other dynamic operations for each link in the tree.
  */
 function menu_tree_check_access(&$tree, $show_hidden = FALSE) {
-  // TODO: Special case node links and access check via db_rewite_sql().
-  // TODO: Move sorting of siblings in the tree here so that we can sort based
-  // on the localized title of each link. Currently the dorting is done in
-  // function _menu_tree_data().
+  $node_links = array();
+  $nids = _menu_tree_collect_node_links($node_links, $tree);
+  if ($nids) {
+    $result = db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.nid IN (". implode(',', $nids) .")"));
+    while ($n = db_fetch_array($result)) {
+      $node_links[$n['nid']]['access'] = TRUE;
+    }
+  }
   _menu_tree_check_access($tree, $show_hidden);
+  return;
+}
+
+/**
+ * Recursive helper function for menu_tree_check_access() - checks node links.
+ */
+function _menu_tree_collect_node_links(&$node_links, &$tree) {
+  static $nids = array();
+  foreach ($tree as $key => $v) {
+    if ($tree[$key]['link']['router_path'] == 'node/%') {
+      $nid = substr($tree[$key]['link']['link_path'], 5);
+      if (ctype_digit($nid)) {
+        $node_links[$nid] = &$tree[$key]['link'];
+        $nids[] = $nid;
+        $tree[$key]['link']['access'] = FALSE;
+      }
+    }
+    if ($tree[$key]['below']) {
+      _menu_tree_collect_node_links($node_links, $tree[$key]['below']);
+    }
+  }
+  return $nids;
 }
 
 /**
  * Recursive helper function for menu_tree_check_access()
  */
 function _menu_tree_check_access(&$tree, $show_hidden) {
+  $new_tree = array();
   foreach ($tree as $key => $v) {
     $item = &$tree[$key]['link'];
     if (!$item['hidden'] || $show_hidden) {
@@ -770,13 +797,19 @@ function _menu_tree_check_access(&$tree,
     else {
       $item['access'] = FALSE;
     }
-    if (!$item['access']) {
-      unset($tree[$key]);
-    }
-    elseif ($tree[$key]['below']) {
-      _menu_tree_check_access($tree[$key]['below'], $show_hidden);
+    if ($item['access']) {
+      if ($tree[$key]['below']) {
+        _menu_tree_check_access($tree[$key]['below'], $show_hidden);
+      }
+      // The weights are made a uniform 5 digits by adding 50000 as an offset.
+      // After _menu_link_translate(), $item['title'] has the localized link title.
+      // Adding the mlid to the end of the index insures that it is unique.
+      $new_tree[(50000 + $item['weight']) .' '. $item['title'] .' '. $item['mlid']] = $tree[$key];
     }
   }
+  // Sort siblings in the tree based on the weights and localized titles.
+  ksort($new_tree);
+  $tree = $new_tree;
 }
 
 /**
@@ -812,9 +845,8 @@ function _menu_tree_data($result, $paren
     // We need to determine if we're on the path to root so we can later build
     // the correct active trail and breadcrumb.
     $item['in_active_trail'] = in_array($item['mlid'], $parents);
-    // The weights are uniform 5 digits because of the 50000 offset in the
-    // query. We add mlid at the end of the index to insure uniqueness.
-    $index = $previous_element ? ($previous_element['weight'] .' '. drupal_strtolower($previous_element['link_title']) . $previous_element['mlid']) : '';
+
+    $index = $previous_element ? ($previous_element['mlid']) : '';
     // The current item is the first in a new submenu.
     if ($item['depth'] > $depth) {
       // _menu_tree returns an item and the menu tree structure.
@@ -825,7 +857,6 @@ function _menu_tree_data($result, $paren
       );
       // We need to fall back one level.
       if (!isset($item) || $item['depth'] < $depth) {
-        ksort($tree);
         return array($item, $tree);
       }
       // This will be the link to be output in the next iteration.
@@ -851,12 +882,11 @@ function _menu_tree_data($result, $paren
   }
   if ($previous_element) {
     // We have one more link dangling.
-    $tree[$previous_element['weight'] .' '. drupal_strtolower($previous_element['link_title']) .' '. $previous_element['mlid']] = array(
+    $tree[$previous_element['mlid']] = array(
       'link' => $previous_element,
       'below' => '',
     );
   }
-  ksort($tree);
   return array($remnant, $tree);
 }
 
