? menutree.patch
Index: README.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/menutree/README.txt,v
retrieving revision 1.4
diff -u -p -r1.4 README.txt
--- README.txt	9 Jan 2008 05:20:03 -0000	1.4
+++ README.txt	21 Jan 2008 13:53:40 -0000
@@ -1,14 +1,15 @@
 ABOUT
 
 This module provides a nested unordered list representation of a complete 
-Drupal menu structure.  menutree/1 provides a tree representation of menu 1, 
-menutree/2 provides a tree representation of menu 2, etc.  If no ID is 
-specified, the primary_links menu is used.  That allows it to be used as a 
-simple menu-based sitemap, give or take a path alias.
+Drupal menu structure. menutree/navigation provides a tree representation of
+the navigation menu, menutree/primary-links provides a tree representation
+of the primary links menu, etc. If no menu name is specified, the primary
+links menu is used. That allows it to be used as a simple menu-based
+sitemap, give or take a path alias.
 
 REQUIREMENTS
 
-- Drupal 5.x
+- Drupal 6.x
 
 INSTALLATION
 
@@ -19,6 +20,10 @@ INSTALLATION
 - Everything else is handled by the miracle of Drupal's automated install
   system.
 
+UPGRADING FROM 5.x
+
+Please note that the menutree paths have changed (e.g. menutree/1 is now menutree/navigation), so you will have to update any path aliases to the new paths.
+
 AUTHOR AND CREDIT
 
 Larry Garfield
Index: menutree.admin.inc
===================================================================
RCS file: menutree.admin.inc
diff -N menutree.admin.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ menutree.admin.inc	21 Jan 2008 13:53:40 -0000
@@ -0,0 +1,48 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Administrative page callbacks for menutree module.
+ */
+
+/**
+ * Form builder; Display menutree settings form.
+ */
+function menutree_settings() {
+  $form = array();
+
+  $form['menutree'] = array('#tree' => FALSE);
+
+  $menus = menu_get_menus();
+  foreach ($menus as $menu_name => $menu_title) {
+    $open = trim(variable_get('menutree_title_'. $menu_name, '') . variable_get('menutree_intro_text_'. $menu_name, ''));
+
+    $form['menutree'][$menu_name] = array(
+      '#type' => 'fieldset',
+      '#title' => $menu_title,
+      '#collapsible' => TRUE,
+      '#collapsed' => ($open ? FALSE : TRUE),
+      '#description' => t('The path <a href="@link">@path</a> will provide a complete tree of all menu items in this menu.  If you wish to set a custom title or header text, do so here.', array(
+        '@link' => url('menutree/'. $menu_name),  
+        '@path' => 'menutree/'. $menu_name,
+      )),
+    );
+    $form['menutree'][$menu_name]['menutree_title_'. $menu_name] = array(
+      '#type' => 'textfield',
+      '#title' => t('Page title'),
+      '#default_value' => variable_get('menutree_title_'. $menu_name, ''),
+      '#description' => t('A page title that is displayed instead of the root menu item title.'),
+    );
+    $form['menutree'][$menu_name]['menutree_intro_text_'. $menu_name] = array(
+      '#type' => 'textarea',
+      '#title' => t('Intro text'),
+      '#default_value' => variable_get('menutree_intro_text_'. $menu_name, ''),
+      '#resizable' => TRUE,
+      '#description' => t('An intro text that is displayed below the page title.'),
+    );
+  }
+
+  return system_settings_form($form);
+}
+
Index: menutree.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/menutree/menutree.info,v
retrieving revision 1.4
diff -u -p -r1.4 menutree.info
--- menutree.info	9 Jan 2008 05:20:03 -0000	1.4
+++ menutree.info	21 Jan 2008 13:53:40 -0000
@@ -1,3 +1,4 @@
 name = MenuTree
 description = Display a site-map page based on one or more menus
-dependencies = menu
+dependencies[] = menu
+core = 6.x
Index: menutree.install
===================================================================
RCS file: menutree.install
diff -N menutree.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ menutree.install	21 Jan 2008 13:53:40 -0000
@@ -0,0 +1,50 @@
+<?php
+// $Id$
+
+/**
+ * Implementation of hook_update_N().
+ *
+ * Update from 5.x to 6.x
+ */
+function menutree_update_1() {
+  // Update title and intro text of navigation tree
+  $title = variable_get('menutree_title_1', '');
+  if (!empty($title)) {
+    variable_set('menutree_title_navigation', $title);
+    variable_del('menutree_title_1');
+  }
+  $intro = variable_get('menutree_intro_text_1', '');
+  if (!empty($intro)) {
+    variable_set('menutree_intro_text_navigation', $intro);
+    variable_del('menutree_intro_text_1');
+  }
+
+  // Update title and intro text of primary links tree
+  $plid = variable_get('menu_primary_menu', 2);
+  $title = variable_get('menutree_title_'. $plid, '');
+  if (!empty($title)) {
+    variable_set('menutree_title_primary-links', $title);
+    variable_del('menutree_title_'. $plid);
+  }
+  $intro = variable_get('menutree_intro_text_'. $plid, '');
+  if (!empty($intro)) {
+    variable_set('menutree_intro_text_primary-links', $intro);
+    variable_del('menutree_intro_text_'. $plid);
+  }
+
+  // Update title and intro text of secondary links tree
+  $slid = variable_get('menu_secondary_menu', 2);
+  if ($slid != $plid) {
+    $title = variable_get('menutree_title_'. $slid, '');
+    if (!empty($title)) {
+      variable_set('menutree_title_secondary-links', $title);
+      variable_del('menutree_title_'. $slid);
+    }
+    $intro = variable_get('menutree_intro_text_'. $slid, '');
+    if (!empty($intro)) {
+      variable_set('menutree_intro_text_secondary-links', $intro);
+      variable_del('menutree_intro_text_'. $slid);
+    }
+  }
+  return array();
+}
Index: menutree.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/menutree/menutree.module,v
retrieving revision 1.3
diff -u -p -r1.3 menutree.module
--- menutree.module	9 Jan 2008 05:20:03 -0000	1.3
+++ menutree.module	21 Jan 2008 13:53:40 -0000
@@ -10,6 +10,15 @@
  *
  */
 
+/**
+ * Implementation of hook_theme()
+ */
+function menutree_theme() { 
+  return array(
+    'menutree_page' => array('arguments' => array('output' => NULL)),
+    'menutree_tree' => array('arguments' => array('menu_name' => NULL)),
+  );
+}
 
 /**
  * Implementation of hook_perm().
@@ -21,141 +30,101 @@ function menutree_perm() {
 /**
  * Implementation of hook_menu().
  */
-function menutree_menu($may_cache) {
+function menutree_menu() {
   $items = array();
-
-  if ($may_cache) {
-    $items[] = array(
-      'path' => 'menutree', 
-      'title' => t('Sitemap'),
-      'access' => user_access('view site tree'),
-      'callback' => 'menutree_display',
-      'type' => MENU_CALLBACK,
-    );
-    $items[] = array(
-      'path' => 'admin/build/menutree',
-      'title' => t('Menu trees'),
-      'description' => t('Configure page titles and intro text for menu tree pages.'),
-      'access' => user_access('administer menu tree'),
-      'callback' => 'drupal_get_form',
-      'callback arguments' => 'menutree_settings',
-    );
-  }
-
+  $items['menutree'] = array(
+    'title' => 'Sitemap',
+    'page callback' => 'menutree_display',
+    'page arguments' => array(menu_load('primary-links')),
+    'access callback' => 'user_access',
+    'access arguments' => array('view site tree'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['menutree/%menu'] = array(
+    'title' => 'Sitemap',
+    'page arguments' => array(1),
+    'type' => MENU_CALLBACK,
+  );
+  $items['admin/build/menutree'] = array(
+    'title' => 'Menu trees',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('menutree_settings'),
+    'description' => 'Configure page titles and intro text for menu tree pages.',
+    'access callback' => 'user_access',
+    'access arguments' => array('administer menu tree'),
+    'file' => 'menutree.admin.inc',
+  );
   return $items;
 }
 
 /**
- * Form builder; Display menutree settings form.
- */
-function menutree_settings() {
-  $form = array();
-  
-  $form['menutree'] = array('#tree' => FALSE);
-  
-  $menus = menu_get_root_menus();
-  foreach ($menus as $mid => $menu) {
-    $open = trim(variable_get('menutree_title_'. $mid, '') . variable_get('menutree_intro_text_'. $mid, ''));
- 
-    $form['menutree'][$mid] = array(
-      '#type' => 'fieldset',
-      '#title' => $menu,
-      '#collapsible' => TRUE,
-      '#collapsed' => ($open ? FALSE : TRUE),
-      '#description' => t('The path <a href="@link">@path</a> will provide a complete tree of all menu items in this menu.  If you wish to set a custom title or header text, do so here.', array(
-        '@link' => url('menutree/'. $mid),  
-        '@path' => 'menutree/'. $mid,
-      )),
-    );
-    $form['menutree'][$mid]['menutree_title_'. $mid] = array(
-      '#type' => 'textfield',
-      '#title' => t('Page title'),
-      '#default_value' => variable_get('menutree_title_'. $mid, ''),
-      '#description' => t('A page title that is displayed instead of the root menu item title.'),
-    );
-    $form['menutree'][$mid]['menutree_intro_text_'. $mid] = array(
-      '#type' => 'textarea',
-      '#title' => t('Intro text'),
-      '#default_value' => variable_get('menutree_intro_text_'. $mid, ''),
-      '#resizable' => TRUE,
-      '#description' => t('An intro text that is displayed below the page title.'),
-    );
-  }
-  
-  return system_settings_form($form);
-}
-
-/**
  * Display a fully-expanded version of the menu specified on the path
  *
- * @param int $pid
- *  The menu to display.  If none is specified, we default to the Primary Links menu
+ * @param $menu
+ *  The menu to display.
  */
-function menutree_display($pid = 0) {
+function menutree_display($menu) {
   $output = '';
   
-  // Default to the Primary Links menu
-  if (!$pid) {
-    $pid = variable_get('menu_primary_menu', 0);
-  }
-  
-  $menu = menu_get_item($pid);
-  if (empty($menu)) {
-    drupal_not_found();
-  }
-  
-  $title = variable_get('menutree_title_'. $pid, '');
-  drupal_set_title(check_plain($title ? $title : $menu['title']));
-  $intro = variable_get('menutree_intro_text_'. $pid, '');
+  $title = variable_get('menutree_title_'. $menu['menu_name'], '');
+  drupal_set_title(check_plain(!empty($title) ? $title : $menu['title']));
   
   // Output custom intro text.
+  $intro = variable_get('menutree_intro_text_'. $menu['menu_name'], '');
   if (!empty($intro)) {
     $output .= check_markup($intro, FILTER_FORMAT_DEFAULT, FALSE);
   }
   
-  $tree = theme('menutree_tree', $pid);
+  $tree = theme('menutree_tree', $menu['menu_name']);
   $output .= theme('menutree_page', $tree);
-  
+
   return $output;
 }
 
 /**
- * Generate the HTML for a menu tree.
+ * Get the data structure representing a named menu tree.
  *
- * @param $pid
- *   The parent id of the menu.
+ * This is a modified version of menu_tree_page_data() from menu.inc.
+ * The difference is that it returns a fully expanded menu tree rather
+ * than just expanding the items which are in the current breadcrumb.
  *
- * @ingroup themeable
- */
-function theme_menutree_tree($pid = 1) {
-  if ($tree = menutree_tree($pid)) {
-    return "\n<ul class=\"menu\">\n". $tree ."\n</ul>\n";
-  }
-}
-
-/**
- * Returns a rendered menu tree.
+ * @param $menu_name
+ *   The named menu links to return
  * 
- * This is a near-direct copy of menu_tree() from menu.inc.
- * The only difference is that we always call theme(menutree_tree) on the item 
- * rather than only if it's in the breadcrumb
- *
- * @param $pid
- *   The parent id of the menu.
- */
-function menutree_tree($pid = 1) {
-  $menu = menu_get_menu();
-  $output = '';
-
-  if (isset($menu['visible'][$pid]) && $menu['visible'][$pid]['children']) {
-    foreach ($menu['visible'][$pid]['children'] as $mid) {
-      $type = isset($menu['visible'][$mid]['type']) ? $menu['visible'][$mid]['type'] : NULL;
-      $children = isset($menu['visible'][$mid]['children']) ? $menu['visible'][$mid]['children'] : NULL;
-      $output .= theme('menu_item', $mid, theme('menutree_tree', $mid), count($children) == 0);
+ * @return
+ *   An array of menu links, in the order they should be rendered. The array
+ *   is a list of associative arrays -- these have two keys, link and below.
+ *   link is a menu item, ready for theming as a link. Below represents the
+ *   submenu below the link if there is one, and it is a subtree that has the
+ *   same structure described for the top-level array.
+ */
+function menutree_tree_page_data($menu_name) {
+  $args = array(0);
+
+  // Collect all the links, and then add all of
+  // their children to the list as well.
+  do {
+    $result = db_query("SELECT mlid FROM {menu_links} WHERE menu_name = '%s' AND has_children = 1 AND plid IN (". db_placeholders($args) .') AND mlid NOT IN ('. db_placeholders($args) .')', array_merge(array($menu_name), $args, $args));
+    $has_rows = FALSE;
+    while ($item = db_fetch_array($result)) {
+      $args[] = $item['mlid'];
+      $has_rows = TRUE;
     }
-  }
+  } while ($has_rows);
+  array_unshift($args, $menu_name);
 
-  return $output;
+  // 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.
+  $tree = menu_tree_data(db_query("
+    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.*
+    FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path
+    WHERE ml.menu_name = '%s' AND ml.plid IN (". db_placeholders($args) .")
+    ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC, p6 ASC, p7 ASC, p8 ASC, p9 ASC", $args));
+
+  // Check access for the current user to each item in the tree.
+  menu_tree_check_access($tree);
+  return $tree;
 }
 
 /**
@@ -165,11 +134,23 @@ function menutree_tree($pid = 1) {
  *
  * @param string $output
  *  The menutree, pre-rendered
+ *
  * @ingroup themeable
  */
 function theme_menutree_page($output) {
-  
-  return '<div class="menutree-page">' . $output . "</div>\n";
-  
+  return '<div class="menutree-page">'. $output ."</div>\n";
 }
 
+/**
+ * Generate the HTML for a menu tree.
+ *
+ * @param $menu_name
+ *   The name of the menu.
+ *
+ * @ingroup themeable
+ */
+function theme_menutree_tree($menu_name) {
+  if ($output = menu_tree_output(menutree_tree_page_data($menu_name))) {
+    return "<ul class=\"menu\">". $output ."</ul>\n";
+  }
+}
