Index: modules/sitemenu/sitemenu.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/sitemenu/sitemenu.module,v
retrieving revision 1.16
diff -u -r1.16 sitemenu.module
--- modules/sitemenu/sitemenu.module	24 Apr 2006 01:16:51 -0000	1.16
+++ modules/sitemenu/sitemenu.module	7 May 2006 17:58:00 -0000
@@ -1,6 +1,6 @@
 <?php
 
-//$Id: sitemenu.module,v 1.16 2006/04/24 01:16:51 wafaa Exp $
+//$Id: sitemenu.module,v 1.15 2006/02/07 00:12:31 kbahey Exp $
 
 // Copyright 2005 Khalid Baheyeldin http://2bits.com
 
@@ -10,6 +10,202 @@
 define (VOCAB_TYPE_IMAGE, 1);
 define (VOCAB_TYPE_FORUM, 2);
 
+/**
+ * Module-specific functions
+ */
+
+/**
+ * @return string
+ */
+function _sitemenu_contents() {
+  $boxes = _sitemenu_overview(0, 'block');
+  return _sitemenu_print_boxes($boxes, 'block');
+} 
+
+/**
+ * Check whether the vocabulary is used by a known core 
+ * module, image or forum.
+ *
+ * @param int $vid
+ * @return boolean
+ */
+function _sitemenu_check_vid($vid) {
+
+  $vocab_type = VOCAB_TYPE_NONE;
+
+  if ($vid == variable_get('image_nav_vocabulary', '')) {
+    $vocab_type = VOCAB_TYPE_IMAGE;
+  }
+  elseif ($vid == variable_get('forum_nav_vocabulary', '')) {
+    $vocab_type = VOCAB_TYPE_FORUM;
+  }
+
+  return $vocab_type;
+}
+
+/**
+ * Get only requested vocabularies
+ *
+ * @param string $type Node type name
+ * @return array
+ */
+function _sitemenu_get_vocabularies($type = NULL) { 
+  $vocabularies = taxonomy_get_vocabularies($type);    
+  $omits = variable_get("sitemenu_overview_vocab", array()); //omit undesired vocabularies from listing  
+  foreach ($omits as $omit) {
+    unset($vocabularies[$omit]);
+  }
+  return $vocabularies;
+}  
+
+/**
+ * given a taxonomy tree, add nodes below all relevant terms
+ * @param object $tree Tree in which the nodes are inserted
+ * @param string $type Node type name
+ * @param string $mode Nodes are not injected unless $mode == 'page'
+ * @return array
+ */
+function _sitemenu_inject_nodes($tree, $type = NULL, $mode = 'page') {
+  $tree_node = $tree;
+  if ( $mode == 'page' ) {
+    $max_rows = variable_get("sitemenu_max_rows", "0");
+    $get_author_and_comments = variable_get("sitemenu_author_and_comments", "1");
+
+    // iterate over the tree backwards, so I don't trip on the new items
+    for ($i=count($tree)-1; $i>=0 ; $i--) {
+      $term = $tree[$i];
+      $sql = "SELECT n.nid, n.title, n.type ";
+      if ( $get_author_and_comments ) {
+        $sql .= ", u.uid, u.name ";
+      }
+      $sql .= "FROM {term_node} r LEFT JOIN {node} n ON r.nid = n.nid ";
+      if ($get_author_and_comments) {
+        $sql .= "LEFT JOIN {users} u ON n.uid = u.uid ";
+      }
+      $sql .= "WHERE n.status = '1' AND r.tid = '$term->tid' ORDER BY n.changed ASC";
+      $result = db_query_range($sql, 0, $max_rows);
+      while ($node = db_fetch_object($result)) {
+        if ($type && $node->type !== $type) {
+          // skip nodes not of specified type (if type was supplied)
+          }
+        else {
+        if ( $get_author_and_comments ) {
+          $detail = t("Author: %username", array('%username' => strip_tags(theme('username',$node))));
+          if (module_exist('comment')) {
+            $detail .= t(", comments: ") . comment_num_all($node->nid);
+            }
+          $link = l($node->title, "node/$node->nid", array ("title" => $detail)); 
+        }
+        else {
+          $link = l($node->title, "node/$node->nid"); 
+        }
+        $term_node = (object)(array ("nid" => $node->nid, "depth" => $term->depth+1, "link" => $link));
+        $part1 = array_slice($tree_node, 0, $i+1);
+        $part2 = array_slice($tree_node, $i+1, count($tree_node));
+        $part1[] = $term_node;
+        $tree_node = array_merge($part1, $part2);
+        }
+      }
+    }
+  }
+  
+  return $tree_node;
+}
+
+/**
+ * accepts an optional param for restricting nodes to a particular type
+ * @param string $type Node type name. Default to invalid node type '(integer) 0'
+ * @param string $mode Only 'page' mode can have node counts optionally displayed
+ * @return array Array of outline boxes, possibly empty, but never NULL
+ */
+function _sitemenu_overview($type = 0, $mode = 'page') {
+  $n=0;
+  $vocabularies = _sitemenu_get_vocabularies($type);
+  foreach ($vocabularies as $vocabulary) {
+    $tree_nodes = unserialize(cache_get("sitemenu:tree_nodes_$type". $vocabulary->vid));
+    if (!$tree_nodes) {
+      $tree = taxonomy_get_tree($vocabulary->vid);
+      
+      $get_node_count = variable_get("sitemenu_node_count", "1");
+      if ($get_node_count && $mode == 'page') {
+        // append the node count to each term name
+        for ($m=0; $m<count($tree); $m++) {
+          if ($count = taxonomy_term_count_nodes($tree[$m]->tid, $type)) {
+            $tree[$m]->count = $count;
+          } 
+        }
+      }
+    
+      $tree_nodes = _sitemenu_inject_nodes($tree, $type, $mode);
+    }  
+    $vocab_type = _sitemenu_check_vid($vocabulary->vid);
+
+    $boxes[$n]["content"] = theme('sitemenu_render_outline', $tree_nodes, $vocab_type);
+    $boxes[$n]["subject"] = $vocabulary->name;
+    $n++;
+  }
+  return $boxes ? $boxes : array();
+}
+
+/**
+ * Build the themed set of outline boxes
+ *
+ * @param array $boxes Each row has 'subject' and 'content' subrows
+ * @param string $mode If $mode == 'page', add pre- and post- content from settings
+ * @return string themed HTML
+ */
+function _sitemenu_print_boxes($boxes, $mode = 'page') {
+  if ($mode == 'page') {
+    $output .= variable_get("sitemenu_description", '');
+    }
+  foreach ($boxes as $box) {
+    if ($mode == 'page') {
+      $output .= theme("box", $box["subject"], $box["content"]);
+      }
+    else {
+      $output .= theme('sitemenu_box', $box["subject"], $box["content"]);
+      }
+    }
+  if ($mode == 'page') {
+    $output .= variable_get("sitemenu_footer", '');
+    }
+  return $output;
+}
+
+/**
+ * Drupal Hooks implementation
+ */
+
+
+/**
+ * hook_block
+ */
+function sitemenu_block($op = 'list', $delta = 0) {
+  $title = variable_get("sitemenu_block_title", t('Menu'));
+
+  switch ($op) {
+    case 'list':
+      $block[0]['info'] = $title;
+      break;
+
+    case 'view':
+      switch ($delta) {
+        case 0:
+          $block['subject'] = $title;
+          $block['content'] = _sitemenu_contents();
+          break;
+        }
+      break;
+
+    default:
+      break;
+    }
+    return $block;
+}
+
+/**
+ * hook_help
+ */
 function sitemenu_help($section) {
   $output ="";
 
@@ -26,7 +222,9 @@
   return $output;
 }
 
-
+/**
+ * hook_settings
+ */
 function sitemenu_settings() {
   $vocabularies = taxonomy_get_vocabularies();
   $select[0] = '<'. t("none") .'>';
@@ -69,14 +267,9 @@
   );
   $form['sitemenu_node_count'] = array(
     '#type' => 'checkbox',
-    '#title' => t('Show number of nodes for each term on site map page'),
+    '#title' => t('Show number of nodes for each term'),
     '#default_value' => variable_get("sitemenu_node_count", 1),
   );
-  $form['sitemenu_node_count_in_block'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Show number of nodes for each term in menu block'),
-    '#default_value' => variable_get("sitemenu_node_count_in_block", 1),
-  );
   $form['sitemenu_author_and_comments'] = array(
     '#type' => 'checkbox',
     '#title' => t('Show Author and number of Comments (in mousover)'),
@@ -91,13 +284,20 @@
     '#maxsize' => 10,
     '#description' => t('Number of nodes to show per taxonomy term. Set to 0 if you do not want nodes to listed.'),
   );
+  $form['sitemenu_footer'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Closing description'),
+    '#default_value' => variable_get('sitemenu_footer', null),
+    '#cols' => 70,
+    '#rows' => 7,
+    '#description' => t('This text will be displayed at the bottom of the site menu page'),
+  );
   return $form;
 }
 
-function sitemenu_perm() {
-  return array ("use sitemenu");
-}
-
+/**
+ * hook_link
+ */
 function sitemenu_link($type, $node = 0, $main = 0) {
   global $user;
 
@@ -110,79 +310,16 @@
   return $links;
 }
 
-function sitemenu_page() {
-  if (user_access("use sitemenu"))
-  {
-    $title = variable_get("sitemenu_overview_title", t("site map"));
-
-    $boxes = sitemenu_overview();
-    print theme("page", sitemenu_print_boxes($boxes) );
-  }
-}
-
-function sitemenu_print_boxes($boxes, $mode = 'page') {
-  if ($mode == 'page') {
-    $output .= variable_get("sitemenu_description", '');
-    }
-
-  foreach ($boxes as $box) {
-    if ($mode == 'page') {
-      $output .= theme("box", $box["subject"], $box["content"]);
-      }
-    else {
-      $output .= sitemenu_theme_box($box["subject"], $box["content"]);
-      }
-    }
-  return $output;
-}
-
-function sitemenu_theme_box($subtitle, $content) {
-  $output .= "<h3>$subtitle</h3>";
-  $output .= "$content";
-
-  return $output;
-}
-
-// accepts an optional param for restricting nodes to a particular type
-function sitemenu_overview($type = 0, $mode = 'page') {
-  $n=0;
-  $vocabularies = sitemenu_get_vocabularies($type);
-  foreach ($vocabularies as $vocabulary) {
-    $tree_nodes = unserialize(cache_get("sitemenu:tree_nodes_$type". $vocabulary->vid));
-    if (!$tree_nodes) {
-      $tree = taxonomy_get_tree($vocabulary->vid);
-      
-      $get_node_count = variable_get("sitemenu_node_count", "1");
-      $get_node_count_in_block = variable_get("sitemenu_node_count_in_block", "1");
-      if ( ($get_node_count && $mode == 'page') || ($get_node_count_in_block && $mode == 'block') ) {
-        // append the node count to each term name
-        for ($m=0; $m<count($tree); $m++) {
-          if ($count = taxonomy_term_count_nodes($tree[$m]->tid, $type)) {
-            $tree[$m]->name .= " ($count)";
-          } 
-        }
-      }
-    
-      $tree_nodes = sitemenu_inject_nodes($tree, $type, $mode);
-    }  
-    $vocab_type = _sitemenu_check_vid($vocabulary->vid);
-
-    $boxes[$n]["content"] = theme_sitemenu_render_outline ($tree_nodes, $vocab_type);
-    $boxes[$n]["subject"] = $vocabulary->name;
-    $n++;
-  }
-  return $boxes ? $boxes : array();
+/**
+ * hook_perm
+ */
+function sitemenu_perm() {
+  return array ("use sitemenu");
 }
 
-function sitemenu_get_vocabularies($type = NULL) { 
-  $vocabularies = taxonomy_get_vocabularies($type);    
-  $omits = variable_get("sitemenu_overview_vocab", array()); //omit undesired vocabularies from listing  
-  foreach ($omits as $omit) {
-    unset($vocabularies[$omit]);
-  }
-  return $vocabularies;
-}  
-
+/**
+ * hook_menu
+ */
 function sitemenu_menu($may_cache) {
   $items = array();
 
@@ -192,7 +329,8 @@
   if ($may_cache) {
     $items[] = array(
     'path'     => 'sitemenu',
-    'callback' => 'sitemenu_page',
+    'callback' => 'theme',
+    'callback arguments' => array('sitemenu_page'),
     'title'    => $title,
     'access'   => $access,
     'weight'   => 0 );
@@ -201,57 +339,49 @@
   return $items;
 }
 
-// given a taxonomy tree, add nodes below all relevant terms
-function sitemenu_inject_nodes($tree, $type = NULL, $mode = 'page') {
-  $tree_node = $tree;
-  if ( $mode == 'page' ) {
-    $max_rows = variable_get("sitemenu_max_rows", "0");
-    $get_author_and_comments = variable_get("sitemenu_author_and_comments", "1");
+/**
+ * Themeable elements
+ */
+
+/**
+ * Theme the box containing the outline for a given vocabulary
+ *
+ * @param string $subtitle 
+ * @param string $content
+ * @return string Themed HTML
+ * @see theme_sitemenu_render_outline for the generation of $content
+ * @see _sitemenu_overview() which actually uses this function
+ */
+function theme_sitemenu_box($subtitle, $content) {
+  $output  = "<h3>$subtitle</h3>";
+  $output .= "$content";
+  return $output;
+}
 
-    // iterate over the tree backwards, so I don't trip on the new items
-    for ($i=count($tree)-1; $i>=0 ; $i--) {
-      $term = $tree[$i];
-      $sql = "SELECT n.nid, n.title, n.type ";
-      if ( $get_author_and_comments ) {
-        $sql .= ", u.uid, u.name ";
-      }
-      $sql .= "FROM {term_node} r LEFT JOIN {node} n ON r.nid = n.nid ";
-      if ($get_author_and_comments) {
-        $sql .= "LEFT JOIN {users} u ON n.uid = u.uid ";
-      }
-      $sql .= "WHERE n.status = '1' AND r.tid = '$term->tid' ORDER BY n.changed ASC";
-      $result = db_query_range($sql, 0, $max_rows);
-      while ($node = db_fetch_object($result)) {
-        if ($type && $node->type !== $type) {
-          // skip nodes not of specified type (if type was supplied)
-          }
-        else {
-        if ( $get_author_and_comments ) {
-          $detail = t("Author: %username", array('%username' => strip_tags(theme('username',$node))));
-          if (module_exist('comment')) {
-            $detail .= t(", comments: ") . comment_num_all($node->nid);
-            }
-          $link = l($node->title, "node/$node->nid", array ("title" => $detail)); 
-        }
-        else {
-          $link = l($node->title, "node/$node->nid"); 
-        }
-        $term_node = (object)(array ("nid" => $node->nid, "depth" => $term->depth+1, "link" => $link));
-        $part1 = array_slice($tree_node, 0, $i+1);
-        $part2 = array_slice($tree_node, $i+1, count($tree_node));
-        $part1[] = $term_node;
-        $tree_node = array_merge($part1, $part2);
-        }
-      }
-    }
+/**
+ * Theme the main sitemenu page
+ *
+ * @return string HTML
+ */
+function theme_sitemenu_page() {
+  if (user_access("use sitemenu")) {
+    $title = variable_get("sitemenu_overview_title", t("site map"));
+    $boxes = _sitemenu_overview();
+    $output = _sitemenu_print_boxes($boxes, 'box');
+    return $output;
   }
-  
-  return $tree_node;
 }
 
+/**
+ * Theme a vocabulary outline
+ *
+ * @param array $tree Vocabulary tree
+ * @param string $vocab_type Node type for the vocabulary
+ * @return string Themed HTML
+ */
 function theme_sitemenu_render_outline($tree, $vocab_type) {
   global $ul;
-  
+
   $old_depth = -1;
   $output = "";
   for ($m = 0; $m < count($tree); $m++) {
@@ -281,12 +411,11 @@
         break;
     }
 
-    if ($term->description) {
+    if (isset($term->description)) {
       // use the description as a title attribute for terms
       $link = l($term->name, $path . $term->tid,  array ("title" => $term->description));
     }
-    else
-    if ($term->link) {
+    elseif (isset($term->link)) {
       // This is a node
       $link = $term->link;
     }
@@ -294,6 +423,9 @@
       $link = l($term->name, $path . $term->tid );
     }
 
+    if (isset($term->count))
+      $link .= " ($term->count)";
+
     // if children exist, output with proper class and id attributes, else, output item with
     // specified link or default link
     if ($term->depth < $tree[$m+1]->depth) {
@@ -308,46 +440,4 @@
   if ($term->depth == 0) { $output .= '</ul>'."\n"; }
   $output .= str_repeat("</ul>\n", $term->depth);
   return $output;
-}
-
-function sitemenu_block($op = 'list', $delta = 0) {
-  $title = variable_get("sitemenu_block_title", t('Menu'));
-
-  switch ($op) {
-    case 'list':
-      $block[0]['info'] = $title;
-      break;
-
-    case 'view':
-      switch ($delta) {
-        case 0:
-          $block['subject'] = $title;
-          $block['content'] = sitemenu_contents();
-          break;
-        }
-      break;
-
-    default:
-      break;
-    }
-    return $block;
-}
-
-function sitemenu_contents() {
-  $boxes = sitemenu_overview(0, 'block');
-  return sitemenu_print_boxes($boxes, 'block');
-} 
-
-function _sitemenu_check_vid($vid) {
-
-  $vocab_type = VOCAB_TYPE_NONE;
-
-  if ($vid == variable_get('image_nav_vocabulary', '')) {
-    $vocab_type = VOCAB_TYPE_IMAGE;
-  }
-  elseif ($vid == variable_get('forum_nav_vocabulary', '')) {
-    $vocab_type = VOCAB_TYPE_FORUM;
-  }
-
-  return $vocab_type;
-}
+}
\ No newline at end of file
