Index: modules/taxonomy/views_handler_field_term_node_tid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/taxonomy/views_handler_field_term_node_tid.inc,v
retrieving revision 1.4
diff -u -p -r1.4 views_handler_field_term_node_tid.inc
--- modules/taxonomy/views_handler_field_term_node_tid.inc	1 Jul 2009 23:07:14 -0000	1.4
+++ modules/taxonomy/views_handler_field_term_node_tid.inc	25 Jul 2010 15:56:28 -0000
@@ -21,6 +21,8 @@ class views_handler_field_term_node_tid 
     $options['link_to_taxonomy'] = array('default' => TRUE);
     $options['limit'] = array('default' => FALSE);
     $options['vids'] = array('default' => array());
+    $options['limit_depth'] = array('default' => FALSE);
+    $options['limit_depth_value'] = array('default' =>  array());
 
     return $options;
   }
@@ -30,6 +32,7 @@ class views_handler_field_term_node_tid 
    */
   function options_form(&$form, &$form_state) {
     parent::options_form($form, $form_state);
+    
     $form['link_to_taxonomy'] = array(
       '#title' => t('Link this field to its term page'),
       '#type' => 'checkbox',
@@ -58,6 +61,23 @@ class views_handler_field_term_node_tid 
       '#process' => array('expand_checkboxes', 'views_process_dependency'),
       '#dependency' => array('edit-options-limit' => array(TRUE)),
     );
+
+    $form['limit_depth'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Limit terms by depth'),
+      '#default_value' => $this->options['limit_depth'],
+    );
+
+    $form['limit_depth_value'] = array(
+      '#prefix' => '<div><div id="edit-options-limit-depth-value">',
+      '#suffix' => '</div></div>',
+      '#type' => 'checkboxes',
+      '#title' => t('Display term with depth'),
+      '#options' => array_combine(range(1, 10), range(1, 10)),
+      '#default_value' => $this->options['limit_depth_value'],
+      '#process' => array('expand_checkboxes', 'views_process_dependency'),
+      '#dependency' => array('edit-options-limit-depth' => array(TRUE)),
+    );
   }
 
   /**
@@ -78,18 +98,58 @@ class views_handler_field_term_node_tid 
 
     if ($vids) {
       $voc = '';
+      $thjoin = '';
+      $thselect = '';
+
       if (!empty($this->options['limit']) && !empty($this->options['vids'])) {
         $voc = " AND td.vid IN (" . implode(', ', array_keys(array_filter($this->options['vids']))) . ")";
       }
 
-      $result = db_query("SELECT tn.vid AS node_vid, td.*, v.name as vocabulary FROM {term_data} td INNER JOIN {term_node} tn ON td.tid = tn.tid INNER JOIN {vocabulary} v ON v.vid = td.vid WHERE tn.vid IN (" . implode(', ', $vids) . ")$voc ORDER BY td.weight, td.name");
+      if ($this->options['limit_depth']) {
+        $thjoin = " INNER JOIN {term_hierarchy} th ON th.tid = tn.tid";
+        $thselect = " th.parent,";
+      }
+
+      $result = db_query("SELECT tn.vid AS node_vid, td.*,$thselect v.name AS vocabulary FROM {term_data} td INNER JOIN {term_node} tn ON td.tid = tn.tid INNER JOIN {vocabulary} v ON v.vid = td.vid$thjoin WHERE tn.vid IN (" . implode(', ', $vids) . ")$voc ORDER BY td.weight, td.name");
 
+      // Extract data
+      $terms_res = array();
       while ($term = db_fetch_object($result)) {
+        $terms_res[] = $term;
+      }
+
+      if ($this->options['limit_depth']) {
+        // HP 1: All terms tree is avaiable for node.
+        $all_terms = array();
+        // Restructure terms hierarchy
+        foreach ($terms_res as $term) {
+          $all_terms[$term->node_vid][$term->vid][$term->tid] = $term;
+        }
+
+        // Reset $terms_res
+        $terms_res = array();
+
+        // Add term deepth
+        foreach ($all_terms as $node_vid => $voc_terms) {
+          foreach ($voc_terms as $voc_vid => $terms) {
+            foreach ($terms as $tid => $term) {
+              $this->_term_get_parents($terms, $term);
+
+              // Extract only term with correct level
+              if ($this->options['limit_depth_value'][$term->depth + 1]) {
+                $terms_res[] = $term;
+              }
+            }
+          }
+        }
+      }
+
+      foreach ($terms_res as $term) {
         $this->items[$term->node_vid][$term->tid]['name'] = check_plain($term->name);
         $this->items[$term->node_vid][$term->tid]['tid'] = $term->tid;
         $this->items[$term->node_vid][$term->tid]['vid'] = $term->vid;
         $this->items[$term->node_vid][$term->tid]['vocabulary'] = check_plain($term->vocabulary);
-        
+
         if (!empty($this->options['link_to_taxonomy'])) {
           $this->items[$term->node_vid][$term->tid]['make_link'] = TRUE;
           $this->items[$term->node_vid][$term->tid]['path'] = taxonomy_term_path($term);
@@ -115,5 +175,44 @@ class views_handler_field_term_node_tid 
     $tokens['[' . $this->options['id'] . '-vid' . ']'] = $item['vid'];
     $tokens['[' . $this->options['id'] . '-vocabulary' . ']'] = $item['vocabulary'];
   }
-}
 
+  /**
+   * Generate term depth for selected terms.
+   *
+   * This function load term not already loaded if required to complete
+   * taxonomy tree from down to up to limitate memory usage but increase
+   * number of query executed if taxonomy tree associated to node is sparse.
+   *
+   * @param array &$all_terms
+   *   Array with all extract terms for specific node version and vocabulary
+   *
+   * @param stdClass &$term
+   *   Term to determ deepth
+   *
+   */
+  function _term_get_parents(&$all_terms, &$term) {
+    // Root term
+    if ($term->parent == 0) {
+      $term->depth = 0;
+    }
+
+    // Parent is not already loaded
+    elseif (is_null($all_terms[$term->parent])) {
+      $all_terms[$term->parent] = db_fetch_object(db_query('SELECT td.*, th.parent FROM {term_data} td LEFT JOIN {term_hierarchy} th ON td.tid = th.tid WHERE td.tid = %d', $term->parent));
+      $this->_term_get_parents($all_terms, $all_terms[$term->parent]) + 1;
+    }
+
+    // If parent have already a deepth
+    elseif (!is_null($all_terms[$term->parent]->depth)) {
+      $term->depth = $all_terms[$term->parent]->depth + 1;
+    }
+
+    // Recursive to find parent deepth
+    else {
+      $this->_term_get_parents($all_terms, $all_terms[$term->parent]) + 1;
+    }
+
+    // Also associate depth to $all_term array
+    $all_terms[$term->tid]->depth = $term->depth;
+  }
+}
