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 26 Nov 2010 13:04:14 -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' => '
', + '#suffix' => '
', + '#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,22 +98,65 @@ 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($all_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); } + if ($this->options['limit_depth']) { + $this->items[$term->node_vid][$term->tid]['depth'] = $term->depth; + } } } } @@ -107,6 +170,10 @@ class views_handler_field_term_node_tid $tokens['[' . $this->options['id'] . '-name' . ']'] = t('The taxonomy term name for the term.'); $tokens['[' . $this->options['id'] . '-vid' . ']'] = t('The vocabulary ID for the vocabulary the term belongs to.'); $tokens['[' . $this->options['id'] . '-vocabulary' . ']'] = t('The name for the vocabulary the term belongs to.'); + + if ($this->options['limit_depth']) { + $tokens['[' . $this->options['id'] . '-depth' . ']'] = t('The depth of term.'); + } } function add_self_tokens(&$tokens, $item) { @@ -114,6 +181,45 @@ class views_handler_field_term_node_tid $tokens['[' . $this->options['id'] . '-name' . ']'] = $item['name']; $tokens['[' . $this->options['id'] . '-vid' . ']'] = $item['vid']; $tokens['[' . $this->options['id'] . '-vocabulary' . ']'] = $item['vocabulary']; + + if ($this->options['limit_depth']) { + $tokens['[' . $this->options['id'] . '-depth' . ']'] = $item['depth']; + } } -} + /** + * 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]); + $term->depth = $all_terms[$term->parent]->depth + 1; + } + + // If parent have already a deepth + elseif (!is_null($all_terms[$term->parent]->depth)) { + $term->depth = $all_terms[$term->parent]->depth + 1; + } + + // Also associate depth to $all_term array + $all_terms[$term->tid]->depth = $term->depth; + } +}