? 241288_token_code_cleanup.patch
? 258326_token_bookpath_hierarchy_broken_deep.patch
Index: token.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/token/token.install,v
retrieving revision 1.2
diff -u -p -r1.2 token.install
--- token.install	31 Jul 2007 12:41:07 -0000	1.2
+++ token.install	19 Jun 2008 20:58:17 -0000
@@ -1,5 +1,12 @@
 <?php
-// $Id $
+// $Id$
+
+/**
+ * @file
+ * The install and update code for the token module.
+ *
+ * @ingroup token
+ */
 
 function token_install() {
   db_query("UPDATE {system} SET weight = 10 WHERE name = 'token'");
Index: token.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/token/token.module,v
retrieving revision 1.7.4.6
diff -u -p -r1.7.4.6 token.module
--- token.module	22 Mar 2008 13:20:35 -0000	1.7.4.6
+++ token.module	19 Jun 2008 20:58:18 -0000
@@ -1,6 +1,17 @@
 <?php
 // $Id: token.module,v 1.7.4.6 2008/03/22 13:20:35 greggles Exp $
 
+/**
+ * @file
+ * The token API module.
+ *
+ * The token module provides an API for providing tokens to other modules.
+ * Tokens are small bits of text that can be placed into larger documents 
+ * via simple placeholders, like %site-name or [user].
+ *
+ * @ingroup token
+ */
+
 function token_theme() {
   return array(
     'token_help' => array(
@@ -20,7 +31,7 @@ function token_theme() {
  * @param suffix
  *    The suffix your module will use when parsing tokens. Defaults to ']'
  * @return An HTML table containing the formatting docs.
- **/
+ */
 function theme_token_help($type = 'all', $prefix = '[', $suffix = ']') {
   token_include();
   $full_list = token_get_list($type);
@@ -28,7 +39,7 @@ function theme_token_help($type = 'all',
   $headers = array(t('Token'), t('Replacement value'));
   $rows = array();
   foreach ($full_list as $key => $category) {
-    $rows[] = array(array('data' => drupal_ucfirst($key) . ' ' . t('tokens'), 'class' => 'region', 'colspan' => 2));
+    $rows[] = array(array('data' => drupal_ucfirst($key) .' '. t('tokens'), 'class' => 'region', 'colspan' => 2));
     foreach ($category as $token => $description) {
       $row = array();
       $row[] = $prefix . $token . $suffix;
@@ -107,7 +118,7 @@ function token_token_list($type = 'all')
 /**
  * General function to include the files that token relies on for the real work.
  *
- **/
+ */
 function token_include() {
   $path = drupal_get_path('module', 'token');
   require_once("$path/token_node.inc");
@@ -146,7 +157,7 @@ function token_include() {
  *    matches. Defaults to a close-bracket.
  * @return The modified version of $original, with all substitutions
  *   made.
- **/
+ */
 function token_replace($original, $type = 'global', $object = NULL, $leading = '[', $trailing = ']', $options = array()) {
   $full = token_get_values($type, $object, FALSE, $options);
   return _token_replace_tokens($original, $full->tokens, $full->values, $leading, $trailing);
@@ -175,7 +186,7 @@ function token_replace($original, $type 
  *    matches. Defaults to a close-bracket.
  * @return The modified version of $original, with all substitutions
  *   made.
- **/
+ */
 function token_replace_multiple($original, $types = array('global' => NULL), $leading = '[', $trailing = ']', $options = array()) {
   $full = new stdClass();
   $full->tokens = $full->values = array();
Index: token_comment.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/token/token_comment.inc,v
retrieving revision 1.3.4.1
diff -u -p -r1.3.4.1 token_comment.inc
--- token_comment.inc	29 Oct 2007 04:40:41 -0000	1.3.4.1
+++ token_comment.inc	19 Jun 2008 20:58:18 -0000
@@ -2,13 +2,25 @@
 // $Id: token_comment.inc,v 1.3.4.1 2007/10/29 04:40:41 eaton Exp $
 
 /**
- * Implementation of hook_token_values()
+ * @file
+ * Implementations of token module hooks for the core comment module.
+ *
+ * The token module requires specific hooks to be added to modules
+ * so that those modules can return data about their objects to the
+ * token API.  Until and unless token becomes a part of core, the
+ * implementations of the token hooks for core modules are provided
+ * in the token module itself.
+ * @ingroup token
+ */
+
+/**
+ * Implementation of hook_token_values().
  */
 function comment_token_values($type, $object = NULL, $options = array()) {
   $values = array();
   switch ($type) {
     case 'comment':
-      
+
       // Cast to an object just in case fussy Drupal gave us an array
       $comment = (object)$object;
 
@@ -40,12 +52,12 @@ function comment_token_values($type, $ob
       $values['comment-d']               = date('j', $comment->timestamp);
       break;
   }
-  
+
   return $values;
 }
 
 /**
- * Implementation of hook_token_list()
+ * Implementation of hook_token_list().
  */
 function comment_token_list($type = 'all') {
   if ($type == 'comment' || $type == 'all') {
Index: token_node.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/token/token_node.inc,v
retrieving revision 1.5.4.6
diff -u -p -r1.5.4.6 token_node.inc
--- token_node.inc	7 Jun 2008 18:57:40 -0000	1.5.4.6
+++ token_node.inc	19 Jun 2008 20:58:18 -0000
@@ -2,7 +2,20 @@
 // $Id: token_node.inc,v 1.5.4.6 2008/06/07 18:57:40 eaton Exp $
 
 /**
- * Implementation of hook_token_values()
+ * @file
+ * Implementations of token module hooks for the core node and book modules.
+ *
+ * The token module requires specific hooks to be added to modules
+ * so that those modules can return data about their objects to the
+ * token API.  Until and unless token becomes a part of core, the
+ * implementations of the token hooks for core modules are provided
+ * in the token module itself.
+ *
+ * @ingroup token
+ */
+
+/**
+ * Implementation of hook_token_values().
  */
 function node_token_values($type, $object = NULL, $options = array()) {
   $values = array();
@@ -56,7 +69,7 @@ function node_token_values($type, $objec
         $menus = menu_get_menus();
         $menu_name = $node->menu['menu_name'];
         $menu_title = $menus[$menu_name];
-        $trail_raw = _menu_titles($menu_name, $node->nid);
+        $trail_raw = _menu_titles($node->menu, $node->nid);
         $trail = array();
         foreach ($trail_raw as $title) {
           $trail[] = check_plain($title);
@@ -84,17 +97,17 @@ function node_token_values($type, $objec
             // has a weight of at least 1 which will run after taxonomy has saved the data which allows us to
             // pull it out of the db here.
             if (!isset($term->name) || !isset($term->tid)) {
-              $vid = db_result(db_query("SELECT t.vid FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.nid = %d ORDER BY v.weight, t.weight, t.name LIMIT 1", $object->nid));
+              $vid = db_result(db_query_range("SELECT t.vid FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.nid = %d ORDER BY v.weight, t.weight, t.name", $object->nid, 0, 1));
               if (!$vid) {
                 continue;
               }
-              $term = db_fetch_object(db_query("SELECT t.tid, t.name FROM {term_data} t INNER JOIN {term_node} r ON r.tid = t.tid WHERE t.vid = %d AND r.nid = %d ORDER BY weight LIMIT 1", $vid, $object->nid));
+              $term = db_fetch_object(db_query_range("SELECT t.tid, t.name FROM {term_data} t INNER JOIN {term_node} r ON r.tid = t.tid WHERE t.vid = %d AND r.nid = %d ORDER BY weight", $vid, $object->nid, 0, 1));
               $term->vid = $vid;
             }
 
             // Ok, if we still don't have a term name maybe this is a pre-taxonomy submit node
             // So if it's a number we can get data from it
-            if(!isset($term->name) && is_array($original_term)) {
+            if (!isset($term->name) && is_array($original_term)) {
               $tid = array_shift($original_term);
               if (is_numeric($tid)) {
                 $term = taxonomy_get_term($tid);
@@ -105,7 +118,7 @@ function node_token_values($type, $objec
             $values['term-id'] = $term->tid;
             $vid = $term->vid;
 
-            if(!empty($vid)) {
+            if (!empty($vid)) {
               $vocabulary = taxonomy_vocabulary_load($vid);
               $values['vocab'] = check_plain($vocabulary->name);
               $values['vocab-raw'] = $vocabulary->name;
@@ -141,7 +154,7 @@ function node_token_values($type, $objec
 }
 
 /**
- * Implementation of hook_token_list()
+ * Implementation of hook_token_list().
  */
 function node_token_list($type = 'all') {
   if ($type == 'node' || $type == 'all') {
@@ -191,27 +204,39 @@ function node_token_list($type = 'all') 
 /**
  * Return an array of titles for a menu, from the top down to the specified node
  *
- * @param $menu_name
- *   The name of the menu.
+ * @param $menu_link
+ *   Fully loaded menu link, of node to which a path is desired.
  * @param $nid
- *   Id of the node at the bottom
+ *   Id of node.
  * @return
  *   An array of titles through the specified node
  */
-function _menu_titles($menu_name, $nid) {
-  // Get the menu hierarchy for the specified page.
-  $item = array_shift(menu_tree_all_data($menu_name));
-  $titles = array();
-  // Go down the active trail until the right level is reached.
-  while ($item) {
-    $titles[] = $item['link']['title'];
-    // Break AFTER getting the desired node's title
-    if ($item['link']['href'] == "node/$nid" || !$item['below']) {
-      break;
+function _menu_titles($menu_link, $nid) {
+  $tree = menu_tree_all_data($menu_link['menu_name'], $menu_link);
+
+  // Get mlid of all nodes in path - top-most parent to leaf node.
+  $parents = array();
+  for ($i = 1; $i < MENU_MAX_DEPTH; $i++) {
+    if ($menu_link["p$i"]) {
+      $parents[] = $menu_link["p$i"];
     }
-    $item = array_shift($item['below']);
   }
 
+  // Build the titles in this hierarchy.
+  $titles = array();
+  $current = array_shift($tree);
+  while ($current) {
+    if (in_array($current['link']['mlid'], $parents)) {
+      $titles[] = $current['link']['title'];
+      if ($current['link']['href'] == "node/". $nid) {
+        break;
+      }
+      // Go deeper in tree hierarchy.
+      $tree = $current['below'];
+    }
+    // Go to next sibling at same level in tree hierarchy.
+    $current = $tree ? array_shift($tree) : NULL;
+  }
   return $titles;
 }
 
@@ -221,10 +246,9 @@ function _menu_titles($menu_name, $nid) 
 function book_token_values($type, $object = NULL, $options = array()) {
   if ($type == 'node') {
     $node = $object;
-    if (isset($node->book)) {
+    if (!empty($node->book['menu_name'])) {
       $menus = menu_get_menus();
-      $menu_name = $node->book['menu_name'];
-      $trail_raw = _menu_titles($menu_name, $node->nid);
+      $trail_raw = _menu_titles($node->book, $node->nid);
       $book_raw = $trail_raw[0];
       $book = check_plain($book_raw);
       // For book paths, we don't include the current node's title (last in
@@ -234,7 +258,7 @@ function book_token_values($type, $objec
       foreach ($trail_raw as $title) {
         $trail[] = check_plain($title);
       }
-      $book_title = $trail[0];
+      $book_title = isset($trail[0]) ? $trail[0] : '';
       $tokens = array();
       $tokens['book'] = $book;
       $tokens['book-raw'] = $book_raw;
Index: token_taxonomy.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/token/token_taxonomy.inc,v
retrieving revision 1.3.4.2
diff -u -p -r1.3.4.2 token_taxonomy.inc
--- token_taxonomy.inc	8 Nov 2007 14:48:00 -0000	1.3.4.2
+++ token_taxonomy.inc	19 Jun 2008 20:58:18 -0000
@@ -2,16 +2,29 @@
 // $Id: token_taxonomy.inc,v 1.3.4.2 2007/11/08 14:48:00 greggles Exp $
 
 /**
- * Implementation of hook_token_values()
+ * @file
+ * Implementations of token module hooks for the core taxonomy module.
+ *
+ * The token module requires specific hooks to be added to modules
+ * so that those modules can return data about their objects to the
+ * token API.  Until and unless token becomes a part of core, the
+ * implementations of the token hooks for core modules are provided
+ * in the token module itself.
+ *
+ * @ingroup token
+ */
+
+/**
+ * Implementation of hook_token_values().
  */
 function taxonomy_token_values($type, $object = NULL, $options = array()) {
   $values = array();
   switch ($type) {
     case 'taxonomy':
       $category = $object;
-      
       $vid = $category->vid;
       $vocabulary = taxonomy_vocabulary_load($vid);
+
       $values['vid'] = $vid;
       $values['vocab'] = check_plain($vocabulary->name);
       $values['cat'] = check_plain($category->name);
@@ -25,7 +38,7 @@ function taxonomy_token_values($type, $o
 }
 
 /**
- * Implementation of hook_token_list()
+ * Implementation of hook_token_list().
  */
 function taxonomy_token_list($type = 'all') {
   if ($type == 'taxonomy' || $type == 'all') {
Index: token_user.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/token/token_user.inc,v
retrieving revision 1.3.4.1
diff -u -p -r1.3.4.1 token_user.inc
--- token_user.inc	29 Oct 2007 04:40:41 -0000	1.3.4.1
+++ token_user.inc	19 Jun 2008 20:58:18 -0000
@@ -2,7 +2,20 @@
 // $Id: token_user.inc,v 1.3.4.1 2007/10/29 04:40:41 eaton Exp $
 
 /**
- * Implementation of hook_token_values()
+ * @file
+ * Implementations of token module hooks for the core user module.
+ *
+ * The token module requires specific hooks to be added to modules
+ * so that those modules can return data about their objects to the
+ * token API.  Until and unless token becomes a part of core, the
+ * implementations of the token hooks for core modules are provided
+ * in the token module itself.
+ *
+ * @ingroup token
+ */
+
+/**
+ * Implementation of hook_token_values().
  */
 function user_token_values($type, $object = NULL, $options = array()) {
   $values = array();
@@ -34,7 +47,7 @@ function user_token_values($type, $objec
 }
 
 /**
- * Implementation of hook_token_list()
+ * Implementation of hook_token_list().
  */
 function user_token_list($type = 'all') {
   if ($type == 'user' || $type == 'all') {
@@ -43,7 +56,7 @@ function user_token_list($type = 'all') 
 
     $tokens['user']['uid']            = t("User's ID");
     $tokens['user']['mail']           = t("User's email address");
- 
+
     $tokens['user']['reg-date']       = t("User's registration date");
     $tokens['user']['reg-since']      = t("Days since the user registered");
     $tokens['user']['log-date']       = t("User's last login date");
