? 0-token-comment-changed-D7.patch
? 0-token-get-info-type-D7.patch
? 0-token-lightestterm-D7.patch
? 125640-token-profile-D7.patch
? 224262-token-current-page-number-D7.patch
? 736178-token-node-source-D7.patch
? 738372-token-ui-tree-D7.patch
? 776952-token-blocks-D7.patch
? 821008-token-devel-D7.patch
? 829744-token-entity-path-D7.patch
? 844912-token-search-tokens-D7.patch
? 845146-token-presort-tokens-D7.patch
? 845148-token-user-email-tree-D7.patch
? jquery-ui-tree
? jstree
? menu.tokens.inc
? patches
? temp-D7.patch
? temp-token-entity-id-D7.patch
? tests
? token.inc
? treeTable
Index: token.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/token/token.module,v
retrieving revision 1.41
diff -u -p -r1.41 token.module
--- token.module	21 Sep 2010 03:17:11 -0000	1.41
+++ token.module	21 Sep 2010 04:05:59 -0000
@@ -2,6 +2,11 @@
 // $Id: token.module,v 1.41 2010/09/21 03:17:11 davereid Exp $
 
 /**
+ * The maximum depth for token tree recursion.
+ */
+define('TOKEN_MAX_DEPTH', 9);
+
+/**
  * Impelements hook_help().
  */
 function token_help($path, $arg) {
@@ -24,6 +29,47 @@ function token_menu() {
     'type' => MENU_CALLBACK,
     'file' => 'token.pages.inc',
   );
+
+  // Devel token pages.
+  if (module_exists('devel')) {
+    $items['node/%node/devel/token'] = array(
+      'title' => 'Tokens',
+      'page callback' => 'token_devel_token_object',
+      'page arguments' => array('node', 1),
+      'access arguments' => array('access devel information'),
+      'type' => MENU_LOCAL_TASK,
+      'file' => 'token.pages.inc',
+      'weight' => 5,
+    );
+    $items['comment/%comment/devel/token'] = array(
+      'title' => 'Tokens',
+      'page callback' => 'token_devel_token_object',
+      'page arguments' => array('comment', 1),
+      'access arguments' => array('access devel information'),
+      'type' => MENU_LOCAL_TASK,
+      'file' => 'token.pages.inc',
+      'weight' => 5,
+    );
+    $items['taxonomy/term/%taxonomy_term/devel/token'] = array(
+      'title' => 'Tokens',
+      'page callback' => 'token_devel_token_object',
+      'page arguments' => array('term', 2),
+      'access arguments' => array('access devel information'),
+      'type' => MENU_LOCAL_TASK,
+      'file' => 'token.pages.inc',
+      'weight' => 5,
+    );
+    $items['user/%user/devel/token'] = array(
+      'title' => 'Tokens',
+      'page callback' => 'token_devel_token_object',
+      'page arguments' => array('user', 1),
+      'access arguments' => array('access devel information'),
+      'type' => MENU_LOCAL_TASK,
+      'file' => 'token.pages.inc',
+      'weight' => 5,
+    );
+  }
+
   return $items;
 }
 
@@ -129,6 +175,13 @@ function token_module_implements_alter(&
 }
 
 /**
+ * Implements hook_flush_caches().
+ */
+function token_flush_caches() {
+  return array('cache_token');
+}
+
+/**
  * Retrieve, sort, store token info from the cache.
  */
 function token_get_info($token_type = NULL) {
@@ -143,7 +196,7 @@ function token_get_info($token_type = NU
 
   if (empty($token_info)) {
     $langcode = $language->language;
-    if ($cache = cache_get("token_info:$langcode")) {
+    if ($cache = cache_get("info:$langcode", 'cache_token')) {
       $token_info = $cache->data;
     }
     else {
@@ -156,7 +209,7 @@ function token_get_info($token_type = NU
       }
 
       // Store info in cache for future use.
-      cache_set("token_info:$langcode", $token_info);
+      cache_set("info:$langcode", $token_info, 'cache_token');
     }
   }
 
@@ -359,3 +412,146 @@ function token_form_user_admin_settings_
     );
   }
 }
+
+/**
+ * Build a tree array of tokens used for themeing or information.
+ *
+ * @param $token_type
+ *   The token type. Should not be an alias (e.g. use 'user' instead of
+ *   'current-user').
+ * @param $flat_tree
+ *   A boolean if TRUE will only make a flat array of tokens, otherwise
+ *   child tokens will be inside the 'children' parameter of a token.
+ * @param $show_restricted
+ *   A boolean if TRUE will show restricted tokens. Otherwise they will be
+ *   hidden. Default is FALSE.
+ * @param $recursion_limit
+ *   An integer with the maximum number of token levels to recurse.
+ * @param $parents
+ *   An optional array with the current parents of the tokens.
+ */
+function token_build_tree($token_type, array $options = array()) {
+  global $language;
+
+  // Static cache of already built token trees.
+  $trees = &drupal_static(__FUNCTION__, array());
+
+  $options += array(
+    'restricted' => FALSE,
+    'depth' => 4,
+    'data' => array(),
+    'values' => FALSE,
+    'flat' => FALSE,
+  );
+
+  // Do not allow past the maximum token information depth.
+  $options['depth'] = min($options['depth'], TOKEN_MAX_DEPTH);
+
+  $tree_cid = "tree:{$token_type}:{$language->language}:{$options['depth']}";
+
+  // If we do not have this base tree in the static cache, check {cache_token}
+  // otherwise generate and store it in the cache.
+  if (!isset($trees[$tree_cid])) {
+    if ($cache = cache_get($tree_cid, 'cache_token')) {
+      $trees[$tree_cid] = $cache->data;
+    }
+    else {
+      $options['parents'] = array();
+      $trees[$tree_cid] = _token_build_tree($token_type, $options);
+      cache_set($tree_cid, $trees[$tree_cid], 'cache_token');
+    }
+  }
+
+  $tree = $trees[$tree_cid];
+
+  // If the user has requested a flat tree, convert it.
+  if (!empty($options['flat'])) {
+    $tree = token_flatten_tree($tree);
+  }
+
+  // Fill in token values.
+  if (!empty($options['values'])) {
+    $token_values = array();
+    foreach ($tree as $token => $token_info) {
+      if (!empty($token_info['dynamic']) || !empty($token_info['restricted'])) {
+        continue;
+      }
+      elseif (!isset($token_info['value'])) {
+        $token_values[$token_info['token']] = $token;
+      }
+    }
+    if (!empty($token_values)) {
+      $token_values = token_generate($token_type, $token_values, $options['data']);
+      foreach ($token_values as $token => $replacement) {
+        $tree[$token]['value'] = $replacement;
+      }
+    }
+  }
+
+  return $tree;
+}
+
+/**
+ * Flatten a token tree.
+ */
+function token_flatten_tree($tree) {
+  $result = array();
+  foreach ($tree as $token => $token_info) {
+    $result[$token] = $token_info;
+    if (isset($token_info['children']) && is_array($token_info['children'])) {
+      $result += token_flatten_tree($token_info['children']);
+      unset($result[$token]['children']);
+    }
+  }
+  return $result;
+}
+
+/**
+ * Generate a token tree.
+ */
+function _token_build_tree($token_type, array $options) {
+  $options += array(
+    'parents' => array(),
+  );
+
+  $info = token_get_info();
+  if ($options['depth'] <= 0 || !isset($info['types'][$token_type])) {
+    return array();
+  }
+
+  $tree = array();
+  foreach ($info['tokens'][$token_type] as $token => $token_info) {
+    // Build the raw token string.
+    $token_parents = $options['parents'];
+    if (empty($token_parents)) {
+      // If the parents array is currently empty, assume the token type is its
+      // parent.
+      $token_parents[] = $token_type;
+    }
+    $token_parents[] = $token;
+    if (!empty($token_info['dynamic'])) {
+      $token_parents[] = '?';
+    }
+    $raw_token = '[' . implode(':', $token_parents) . ']';
+    $tree[$raw_token] = $token_info;
+    $tree[$raw_token]['raw token'] = $raw_token;
+
+    // Add the token's real name (leave out the base token type).
+    $tree[$raw_token]['token'] = implode(':', array_slice($token_parents, 1));
+
+    // Add the token's parent as its raw token value.
+    if (!empty($options['parents'])) {
+      $tree[$raw_token]['parent'] = '[' . implode(':', $options['parents']) . ']';
+    }
+
+    // Fetch the child tokens.
+    if (!empty($token_info['type'])) {
+      $child_options = $options;
+      $child_options['depth']--;
+      $child_options['parents'] = $token_parents;
+      $tree[$raw_token]['children'] = _token_build_tree($token_info['type'], $child_options);
+    }
+  }
+
+  return $tree;
+}
Index: token.pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/token/token.pages.inc,v
retrieving revision 1.10
diff -u -p -r1.10 token.pages.inc
--- token.pages.inc	11 Jul 2010 02:55:08 -0000	1.10
+++ token.pages.inc	21 Sep 2010 04:05:59 -0000
@@ -28,69 +28,6 @@ function theme_tree_table($variables) {
 }
 
 /**
- * Build a tree array of tokens used for themeing or information.
- *
- * @param $token_type
- *   The token type. Should not be an alias (e.g. use 'user' instead of
- *   'current-user').
- * @param $flat_tree
- *   A boolean if TRUE will only make a flat array of tokens, otherwise
- *   child tokens will be inside the 'children' parameter of a token.
- * @param $show_restricted
- *   A boolean if TRUE will show restricted tokens. Otherwise they will be
- *   hidden. Default is FALSE.
- * @param $recursion_limit
- *   An integer with the maximum number of token levels to recurse.
- * @param $parents
- *   An optional array with the current parents of the tokens.
- */
-function token_build_tree($token_type, $flat_tree = FALSE, $show_restricted = FALSE, $recursion_limit = 4, $parents = array()) {
-  $info = token_get_info();
-  if ($recursion_limit <= 0 || !isset($info['types'][$token_type])) {
-    return array();
-  }
-
-  $tree = array();
-  foreach ($info['tokens'][$token_type] as $token => $token_info) {
-    // Skip restricted tokens if desired (default behavior).
-    if (!$show_restricted && !empty($token_info['restricted'])) {
-      continue;
-    }
-    // Build the raw token string.
-    $token_parents = $parents;
-    if (empty($token_parents)) {
-      // If the parents array is currently empty, assume the token type is its
-      // parent.
-      $token_parents[] = $token_type;
-    }
-    $token_parents[] = $token;
-    if (!empty($token_info['dynamic'])) {
-      $token_parents[] = '?';
-    }
-    $raw_token = '[' . implode(':', $token_parents) . ']';
-    $tree[$raw_token] = $token_info;
-
-    // Add the token's parent as its raw token value.
-    if (!empty($parents)) {
-      $tree[$raw_token]['parent'] = '[' . implode(':', $parents) . ']';
-    }
-
-    // Fetch the child tokens.
-    if (!empty($token_info['type'])) {
-      $children = token_build_tree($token_info['type'], $flat_tree, $show_restricted, $recursion_limit - 1, $token_parents);
-      if ($flat_tree) {
-        $tree = array_merge($tree, $children);
-      }
-      else {
-        $tree[$raw_token]['children'] = $children;
-      }
-    }
-  }
-  
-  return $tree;
-}
-
-/**
  * Provide a 'tree' display of nested tokens.
  *
  * @ingroup themeable
@@ -118,16 +55,29 @@ function theme_token_tree($variables) {
       continue;
     }
     $type_info += array('type' => $type);
-    $parent = array();
 
     if (count($token_types) > 1) {
-      $rows[] = _token_token_tree_format_row($type, $type_info, TRUE);
-      $parent = array($type);
+      $row = _token_token_tree_format_row($type, $type_info, TRUE);
+      unset($row['data']['value']);
+      $rows[] = $row;
     }
 
-    $tree = token_build_tree($type_info['type'], TRUE, $variables['show_restricted'], $variables['recursion_limit'], $parent);
+    $options = array(
+      'flat' => TRUE,
+      'restricted' => $variables['show_restricted'],
+      'depth' => $variables['recursion_limit'],
+    );
+    $tree = token_build_tree($type_info['type'], $options);
     foreach ($tree as $token => $token_info) {
-      $rows[] = _token_token_tree_format_row($token, $token_info);
+      if (!empty($token_info['restricted']) && empty($variables['show_restricted'])) {
+        continue;
+      }
+      if (!isset($token_info['parent'])) {
+        $token_info['parent'] = $type;
+      }
+      $row = _token_token_tree_format_row($token, $token_info);
+      unset($row['data']['value']);
+      $rows[] = $row;
     }
   }
 
@@ -158,6 +108,7 @@ function _token_token_tree_format_row($t
     'data' => array(
       'name' => $token_info['name'],
       'token' => '',
+      'value' => '',
       'description' => $token_info['description'],
     ),
   );
@@ -172,6 +123,9 @@ function _token_token_tree_format_row($t
       'data' => $token,
       'class' => array('token-key'),
     );
+    if (isset($token_info['value'])) {
+      $row['data']['value'] = $token_info['value'];
+    }
     if (!empty($token_info['parent'])) {
       $row['parent'] = _token_clean_css_identifier($token_info['parent']);
     }
@@ -192,6 +146,57 @@ function _token_clean_css_identifier($id
   return drupal_clean_css_identifier('token-' . trim($id, '[]'), array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => '', ':' => '-'));
 }
 
+/**
+ * Menu callback; prints the available tokens and values for an object.
+ */
+function token_devel_token_object($entity, $object) {
+
+  $token_types = array($entity);
+  $info = token_get_info();
+
+  $header = array(
+    t('Token'),
+    t('Value'),
+  );
+  $rows = array();
+
+  foreach ($info['types'] as $type => $type_info) {
+    if (!in_array($type, $token_types)) {
+      continue;
+    }
+
+    $options = array(
+      'flat' => TRUE,
+      'values' => TRUE,
+      'data' => array($entity => $object),
+    );
+    $tree = token_build_tree($type, $options);
+    foreach ($tree as $token => $token_info) {
+      if (!empty($token_info['restricted'])) {
+        continue;
+      }
+      if (!isset($token_info['value']) && !empty($token_info['parent']) && !isset($tree[$token_info['parent']]['value'])) {
+        continue;
+      }
+      $row = _token_token_tree_format_row($token, $token_info);
+      unset($row['data']['description']);
+      unset($row['data']['name']);
+      $rows[] = $row;
+    }
+  }
+
+  drupal_add_js(drupal_get_path('module', 'token') . '/token.js');
+  drupal_add_css(drupal_get_path('module', 'token') . '/token.css');
+
+  $table_options = array(
+    'header' => $header,
+    'rows' => $rows,
+    'attributes' => array('class' => array('token-tree')),
+    'empty' => t('No tokens available.'),
+  );
+  return theme('tree_table', $table_options);
+}
+
 function token_autocomplete() {
   $args = func_get_args();
   $string = implode('/', $args);
