aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--taxonomy_node_tree.info6
-rw-r--r--taxonomy_node_tree.module206
3 files changed, 214 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d54e6df
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+# Ignore any vim temp file
+*.swp
diff --git a/taxonomy_node_tree.info b/taxonomy_node_tree.info
new file mode 100644
index 0000000..8cee7d3
--- /dev/null
+++ b/taxonomy_node_tree.info
@@ -0,0 +1,6 @@
+; $Id$
+name = Taxonomy Node Tree
+description = Shows lists of nodes withing it's taxonomic tree.
+core = 6.x
+version = "6.x-0.1"
+dependencies[] = menu
diff --git a/taxonomy_node_tree.module b/taxonomy_node_tree.module
new file mode 100644
index 0000000..3f6bc32
--- /dev/null
+++ b/taxonomy_node_tree.module
@@ -0,0 +1,206 @@
+<?php
+// $Id$
+
+/**
+ * Drawer logic.
+ */
+function theme_taxonomy_node_tree($menu_name, $mlid) {
+ // Get all terms from a given vocabulary
+ $vocabulary = variable_get('taxonomy_node_tree', '1');
+ $terms = taxonomy_node_tree_taxonomy_get_tree($vocabulary);
+
+ foreach ($terms as $term) {
+ // Just show parent terms
+ if (taxonomy_get_parents($term->tid) == array()) {
+ $menu[] = $term;
+ }
+ }
+
+ // Build the drawer
+ $output = taxonomy_node_tree_build($menu);
+ return $output;
+}
+
+/**
+ * Drawer rendering.
+ *
+ * @ingroup themeable
+ */
+function taxonomy_node_tree_build($menu) {
+
+ $output = '<ul id="drw_tabs">';
+ $output .= implode((array) module_invoke_all('taxonomy_node_tree_build'));
+
+ foreach ($menu as $item) {
+ $link['title'] = $item->name;
+ $link['href'] = 'taxonomy_node_tree/' . $item->tid;
+ $output .= theme('taxonomy_node_tree_link', $link);
+ }
+
+ $output .= '</ul>';
+ $output .= '<div id="drw">';
+ $output .= '</div>';
+ return $output;
+
+}
+
+/**
+ * Menu callback.
+ */
+function taxonomy_node_tree_page($tid = null) {
+ // First render all nodes whose parent is $term
+
+ $output = '';
+ $nodes = taxonomy_select_nodes(array($tid));
+
+ while ($node = db_fetch_object($nodes)) {
+ $link['title'] = $node->title;
+ $link['href'] = 'node/' . $node->nid;
+ $output .= theme('taxonomy_node_tree_link', $link);
+ }
+
+ // Then render all nodes whose terms are children of $term
+
+ $vocabulary = variable_get('taxonomy_node_tree', '1');
+ $terms = taxonomy_node_tree_taxonomy_get_tree($vocabulary, $tid);
+
+ foreach ($terms as $term) {
+ $filter[] = $term->tid;
+ }
+
+ $query = 'SELECT node.nid, node.title, term_node.tid FROM {node} LEFT JOIN
+ {term_node} ON term_node.nid = node.nid WHERE term_node.tid IN (%s)
+ AND node.status = "1"';
+
+ $result = db_query(db_rewrite_sql($query), implode(',', $filter));
+
+ while ($node = db_fetch_object($result)) {
+ foreach ($terms as $term) {
+ // add nodes into the term
+ if ($node->tid == $term->tid) {
+ $term->nodes[] = $node;
+ }
+ // update an index of terms
+ $tree[$term->tid] = $term;
+ }
+ }
+
+ // add children relationship just for terms present in the tree
+ foreach ($tree as $term) {
+ if ($term->parents[0] != 0 && isset($tree[$term->parents[0]])) {
+ $tree[$term->parents[0]]->children[] = $term->tid;
+ }
+ }
+
+ // build menu with hierarchy
+ foreach ($tree as $term) {
+ taxonomy_node_tree_build_tree($tree, $term);
+ }
+
+ // format output
+ $output .= '<ul id="drw_item" class="hidden">';
+ foreach ($tree as $term) {
+ $output .= taxonomy_node_tree_menu_build($term);
+ }
+ $output .= '</ul></li>';
+
+ // Display output
+ echo($output);
+
+ // We need to exit here to avoid themeable output
+ exit();
+}
+
+function taxonomy_node_tree_build_tree(&$tree, $term) {
+ if ($term->parents[0] != 0 && isset($tree[$term->parents[0]])) {
+ // is child
+ if (isset($term->children)) {
+ // is also parent, so go down one level
+ foreach($term->children as $child) {
+ taxonomy_node_tree_build_tree($tree, $tree[$child]);
+ }
+ }
+ $tree[$term->parents[0]]->below[] = drupal_clone($term);
+ unset($tree[$term->tid]);
+ }
+}
+
+/**
+ * Recursively build the menu.
+ *
+ * @ingroup themeable
+ */
+function taxonomy_node_tree_menu_build($term) {
+
+ global $taxonomy_node_tree_id;
+
+ if ($taxonomy_node_tree_id == null) {
+ $taxonomy_node_tree_id = 0;
+ }
+
+ $taxonomy_node_tree_id++;
+
+ if (isset($term->tid)) {
+ $output .= '<li>';
+ $output .= $term->name;
+ if (isset($term->below)) {
+ $output .= '<ul id="taxonomy_node_tree[ul][' . $taxonomy_node_tree_id . ']" class="hidden">';
+ foreach($term->below as $child) {
+ $output .= taxonomy_node_tree_menu_build($child);
+ }
+ $output .= '</ul>';
+ } else if (isset($term->nodes)) {
+ $output .= '<ul id="taxonomy_node_tree[ul][' . $taxonomy_node_tree_id . ']" class="hidden">';
+ foreach ($term->nodes as $node) {
+ $output .= '<li>';
+ $output .= '<a href="' . $GLOBALS['base_url'] . '/sitio/' . $node->nid . '">' . $node->title . '</a>';
+ }
+ $output .= '</ul>';
+ $output .= '</li>';
+ }
+ $output .= '</li>';
+ }
+
+ return $output;
+
+}
+
+/**
+ * Version of taxonomy_get_tree() without caching.
+ */
+function taxonomy_node_tree_taxonomy_get_tree($vid, $parent = 0, $depth = -1, $max_depth = NULL, $cache = FALSE) {
+ static $children, $parents, $terms;
+
+ $depth++;
+
+ // We can cache trees, so it's not CPU-intensive to call get_tree() on a term
+ // and its children, too.
+ if (!$cache && !isset($children[$vid])) {
+ $children[$vid] = array();
+
+ $result = db_query(db_rewrite_sql('SELECT t.tid, t.*, parent FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE t.vid = %d ORDER BY weight, name', 't', 'tid'), $vid);
+ while ($term = db_fetch_object($result)) {
+ $children[$vid][$term->parent][] = $term->tid;
+ $parents[$vid][$term->tid][] = $term->parent;
+ $terms[$vid][$term->tid] = $term;
+ }
+ }
+
+ $max_depth = (is_null($max_depth)) ? count($children[$vid]) : $max_depth;
+ $tree = array();
+ if ($max_depth > $depth && !empty($children[$vid][$parent])) {
+ foreach ($children[$vid][$parent] as $child) {
+ $term = drupal_clone($terms[$vid][$child]);
+ $term->depth = $depth;
+ // The "parent" attribute is not useful, as it would show one parent only.
+ unset($term->parent);
+ $term->parents = $parents[$vid][$child];
+ $tree[] = $term;
+ if (!empty($children[$vid][$child])) {
+ $tree = array_merge($tree, taxonomy_get_tree($vid, $child, $depth, $max_depth));
+ }
+ }
+ }
+
+ return $tree;
+}