--- C:/Users/äæåéàíà/Desktop/taxonomy_list1.module Âñ ÿíâ 25 00:15:10 2009 +++ C:/Users/äæåéàíà/Desktop/taxonomy_list2.module ×ò èþí 25 14:42:01 2009 @@ -1,1030 +1,1032 @@ -'. t('The Taxonomy List module adds pages that list all terms in a vocabulary (category). In addition, when the Taxonomy Image module is installed, these lists can include an image for each term.') .'

'; - } -} - -/** - * Implementation of hook_perm(). - */ -function taxonomy_list_perm() { - return array('access taxonomy_list', 'administer taxonomy_list'); -} - -/** - * Implementation of hook_menu(). - */ -function taxonomy_list_menu() { - $items = array(); - - $items['admin/settings/taxonomy_list'] = array( - 'title' => 'Taxonomy List', - 'description' => 'Customize how Taxonomy List displays terms on vocabulary pages.', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('taxonomy_list_admin_settings'), - 'access arguments' => array('administer site configuration'), - 'type' => MENU_NORMAL_ITEM, - ); - - $items['taxonomy/vocabulary/%'] = array( - 'title' => 'Terms for !vids', - 'title arguments' => array('!vids' => arg(2)), - 'page callback' => 'taxonomy_list_show', - 'page arguments' => array(2), - 'access arguments' => array('access taxonomy_list'), - 'type' => MENU_CALLBACK, - ); - - return $items; -} - -/** - * Implementation of hook_init(). - */ -function taxonomy_list_init() { - drupal_add_css(drupal_get_path('module', 'taxonomy_list') .'/taxonomy_list.css'); -} - -/** - * Implementation of hook_theme(). - */ -function taxonomy_list_theme() { - return array( - 'taxonomy_list_admin_links' => array( - 'arguments' => array('vids'), - ), - 'taxonomy_list_vocabulary' => array( - 'arguments' => array('vocabulary'), - ), - 'taxonomy_list_term' => array( - 'arguments' => array('term'), - ), - 'taxonomy_list_term_block' => array( - 'arguments' => array('term'), - ), - 'taxonomy_list_block' => array( - 'arguments' => array('terms'), - ), - 'taxonomy_list_' => array( - 'arguments' => array('terms', 'cells_per_row' => 1, 'list_mode' => 0), - ), - 'taxonomy_list_table' => array( - 'arguments' => array('terms', 'cells_per_row' => 1, 'list_mode' => 0), - ), - 'taxonomy_list_list' => array( - 'arguments' => array('terms', 'cells_per_row' => 1, 'list_mode' => 0), - ), - 'taxonomy_list_nancy' => array( - 'arguments' => array('terms', 'cells_per_row' => 1, 'list_mode' => 0), - 'template' => 'taxonomy_list_nancy', - ), - 'taxonomy_list_directory' => array( - 'arguments' => array('terms', 'cells_per_row' => 1, 'list_mode' => 0), - ), - 'taxonomy_list_directory_node' => array( - 'arguments' => array('node', 'term'), - ), - ); -} - -/** - * Returns tree of terms. - * Enhancement for taxonomy_get_tree. - * - * @param $parent - * the parent term to restrict the tree to. (optional) - * @param $overview - * whether we are doing the overview page (bool) - * - * @return an array of term objects. - */ - -function taxonomy_list_get_tree($vocid, $parent = 0, $max_depth = 2147483647) { - $taxo_img = module_exists('taxonomy_image'); - $show_image = variable_get('taxonomy_list_show_image', 1); - $count_type = variable_get('taxonomy_list_count', 'none'); - $no_show = variable_get('taxonomy_list_noshow', FALSE); - $edit_link = $op == 'block' ? FALSE : variable_get('taxonomy_list_edit_link', FALSE); - $search_link = $op == 'block' ? FALSE : variable_get('taxonomy_list_search_link', FALSE); - $rss_link = variable_get('taxonomy_list_rss_link', FALSE); - $show_parents = variable_get('taxonomy_list_show_parents', FALSE); - $show_children = variable_get('taxonomy_list_show_children', FALSE) ? '/all' : NULL; - $related = variable_get('taxonomy_list_related', FALSE); - $synonyms = variable_get('taxonomy_list_synonyms', FALSE); - $ntf_avail = module_exists('node_type_filter'); - $destination = drupal_get_destination(); - $node_types = node_get_types('names'); - - $tree = taxonomy_get_tree($vocid, $parent); - $vocabulary = taxonomy_vocabulary_load($vocid); - - // Is this a top level request? - if ($parent) { - // The existing elements have depths one too low. - foreach ($tree as $term) ++$term->depth; - // Not top level, so we need to get the requested term - // and stick it on the front of the tree. - $parent_term = taxonomy_get_term($parent); - array_unshift($tree, $parent_term); - $tree[0]->depth = 0; - } - - $new_tree = array(); - foreach ($tree as $term) { - $tid = $term->tid; - // If we are too deep already, skip the whole term. - if ($term->depth > $max_depth) { - continue; - } - // If we are suppressing empty terms and there are no links in this group, skip it. - $count = taxonomy_term_count_nodes($tid); - if ($no_show && $count == 0) { - continue; - } - - $new_tree[$tid] = $term; - $term_path = drupal_get_path_alias(taxonomy_term_path($term)) . $show_children; - - $new_tree[$tid]->children = array(); - if ($term->parents[0] != 0) { - foreach ($term->parents as $parent) { - if (isset($new_tree[$parent])) { - $new_tree[$parent]->children[] = $tid; - } - } - } - - if ($show_image) { - $new_tree[$tid]->image = $taxo_img ? '
'. taxonomy_image_display($term->tid, NULL, NULL, array('wrapper' => FALSE)) .'
' : NULL; - } - else { - $new_tree[$tid]->image = NULL; - } - - $new_tree[$tid]->title = '
'. l($term->name, $term_path, array('attributes' => array('id' => $term->tid))) .'
'; - $new_tree[$tid]->desc = $term->description ? '
'. check_markup($term->description, $format) .'
' : NULL; - - $links = array(); - // Do we want edit link? - if (user_access('administer taxonomy') && $edit_link) { - $links['taxonomy-list-edit-link'] = array( - 'title' => t('edit term'), - 'href' => 'admin/content/taxonomy/edit/term/'. $term->tid, - 'attributes' => array('title' => t('make changes to this term')), - 'query' => $destination, - ); - } - - // Do we want search link? - if (user_access('search content') && $search_link) { - $links['taxonomy-list-search-term'] = array( - 'title' => t('search for term'), - 'href' => 'search/node/"'. $term->name .'"', - 'attributes' => array('title' => t('search for content using this term')), - ); - } - - // Do we want RSS link? - if ($rss_link) { - $links['taxonomy-list-rss'] = array( - 'title' => 'rss feed for '. check_plain($term->name) .'', - 'href' => 'taxonomy/term/'. $term->tid .'/'. $controls['max_depth'] .'/feed', - 'attributes' => array('title' => t('create feed for this term')), - 'html' => TRUE, - ); - } - - if ($links) { - $new_tree[$tid]->links = theme('links', $links, array('class' => 'links inline')); - } - - switch ($count_type) { - case 'none': - $counter = 0; - $new_tree[$tid]->counter = NULL; - break; - - case 'all': - $counter = taxonomy_term_count_nodes($term->tid); - if ($counter == 0 && $no_show) { - $new_tree[$tid]->counter = NULL; - } - else { - $new_tree[$tid]->counter = '
('. $counter .')
'; - } - break; - - case 'not_zero': - case 'by_type': - $count_list = array(); - $counter = 0; - foreach ($vocabulary->nodes as $type) { - $this_count = taxonomy_term_count_nodes($term->tid, $type); - if ($this_count > 0 || $count_type == 'by_type') { - // Is Node Type Filter available? - if ($ntf_avail && $this_count > 0) { - $count_list[] = l($node_types[$type] .': '. $this_count, $term_path, array('query' => 'type='. $type)); - } - else { - $count_list[] = $node_types[$type] .': '. $this_count; - } - } - $counter += $this_count; - } - if ($counter == 0 && $no_show) { - $new_tree[$tid]->counter = NULL; - } - if ($count_list) { - $new_tree[$tid]->counter = '
('. implode(', ', $count_list) .')
'; - } - break; - } - $new_tree[$tid]->node_count = $counter; - - $new_tree[$tid]->term_related = $new_tree[$tid]->term_synonyms = NULL; - if ($related) { - if ($relations = taxonomy_get_related($term->tid, 'name')) { - $names = array(); - foreach ($relations as $related) { - $names[] = l($related->name, drupal_get_path_alias('taxonomy/vocabulary/'. $term->vid), array('fragment' => $related->tid)); - } - $new_tree[$tid]->term_related = ''; - } - } - - if ($synonyms) { - if ($syn_list = taxonomy_get_synonyms($term->tid)) { - $new_tree[$tid]->term_synonyms = '
' - .''. t('Synonyms') .': '. implode(', ', $syn_list) - .'
'; - } - } - if ($show_parents && $new_tree[$tid]->parents[0] != 0) { - $parent_list = array(); - foreach ($new_tree[$tid]->parents as $parent_tid) { - $parent = $new_tree[$parent_tid]; - $parent_list[] = l($parent->name, drupal_get_path_alias('taxonomy/vocabulary/'. $vocabulary->vid), array('fragment' => $parent->tid)); - } - $new_tree[$tid]->parent_list = '
[« '. implode(' « ', $parent_list) .']
'; - } - else { - $new_tree[$tid]->parent_list = NULL; - } - } - return $new_tree; -} - -/** - * Show the category list - */ -function taxonomy_list_show($str_vids, $max_depth = 'all', $op = NULL, $columns = NULL, $type = NULL) { - $params = array( - 'max_depth' => 'all', - 'op' => NULL, - 'type' => NULL, - 'columns' => variable_get('taxonomy_list_cell_per_row', 2), - 'format' => variable_get('taxonomy_list_format', 'table'), - 'list_mode' => variable_get('taxonomy_list_list_mode', 0), - ); - $params = array_merge($params, $_GET); - unset($params['q']); - if (isset($params['cols'])) { - $params['columns'] = $params['cols']; - unset($params['cols']); - } - if (isset($params['depth'])) { - $params['max_depth'] = $params['depth']; - unset($params['depth']); - } - if (isset($params['mode'])) { - $params['list_mode'] = $params['mode']; - unset($params['mode']); - } - - array_walk($params, 'check_plain'); - -// $params['max_depth'] = $params['max_depth'] == 'all' ? 9999999 : $params['max_depth']; - if ($params['max_depth'] == 'all') { - $params['max_depth'] = 9999999; - } - -// drupal_set_message(print_r($params, true)); - - if ($str_vids == 'all') { - $vocs = taxonomy_get_vocabularies(); - $vids = array(); - foreach ($vocs as $vid => $vocab) { - $vids[] = $vid; - } - } - else { - if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str_vids)) { - // The '+' character in a query string may be parsed as ' '. - $vids = preg_split('/[+ ]/', $str_vids); - } - else if (preg_match('/^[0-9]+$/', $str_vids) ) { - $vids = array($str_vids); - } - } - - if (count($vids) <= 0) { - drupal_not_found(); - return; - } - - // Do we want to list the nodes? - if ($params['op'] == 'list') { - return taxonomy_list_nodes_render($vids, $params['max_depth'], $params['type']); - } - - $vocab_titles = array(); - $total_terms = 0; - - $output = '
'; - - foreach ($vids as $vid) { - $vocab = taxonomy_vocabulary_load($vid); - $vocab_titles[] = $vocab->name; - - $terms = taxonomy_list_get_tree($vid, 0, $params['max_depth']); - - $c = count($terms); - if ($c <= 0) { - // This vocab has no term, skip. - continue; - } - $total_terms += $c; - - $output .= theme('taxonomy_list_vocabulary', $vocab, variable_get('taxonomy_list_types', FALSE), (count($vids) > 1)); - $output .= theme(array('taxonomy_list_'. $params['format'], 'taxonomy_list_table'), $terms, $params['columns'], $params['list_mode']); - } - - $output .= '
'; // class="taxonomy-list" - - if ($total_terms == 0) { - drupal_not_found(); - return; - } - - drupal_set_title(implode(variable_get('taxonomy_list_title_separator', ' & '), $vocab_titles)); - $output = theme('taxonomy_list_admin_links', $vids) . $output; - - return $output; -} - -/** - * Theme a table of the term tree. - * - * @param $terms - * the enhanced term tree. - * @param $cells_per_row - * the number of cells per row to display. - * @param $list_mode - * indicates how to show the hierarchy. - * @return - * the themed list to be displayed. - */ -function theme_taxonomy_list_table($terms, $cells_per_row = 1, $list_mode = 0) { - $rows = $cells = array(); - $curr_col = -1; - $curr_depth = 0; - foreach ($terms as $tid => $term) { - if (!isset($vid)) { - // If recursive, watch out for this. - $vid = $term->vid; - } - $class = 'taxonomy-list-depth-'. $term->depth; - - // List_mode = 0 is hierarchical; = 1 is flat. - if ($curr_depth != $term->depth && $list_mode == 0) { - $rows[] = $cells; - $cells = array(); - $curr_col = -1; - $curr_depth = $term->depth; - } - - if ($term->children) { - $class .= ' taxonomy-list-parent'; - } - - $cells[] = '
'. theme_taxonomy_list_term($term) .'
'; - $curr_col = ($curr_col + 1) % $cells_per_row; - if ($curr_col == $cells_per_row - 1) { - $rows[] = $cells; - $cells = array(); - } - } - - if ($cells) { - $rows[] = $cells; - } - - return theme('table', array(), $rows, array('id' => 'taxonomy-list-table-'. $vid)); -} - -/** - * Theme a list of the term tree. - * - * @param $terms - * the enhanced term tree. - * @param $cells_per_row - * the number of cells per row to display. -- not used for list. - * @param $list_mode - * indicates how to show the hierarchy. - * @return - * the themed list to be displayed. - */ -function theme_taxonomy_list_list($terms, $cells_per_row = 1, $list_mode = 0) { - $items = array(); - $odd_even = array('even', 'odd'); - $i = 0; - foreach ($terms as $tid => $term) { - ++$i; - switch ($list_mode) { - case 0: // Hierarchical. - if ($term->depth) { - continue; - } - $item = array('data' => theme('taxonomy_list_term', $term), 'class' => $odd_even[$i & 1]); - if ($term->children) { - $item['children'] = _taxonomy_list_list_children($term->children, $terms); - } - $items[] = $item; - break; - case 1: // Flat. - $items[] = array('data' => theme('taxonomy_list_term', $term), 'class' => $odd_even[$i & 1]); - break; - } - } - return theme('item_list', $items, NULL, 'ul', array('class' => 'taxonomy-list-list')); -} - -/** - * Theme a directory list. - * - * @param $terms - * the enhanced term tree. - * @param $cells_per_row - * the number of cells per row to display. -- not used for directory. - * @param $list_mode - * indicates how to show the hierarchy. - * @return - * the themed list to be displayed. - */ -function theme_taxonomy_list_directory($terms, $cells_per_row = 1, $list_mode = 0) { - $hide_empty = variable_get('taxonomy_list_noshow', FALSE); - $output = '
'; - foreach ($terms as $tid => $term) { - if (!$term->depth) { // Only do top level terms here. -// $output .= print_r($term, true); - $data = $term->image . $term->title . $term->desc; - $nodes = taxonomy_list_select_nodes(array($tid)); - while ($nid = db_result($nodes)) { - $node = node_load($nid); - node_view($node, TRUE, FALSE, FALSE); - $data .= theme('taxonomy_list_directory_node', $node, $term); - } - // If there were no nodes, skip the whole thing. - if ($term->node_count == 0 && $hide_empty) { - continue; - } - if ($term->children) { - $data .= _taxonomy_list_directory_children($term->children, $terms); - } - $fieldset = array( - '#title' => check_plain($term->name), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - '#value' => $data, - ); - $output .= theme('fieldset', $fieldset); - } - } - return $output .'
'; -} - -/** - * Theme child terms for the directory list. - * - * @param $tids - * an array of term ids.. - * @param $tree - * the enhanced term tree. - * @return - * the themed list to be displayed. - */ -function _taxonomy_list_directory_children($tids, $tree) { - static $show_desc; - if (!isset($show_desc)) { - $show_desc = variable_get('taxonomy_list_show_description', TRUE); - } - $output = NULL; - foreach ($tids as $tid) { - $term = $tree[$tid]; - $data = $term->image . $term->title . ($show_desc ? $term->desc : NULL); - $nodes = taxonomy_list_select_nodes(array($tid)); - while ($nid = db_result($nodes)) { - $node = node_load($nid); - $data .= theme('taxonomy_list_directory_node', $node, $term); - } - if ($term->children) { - $data .= _taxonomy_list_directory_children($term->children, $tree); - } - $fieldset = array( - '#title' => check_plain($term->name), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - '#value' => $data, - ); - $output .= theme('fieldset', $fieldset); - } - - return $output; -} - -/** - * Theme a node selected for the directory list. - * - * @param $node - * the full node object. - * @param $term - * the enhanced term object. - * @return - * the themed node to be displayed. - */ -function theme_taxonomy_list_directory_node($node, $term) { - $output = '
'; - $output .= '
'; - $output .= '
'; - if ($node->iid) { - $output .= theme_image_attach_teaser($node); - } - else { - $output .= ' '; - } - $output .= ''; - $output .= '
'. l($node->title, drupal_get_path_alias('node/'. $node->nid)) .'
'; - $output .= '
'; - $output .= '
'; - - return $output .'
'; -} - -function _taxonomy_list_list_children($kids, $tree) { - $items = array(); - $odd_even = array('even', 'odd'); - $i = 0; - foreach ($kids as $tid) { - $term = $tree[$tid]; - ++$i; - $item = array('data' => theme('taxonomy_list_term', $term), 'class' => $odd_even[$i & 1]); - if ($term->children) { - $item['children'] = _taxonomy_list_list_children($term->children, $tree); - } - $items[] = $item; - } - return $items; -} - -/** - * Finds all nodes that match selected taxonomy conditions. - * Copied from taxonomy.module. - * - * @param $tids - * An array of term IDs to match. - * @param $operator - * How to interpret multiple IDs in the array. Can be "or" or "and". - * @param $depth - * How many levels deep to traverse the taxonomy tree. Can be a nonnegative - * integer or "all". - * @param $pager - * Whether the nodes are to be used with a pager (the case on most Drupal - * pages) or not (in an XML feed, for example). - * @param $type - * The node type to retrieve. - * @return - * A resource identifier pointing to the query results. - */ -function taxonomy_list_select_nodes($tids = array(), $operator = 'or', $depth = 0, $pager = TRUE, $type = NULL) { - if (count($tids) > 0) { - // For each term ID, generate an array of descendant term IDs to the right depth. - $descendant_tids = array(); - if ($depth === 'all') { - $depth = NULL; - } - foreach ($tids as $index => $tid) { - $term = taxonomy_get_term($tid); - $tree = taxonomy_get_tree($term->vid, $tid, -1, $depth); - $descendant_tids[] = array_merge(array($tid), array_map('_taxonomy_get_tid_from_term', $tree)); - } - - if ($type) { - if (is_array($type)) { - $get_type = " AND n.type IN ('". implode("', '", $type) ."')"; - } - else { - $get_type = " AND n.type='". $type ."'"; - } - } - else { - $get_type = NULL; - } - - if ($operator == 'or') { - $args = call_user_func_array('array_merge', $descendant_tids); - $placeholders = implode(',', array_fill(0, count($args), '%d')); - $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid IN ('. $placeholders .') AND n.status = 1'. $get_type .' ORDER BY n.sticky DESC, n.created DESC'; - $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid IN ('. $placeholders .') AND n.status = 1'. $get_type; - } - else { - $joins = ''; - $wheres = ''; - $args = array(); - foreach ($descendant_tids as $index => $tids) { - $joins .= ' INNER JOIN {term_node} tn'. $index .' ON n.nid = tn'. $index .'.nid'; - $placeholders = implode(',', array_fill(0, count($tids), '%d')); - $wheres .= ' AND tn'. $index .'.tid IN ('. $placeholders .')'; - $args = array_merge($args, $tids); - } - $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n '. $joins .' WHERE n.status = 1 '. $get_type . $wheres .' ORDER BY n.sticky DESC, n.created DESC'; - $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n '. $joins .' WHERE n.status = 1 '. $get_type . $wheres; - } - $sql = db_rewrite_sql($sql); - $sql_count = db_rewrite_sql($sql_count); - if ($pager) { - $result = pager_query($sql, variable_get('default_nodes_main', 10), 0, $sql_count, $args); - } - else { - $result = db_query_range($sql, $args, 0, variable_get('feed_default_items', 10)); - } - } - - return $result; -} - -/** - * Select and render the nodes in the chosen vocabularies. - */ -function taxonomy_list_nodes_render($vids, $max_depth, $type = NULL) { - $output = '
'; - $terms = array(); - // Get vocabulary names and list of tids. - foreach ($vids as $vid) { - $vocab = taxonomy_vocabulary_load($vid); - $vocab_titles[] = $vocab->name; - // Taxonomy_select_nodes will do the depth part for us, so we just get the top terms. - $terms = array_merge($terms, array_map('_taxonomy_get_tid_from_term', taxonomy_get_tree($vid, 0, -1, 1))); - } - drupal_set_title(implode(variable_get('taxonomy_list_title_separator', ' & '), $vocab_titles)); - sort($terms); - - // Render all nodes in a pager using taxonomy function. - $output .= taxonomy_render_nodes(taxonomy_list_select_nodes($terms, 'or', $max_depth, $type)); - - $output .= '
'; // class="taxonomy-list" - return $output; -} - -/** - * Theme the admin links. - */ -function theme_taxonomy_list_admin_links($vids) { - $destination = drupal_get_destination(); - $output = ''; - return $output; -} - -/** - * Theme the vocabulary. - */ -function theme_taxonomy_list_vocabulary($vocabulary, $types = FALSE, $title = TRUE) { - $output = '
'; - if ($title) { - $output .= '
'. check_plain($vocabulary->name) .'
'; - } - $output .= '
'. decode_entities(check_markup($vocabulary->description)) .'
'; - if ($types) { -// $list = array_intersect_key(node_get_types('names'), array_flip($vocabulary->nodes)); /* php 5.1 */ - $list = array_flip(array_intersect(array_flip(node_get_types('names')), $vocabulary->nodes)); - $output .= '

'. t('Used for content types') .': '. implode(', ', $list) .'

'; - } - $output .= '
'; - return $output; -} - -/** - * Theme the term. - */ -function theme_taxonomy_list_term($term) { - $output = '
' - . $term->image - . $term->title - . $term->parent_list - . $term->counter - . $term->links - . $term->desc - . $term->term_related - . $term->term_synonyms - .'
'; - return $output; -} - -/** - * Theme tree for a block. - * - * @param $terms - * the enhanced term tree. - * @return - * the themed list to be displayed. - */ -function theme_taxonomy_list_block($terms) { - $items = array(); - $odd_even = array('even', 'odd'); - $i = 0; - foreach ($terms as $tid => $term) { - ++$i; - $items[] = array('data' => theme('taxonomy_list_term_block', $term), 'class' => $odd_even[$i & 1]); - } - return theme('item_list', $items, NULL, 'ul', array('class' => 'taxonomy-list-block')); -} - -/** - * Theme the term for a block. - */ -function theme_taxonomy_list_term_block($term) { - $output = '
' - . $term->image - . $term->title - . $term->desc - .'
'; - return $output; -} - -/** - * Implementation of hook_block(). - */ -function taxonomy_list_block($op = 'list', $delta = 0, $edit = array()) { - global $user; - switch ($op) { - case 'list': - $vocabularies = taxonomy_get_vocabularies(); - foreach ($vocabularies as $vocabulary) { - $blocks[$vocabulary->vid]['info'] = t('Taxonomy List for !name', array('!name' => $vocabulary->name)); - } - return $blocks; - - case 'view': - // $delta is the vid. -// $block['content'] = taxonomy_list_show($delta, 'all', 'block', 1); - $tree = taxonomy_list_get_tree($delta); - $block['content'] = theme_taxonomy_list_block($tree); - return $block; - - case 'configure': - $form = array(); - return $form; - - case 'save': - return; - } // end switch($op) -} - -/** - * Menu callback; presents the admin settings form. - */ -function taxonomy_list_admin_settings() { - $form = array(); - - $form['taxonomy_list_info'] = array( - '#value' => t('

The taxonomy_list module enable the URL to browse into each vocabulary, using the format of :

') - . t('"taxonomy/vocabulary/<vid>"') - . t('

Together with the taxonomy_image.module, the list can be displayed with a image icon.

') - ); - - // General settings. - $form['general'] = array( - '#type' => 'fieldset', - '#title' => t('General settings'), - '#collapsible' => TRUE, - '#collapsed' => FALSE, - ); - - $sep_opts = array( - ' & ' => 'ampersand (&)', - ' | ' => 'vertical bar (pipe)', - ', ' => 'comma (,)', - ' • ' => 'bullet', - ' – ' => 'en-dash (–)', - ' — ' => 'em-dash (—)', - ' _ ' => 'underscore', - ); - $form['general']['taxonomy_list_title_separator'] = array( - '#type' => 'radios', - '#title' => t('Title separator'), - '#default_value' => variable_get('taxonomy_list_title_separator', ' & '), - '#options' => $sep_opts, - '#description' => t('This is the character that separates multiple vocabulary names in the page title.'), - '#prefix' => '
', - '#suffix' => '
', - ); - - $theme_opts = array( - 'table' => t('Table - Show terms in a table (legacy method).'), - 'list' => t('List - Show terms as a list.'), - 'directory' => t('Directory - Show terms as a directory of content.'), - ); - $form['general']['taxonomy_list_format'] = array( - '#type' => 'radios', - '#title' => t('List Format'), - '#default_value' => variable_get('taxonomy_list_format', 'table'), - '#options' => $theme_opts, - '#description' => t('The method, or layout, for displaying the terms.'), - ); - - $form['general']['taxonomy_list_list_mode'] = array( - '#type' => 'radios', - '#title' => t('List Mode'), - '#default_value' => variable_get('taxonomy_list_list_mode', 0), - '#options' => array( - '0' => t("Hierarchical - Subcategories set off to show the hierarchy."), - '1' => t('Flat - All terms are listed as the same level in the grid.'), - ), - '#description' => t('Whether Taxonomy List displays the hierarchy of the terms.'), - ); - - $form['general']['taxonomy_list_cell_per_row'] = array( - '#type' => 'textfield', - '#title' => t('Terms per row'), - '#size' => 5, - '#default_value' => variable_get('taxonomy_list_cell_per_row', 2), - '#description' => t('Number of terms to be displayed on the same row.'), - ); - - $form['general']['taxonomy_list_show_description'] = array( - '#type' => 'checkbox', - '#title' => t('Show parent descriptions?'), - '#default_value' => variable_get('taxonomy_list_show_description', TRUE), - '#description' => t('Should we display the description with parent terms in the directory view?'), - ); - - // Taxonomy Image. - if (module_exists('taxonomy_image')) { - $form['general']['taxonomy_list_show_image'] = array( - '#type' => 'checkbox', - '#title' => t('Show taxonomy image?'), - '#default_value' => variable_get('taxonomy_list_show_image', 1), - '#description' => t('The Taxonomy Image module is available; should we display the image with the term?'), - ); - } - - // Link settings. - $form['link'] = array( - '#type' => 'fieldset', - '#title' => t('Link options'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - - $form['link']['taxonomy_list_edit_link'] = array( - '#type' => 'checkbox', - '#title' => t('Add "edit term" link'), - '#default_value' => variable_get('taxonomy_list_edit_link', FALSE), - '#description' => t('Should I add an "edit term" link to the display for authorized users?'), - ); - - if (module_exists('search')) { - $form['link']['taxonomy_list_search_link'] = array( - '#type' => 'checkbox', - '#title' => t('Add "search for term" link'), - '#default_value' => variable_get('taxonomy_list_search_link', FALSE), - '#description' => t('Should I add an "search for term" link to the display for authorized users?'), - ); - } - - $form['link']['taxonomy_list_rss_link'] = array( - '#type' => 'checkbox', - '#title' => t('Add RSS link'), - '#default_value' => variable_get('taxonomy_list_rss_link', FALSE), - '#description' => t('Should I add an RSS link (icon) to the display?'), - ); - - $form['link']['taxonomy_list_show_children'] = array( - '#type' => 'checkbox', - '#title' => t('Show children when clicked'), - '#default_value' => variable_get('taxonomy_list_show_children', FALSE), - '#description' => t('If this is a parent term, show the content for children when the link is clicked upon?'), - ); - - // Optional settings. - $form['optional'] = array( - '#type' => 'fieldset', - '#title' => t('Optional information'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - - $form['optional']['taxonomy_list_types'] = array( - '#type' => 'checkbox', - '#title' => t('Show content types'), - '#default_value' => variable_get('taxonomy_list_types', FALSE), - '#description' => t('Do you want to display a list of the content types for the vocabulary?'), - ); - - $form['optional']['taxonomy_list_related'] = array( - '#type' => 'checkbox', - '#title' => t('Show related terms'), - '#default_value' => variable_get('taxonomy_list_related', FALSE), - '#description' => t('If there are related terms, should they be listed?'), - ); - - $form['optional']['taxonomy_list_synonyms'] = array( - '#type' => 'checkbox', - '#title' => t('Show synonyms for the term'), - '#default_value' => variable_get('taxonomy_list_synonyms', FALSE), - '#description' => t('If there are synonyms for the term, should they be listed?'), - ); - - $form['optional']['taxonomy_list_show_parents'] = array( - '#type' => 'checkbox', - '#title' => t('Show parents of the term'), - '#default_value' => variable_get('taxonomy_list_show_parents', FALSE), - '#description' => t('If this is a child term, show the parent structure?'), - ); - - // Counting settings. - $form['count'] = array( - '#type' => 'fieldset', - '#title' => t('Count content'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - - $count_opts = array( - 'none' => t('No count.'), - 'all' => t('Count all content types.'), - 'by_type' => t('Count by content type.'), - 'not_zero' => t("Count by type, don't show zero counts."), - ); - $form['count']['taxonomy_list_count'] = array( - '#type' => 'radios', - '#title' => t('Count content types'), - '#default_value' => variable_get('taxonomy_list_count', 0), - '#options' => $count_opts, - '#description' => t('How Taxonomy List counts the content types for terms.'), - '#prefix' => '
', - '#suffix' => '
', - ); - - if (module_exists('node_type_filter')) { - $form['count']['taxonomy_list_count']['#description'] .= ' '. t('The "Count by type" options will generate a link to show that type within that term.'); - } - - $form['count']['taxonomy_list_noshow'] = array( - '#type' => 'checkbox', - '#title' => t('Hide terms with no content?'), - '#default_value' => variable_get('taxonomy_list_noshow', FALSE), - '#description' => t('Do not show the term if there is no content using the term. Requires one of the counting options above.'), - ); - - return system_settings_form($form); -} +'. t('The Taxonomy List module adds pages that list all terms in a vocabulary (category). In addition, when the Taxonomy Image module is installed, these lists can include an image for each term.') .'

'; + } +} + +/** + * Implementation of hook_perm(). + */ +function taxonomy_list_perm() { + return array('access taxonomy_list', 'administer taxonomy_list'); +} + +/** + * Implementation of hook_menu(). + */ +function taxonomy_list_menu() { + $items = array(); + + $items['admin/settings/taxonomy_list'] = array( + 'title' => 'Taxonomy List', + 'description' => 'Customize how Taxonomy List displays terms on vocabulary pages.', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('taxonomy_list_admin_settings'), + 'access arguments' => array('administer site configuration'), + 'type' => MENU_NORMAL_ITEM, + ); + + $items['taxonomy/vocabulary/%'] = array( + 'title' => 'Terms for !vids', + 'title arguments' => array('!vids' => arg(2)), + 'page callback' => 'taxonomy_list_show', + 'page arguments' => array(2), + 'access arguments' => array('access taxonomy_list'), + 'type' => MENU_CALLBACK, + ); + + return $items; +} + +/** + * Implementation of hook_init(). + */ +function taxonomy_list_init() { + drupal_add_css(drupal_get_path('module', 'taxonomy_list') .'/taxonomy_list.css'); +} + +/** + * Implementation of hook_theme(). + */ +function taxonomy_list_theme() { + return array( + 'taxonomy_list_admin_links' => array( + 'arguments' => array('vids'), + ), + 'taxonomy_list_vocabulary' => array( + 'arguments' => array('vocabulary'), + ), + 'taxonomy_list_term' => array( + 'arguments' => array('term'), + ), + 'taxonomy_list_term_block' => array( + 'arguments' => array('term'), + ), + 'taxonomy_list_block' => array( + 'arguments' => array('terms'), + ), + 'taxonomy_list_' => array( + 'arguments' => array('terms', 'cells_per_row' => 1, 'list_mode' => 0), + ), + 'taxonomy_list_table' => array( + 'arguments' => array('terms', 'cells_per_row' => 1, 'list_mode' => 0), + ), + 'taxonomy_list_list' => array( + 'arguments' => array('terms', 'cells_per_row' => 1, 'list_mode' => 0), + ), + 'taxonomy_list_nancy' => array( + 'arguments' => array('terms', 'cells_per_row' => 1, 'list_mode' => 0), + 'template' => 'taxonomy_list_nancy', + ), + 'taxonomy_list_directory' => array( + 'arguments' => array('terms', 'cells_per_row' => 1, 'list_mode' => 0), + ), + 'taxonomy_list_directory_node' => array( + 'arguments' => array('node', 'term'), + ), + ); +} + +/** + * Returns tree of terms. + * Enhancement for taxonomy_get_tree. + * + * @param $parent + * the parent term to restrict the tree to. (optional) + * @param $overview + * whether we are doing the overview page (bool) + * + * @return an array of term objects. + */ + +function taxonomy_list_get_tree($vocid, $parent = 0, $max_depth = 2147483647) { + $taxo_img = module_exists('taxonomy_image'); + $show_image = variable_get('taxonomy_list_show_image', 1); + $count_type = variable_get('taxonomy_list_count', 'none'); + $no_show = variable_get('taxonomy_list_noshow', FALSE); + $edit_link = $op == 'block' ? FALSE : variable_get('taxonomy_list_edit_link', FALSE); + $search_link = $op == 'block' ? FALSE : variable_get('taxonomy_list_search_link', FALSE); + $rss_link = variable_get('taxonomy_list_rss_link', FALSE); + $show_parents = variable_get('taxonomy_list_show_parents', FALSE); + $show_children = variable_get('taxonomy_list_show_children', FALSE) ? '/all' : NULL; + $related = variable_get('taxonomy_list_related', FALSE); + $synonyms = variable_get('taxonomy_list_synonyms', FALSE); + $ntf_avail = module_exists('node_type_filter'); + $destination = drupal_get_destination(); + $node_types = node_get_types('names'); + + $tree = taxonomy_get_tree($vocid, $parent); + $vocabulary = taxonomy_vocabulary_load($vocid); + + // Is this a top level request? + if ($parent) { + // The existing elements have depths one too low. + foreach ($tree as $term) ++$term->depth; + // Not top level, so we need to get the requested term + // and stick it on the front of the tree. + $parent_term = taxonomy_get_term($parent); + array_unshift($tree, $parent_term); + $tree[0]->depth = 0; + } + + $new_tree = array(); + foreach ($tree as $term) { + $tid = $term->tid; + // If we are too deep already, skip the whole term. + if ($term->depth > $max_depth) { + continue; + } + // If we are suppressing empty terms and there are no links in this group, skip it. + $count = taxonomy_term_count_nodes($tid); + if ($no_show && $count == 0) { + continue; + } + + $new_tree[$tid] = $term; + $term_path = drupal_get_path_alias(taxonomy_term_path($term)) . $show_children; + + $new_tree[$tid]->children = array(); + if ($term->parents[0] != 0) { + foreach ($term->parents as $parent) { + if (isset($new_tree[$parent])) { + $new_tree[$parent]->children[] = $tid; + } + } + } + + if ($show_image) { + $new_tree[$tid]->image = $taxo_img ? '
'. taxonomy_image_display($term->tid, NULL, NULL, array('wrapper' => FALSE)) .'
' : NULL; + if (!taxonomy_image_display($term->tid, NULL, NULL, array('wrapper' => FALSE))) + {$new_tree[$tid]->title = '
'. l($term->name, $term_path, array('attributes' => array('id' => $term->tid))) .'
';} + + } + else { + $new_tree[$tid]->image = NULL; + } + + $new_tree[$tid]->desc = $term->description ? '
'. check_markup($term->description, $format) .'
' : NULL; + + $links = array(); + // Do we want edit link? + if (user_access('administer taxonomy') && $edit_link) { + $links['taxonomy-list-edit-link'] = array( + 'title' => t('edit term'), + 'href' => 'admin/content/taxonomy/edit/term/'. $term->tid, + 'attributes' => array('title' => t('make changes to this term')), + 'query' => $destination, + ); + } + + // Do we want search link? + if (user_access('search content') && $search_link) { + $links['taxonomy-list-search-term'] = array( + 'title' => t('search for term'), + 'href' => 'search/node/"'. $term->name .'"', + 'attributes' => array('title' => t('search for content using this term')), + ); + } + + // Do we want RSS link? + if ($rss_link) { + $links['taxonomy-list-rss'] = array( + 'title' => 'rss feed for '. check_plain($term->name) .'', + 'href' => 'taxonomy/term/'. $term->tid .'/'. $controls['max_depth'] .'/feed', + 'attributes' => array('title' => t('create feed for this term')), + 'html' => TRUE, + ); + } + + if ($links) { + $new_tree[$tid]->links = theme('links', $links, array('class' => 'links inline')); + } + + switch ($count_type) { + case 'none': + $counter = 0; + $new_tree[$tid]->counter = NULL; + break; + + case 'all': + $counter = taxonomy_term_count_nodes($term->tid); + if ($counter == 0 && $no_show) { + $new_tree[$tid]->counter = NULL; + } + else { + $new_tree[$tid]->counter = '
('. $counter .')
'; + } + break; + + case 'not_zero': + case 'by_type': + $count_list = array(); + $counter = 0; + foreach ($vocabulary->nodes as $type) { + $this_count = taxonomy_term_count_nodes($term->tid, $type); + if ($this_count > 0 || $count_type == 'by_type') { + // Is Node Type Filter available? + if ($ntf_avail && $this_count > 0) { + $count_list[] = l($node_types[$type] .': '. $this_count, $term_path, array('query' => 'type='. $type)); + } + else { + $count_list[] = $node_types[$type] .': '. $this_count; + } + } + $counter += $this_count; + } + if ($counter == 0 && $no_show) { + $new_tree[$tid]->counter = NULL; + } + if ($count_list) { + $new_tree[$tid]->counter = '
('. implode(', ', $count_list) .')
'; + } + break; + } + $new_tree[$tid]->node_count = $counter; + + $new_tree[$tid]->term_related = $new_tree[$tid]->term_synonyms = NULL; + if ($related) { + if ($relations = taxonomy_get_related($term->tid, 'name')) { + $names = array(); + foreach ($relations as $related) { + $names[] = l($related->name, drupal_get_path_alias('taxonomy/vocabulary/'. $term->vid), array('fragment' => $related->tid)); + } + $new_tree[$tid]->term_related = ''; + } + } + + if ($synonyms) { + if ($syn_list = taxonomy_get_synonyms($term->tid)) { + $new_tree[$tid]->term_synonyms = '
' + .''. t('Synonyms') .': '. implode(', ', $syn_list) + .'
'; + } + } + if ($show_parents && $new_tree[$tid]->parents[0] != 0) { + $parent_list = array(); + foreach ($new_tree[$tid]->parents as $parent_tid) { + $parent = $new_tree[$parent_tid]; + $parent_list[] = l($parent->name, drupal_get_path_alias('taxonomy/vocabulary/'. $vocabulary->vid), array('fragment' => $parent->tid)); + } + $new_tree[$tid]->parent_list = '
[« '. implode(' « ', $parent_list) .']
'; + } + else { + $new_tree[$tid]->parent_list = NULL; + } + } + return $new_tree; +} + +/** + * Show the category list + */ +function taxonomy_list_show($str_vids, $max_depth = 'all', $op = NULL, $columns = NULL, $type = NULL) { + $params = array( + 'max_depth' => 'all', + 'op' => NULL, + 'type' => NULL, + 'columns' => variable_get('taxonomy_list_cell_per_row', 2), + 'format' => variable_get('taxonomy_list_format', 'table'), + 'list_mode' => variable_get('taxonomy_list_list_mode', 0), + ); + $params = array_merge($params, $_GET); + unset($params['q']); + if (isset($params['cols'])) { + $params['columns'] = $params['cols']; + unset($params['cols']); + } + if (isset($params['depth'])) { + $params['max_depth'] = $params['depth']; + unset($params['depth']); + } + if (isset($params['mode'])) { + $params['list_mode'] = $params['mode']; + unset($params['mode']); + } + + array_walk($params, 'check_plain'); + +// $params['max_depth'] = $params['max_depth'] == 'all' ? 9999999 : $params['max_depth']; + if ($params['max_depth'] == 'all') { + $params['max_depth'] = 9999999; + } + +// drupal_set_message(print_r($params, true)); + + if ($str_vids == 'all') { + $vocs = taxonomy_get_vocabularies(); + $vids = array(); + foreach ($vocs as $vid => $vocab) { + $vids[] = $vid; + } + } + else { + if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str_vids)) { + // The '+' character in a query string may be parsed as ' '. + $vids = preg_split('/[+ ]/', $str_vids); + } + else if (preg_match('/^[0-9]+$/', $str_vids) ) { + $vids = array($str_vids); + } + } + + if (count($vids) <= 0) { + drupal_not_found(); + return; + } + + // Do we want to list the nodes? + if ($params['op'] == 'list') { + return taxonomy_list_nodes_render($vids, $params['max_depth'], $params['type']); + } + + $vocab_titles = array(); + $total_terms = 0; + + $output = '
'; + + foreach ($vids as $vid) { + $vocab = taxonomy_vocabulary_load($vid); + $vocab_titles[] = $vocab->name; + + $terms = taxonomy_list_get_tree($vid, 0, $params['max_depth']); + + $c = count($terms); + if ($c <= 0) { + // This vocab has no term, skip. + continue; + } + $total_terms += $c; + + $output .= theme('taxonomy_list_vocabulary', $vocab, variable_get('taxonomy_list_types', FALSE), (count($vids) > 1)); + $output .= theme(array('taxonomy_list_'. $params['format'], 'taxonomy_list_table'), $terms, $params['columns'], $params['list_mode']); + } + + $output .= '
'; // class="taxonomy-list" + + if ($total_terms == 0) { + drupal_not_found(); + return; + } + + drupal_set_title(implode(variable_get('taxonomy_list_title_separator', ' & '), $vocab_titles)); + $output = theme('taxonomy_list_admin_links', $vids) . $output; + + return $output; +} + +/** + * Theme a table of the term tree. + * + * @param $terms + * the enhanced term tree. + * @param $cells_per_row + * the number of cells per row to display. + * @param $list_mode + * indicates how to show the hierarchy. + * @return + * the themed list to be displayed. + */ +function theme_taxonomy_list_table($terms, $cells_per_row = 1, $list_mode = 0) { + $rows = $cells = array(); + $curr_col = -1; + $curr_depth = 0; + foreach ($terms as $tid => $term) { + if (!isset($vid)) { + // If recursive, watch out for this. + $vid = $term->vid; + } + $class = 'taxonomy-list-depth-'. $term->depth; + + // List_mode = 0 is hierarchical; = 1 is flat. + if ($curr_depth != $term->depth && $list_mode == 0) { + $rows[] = $cells; + $cells = array(); + $curr_col = -1; + $curr_depth = $term->depth; + } + + if ($term->children) { + $class .= ' taxonomy-list-parent'; + } + + $cells[] = '
'. theme_taxonomy_list_term($term) .'
'; + $curr_col = ($curr_col + 1) % $cells_per_row; + if ($curr_col == $cells_per_row - 1) { + $rows[] = $cells; + $cells = array(); + } + } + + if ($cells) { + $rows[] = $cells; + } + + return theme('table', array(), $rows, array('id' => 'taxonomy-list-table-'. $vid)); +} + +/** + * Theme a list of the term tree. + * + * @param $terms + * the enhanced term tree. + * @param $cells_per_row + * the number of cells per row to display. -- not used for list. + * @param $list_mode + * indicates how to show the hierarchy. + * @return + * the themed list to be displayed. + */ +function theme_taxonomy_list_list($terms, $cells_per_row = 1, $list_mode = 0) { + $items = array(); + $odd_even = array('even', 'odd'); + $i = 0; + foreach ($terms as $tid => $term) { + ++$i; + switch ($list_mode) { + case 0: // Hierarchical. + if ($term->depth) { + continue; + } + $item = array('data' => theme('taxonomy_list_term', $term), 'class' => $odd_even[$i & 1]); + if ($term->children) { + $item['children'] = _taxonomy_list_list_children($term->children, $terms); + } + $items[] = $item; + break; + case 1: // Flat. + $items[] = array('data' => theme('taxonomy_list_term', $term), 'class' => $odd_even[$i & 1]); + break; + } + } + return theme('item_list', $items, NULL, 'ul', array('class' => 'taxonomy-list-list')); +} + +/** + * Theme a directory list. + * + * @param $terms + * the enhanced term tree. + * @param $cells_per_row + * the number of cells per row to display. -- not used for directory. + * @param $list_mode + * indicates how to show the hierarchy. + * @return + * the themed list to be displayed. + */ +function theme_taxonomy_list_directory($terms, $cells_per_row = 1, $list_mode = 0) { + $hide_empty = variable_get('taxonomy_list_noshow', FALSE); + $output = '
'; + foreach ($terms as $tid => $term) { + if (!$term->depth) { // Only do top level terms here. +// $output .= print_r($term, true); + $data = $term->image . $term->title . $term->desc; + $nodes = taxonomy_list_select_nodes(array($tid)); + while ($nid = db_result($nodes)) { + $node = node_load($nid); + node_view($node, TRUE, FALSE, FALSE); + $data .= theme('taxonomy_list_directory_node', $node, $term); + } + // If there were no nodes, skip the whole thing. + if ($term->node_count == 0 && $hide_empty) { + continue; + } + if ($term->children) { + $data .= _taxonomy_list_directory_children($term->children, $terms); + } + $fieldset = array( + '#title' => check_plain($term->name), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#value' => $data, + ); + $output .= theme('fieldset', $fieldset); + } + } + return $output .'
'; +} + +/** + * Theme child terms for the directory list. + * + * @param $tids + * an array of term ids.. + * @param $tree + * the enhanced term tree. + * @return + * the themed list to be displayed. + */ +function _taxonomy_list_directory_children($tids, $tree) { + static $show_desc; + if (!isset($show_desc)) { + $show_desc = variable_get('taxonomy_list_show_description', TRUE); + } + $output = NULL; + foreach ($tids as $tid) { + $term = $tree[$tid]; + $data = $term->image . $term->title . ($show_desc ? $term->desc : NULL); + $nodes = taxonomy_list_select_nodes(array($tid)); + while ($nid = db_result($nodes)) { + $node = node_load($nid); + $data .= theme('taxonomy_list_directory_node', $node, $term); + } + if ($term->children) { + $data .= _taxonomy_list_directory_children($term->children, $tree); + } + $fieldset = array( + '#title' => check_plain($term->name), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#value' => $data, + ); + $output .= theme('fieldset', $fieldset); + } + + return $output; +} + +/** + * Theme a node selected for the directory list. + * + * @param $node + * the full node object. + * @param $term + * the enhanced term object. + * @return + * the themed node to be displayed. + */ +function theme_taxonomy_list_directory_node($node, $term) { + $output = '
'; + $output .= '
'; + $output .= '
'; + if ($node->iid) { + $output .= theme_image_attach_teaser($node); + } + else { + $output .= ' '; + } + $output .= ''; + $output .= '
'. l($node->title, drupal_get_path_alias('node/'. $node->nid)) .'
'; + $output .= '
'; + $output .= '
'; + + return $output .'
'; +} + +function _taxonomy_list_list_children($kids, $tree) { + $items = array(); + $odd_even = array('even', 'odd'); + $i = 0; + foreach ($kids as $tid) { + $term = $tree[$tid]; + ++$i; + $item = array('data' => theme('taxonomy_list_term', $term), 'class' => $odd_even[$i & 1]); + if ($term->children) { + $item['children'] = _taxonomy_list_list_children($term->children, $tree); + } + $items[] = $item; + } + return $items; +} + +/** + * Finds all nodes that match selected taxonomy conditions. + * Copied from taxonomy.module. + * + * @param $tids + * An array of term IDs to match. + * @param $operator + * How to interpret multiple IDs in the array. Can be "or" or "and". + * @param $depth + * How many levels deep to traverse the taxonomy tree. Can be a nonnegative + * integer or "all". + * @param $pager + * Whether the nodes are to be used with a pager (the case on most Drupal + * pages) or not (in an XML feed, for example). + * @param $type + * The node type to retrieve. + * @return + * A resource identifier pointing to the query results. + */ +function taxonomy_list_select_nodes($tids = array(), $operator = 'or', $depth = 0, $pager = TRUE, $type = NULL) { + if (count($tids) > 0) { + // For each term ID, generate an array of descendant term IDs to the right depth. + $descendant_tids = array(); + if ($depth === 'all') { + $depth = NULL; + } + foreach ($tids as $index => $tid) { + $term = taxonomy_get_term($tid); + $tree = taxonomy_get_tree($term->vid, $tid, -1, $depth); + $descendant_tids[] = array_merge(array($tid), array_map('_taxonomy_get_tid_from_term', $tree)); + } + + if ($type) { + if (is_array($type)) { + $get_type = " AND n.type IN ('". implode("', '", $type) ."')"; + } + else { + $get_type = " AND n.type='". $type ."'"; + } + } + else { + $get_type = NULL; + } + + if ($operator == 'or') { + $args = call_user_func_array('array_merge', $descendant_tids); + $placeholders = implode(',', array_fill(0, count($args), '%d')); + $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid IN ('. $placeholders .') AND n.status = 1'. $get_type .' ORDER BY n.sticky DESC, n.created DESC'; + $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid IN ('. $placeholders .') AND n.status = 1'. $get_type; + } + else { + $joins = ''; + $wheres = ''; + $args = array(); + foreach ($descendant_tids as $index => $tids) { + $joins .= ' INNER JOIN {term_node} tn'. $index .' ON n.nid = tn'. $index .'.nid'; + $placeholders = implode(',', array_fill(0, count($tids), '%d')); + $wheres .= ' AND tn'. $index .'.tid IN ('. $placeholders .')'; + $args = array_merge($args, $tids); + } + $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n '. $joins .' WHERE n.status = 1 '. $get_type . $wheres .' ORDER BY n.sticky DESC, n.created DESC'; + $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n '. $joins .' WHERE n.status = 1 '. $get_type . $wheres; + } + $sql = db_rewrite_sql($sql); + $sql_count = db_rewrite_sql($sql_count); + if ($pager) { + $result = pager_query($sql, variable_get('default_nodes_main', 10), 0, $sql_count, $args); + } + else { + $result = db_query_range($sql, $args, 0, variable_get('feed_default_items', 10)); + } + } + + return $result; +} + +/** + * Select and render the nodes in the chosen vocabularies. + */ +function taxonomy_list_nodes_render($vids, $max_depth, $type = NULL) { + $output = '
'; + $terms = array(); + // Get vocabulary names and list of tids. + foreach ($vids as $vid) { + $vocab = taxonomy_vocabulary_load($vid); + $vocab_titles[] = $vocab->name; + // Taxonomy_select_nodes will do the depth part for us, so we just get the top terms. + $terms = array_merge($terms, array_map('_taxonomy_get_tid_from_term', taxonomy_get_tree($vid, 0, -1, 1))); + } + drupal_set_title(implode(variable_get('taxonomy_list_title_separator', ' & '), $vocab_titles)); + sort($terms); + + // Render all nodes in a pager using taxonomy function. + $output .= taxonomy_render_nodes(taxonomy_list_select_nodes($terms, 'or', $max_depth, $type)); + + $output .= '
'; // class="taxonomy-list" + return $output; +} + +/** + * Theme the admin links. + */ +function theme_taxonomy_list_admin_links($vids) { + $destination = drupal_get_destination(); + $output = ''; + return $output; +} + +/** + * Theme the vocabulary. + */ +function theme_taxonomy_list_vocabulary($vocabulary, $types = FALSE, $title = TRUE) { + $output = '
'; + if ($title) { + $output .= '
'. check_plain($vocabulary->name) .'
'; + } + $output .= '
'. decode_entities(check_markup($vocabulary->description)) .'
'; + if ($types) { +// $list = array_intersect_key(node_get_types('names'), array_flip($vocabulary->nodes)); /* php 5.1 */ + $list = array_flip(array_intersect(array_flip(node_get_types('names')), $vocabulary->nodes)); + $output .= '

'. t('Used for content types') .': '. implode(', ', $list) .'

'; + } + $output .= '
'; + return $output; +} + +/** + * Theme the term. + */ +function theme_taxonomy_list_term($term) { + $output = '
' + . $term->image + . $term->title + . $term->parent_list + . $term->counter + . $term->links + . $term->desc + . $term->term_related + . $term->term_synonyms + .'
'; + return $output; +} + +/** + * Theme tree for a block. + * + * @param $terms + * the enhanced term tree. + * @return + * the themed list to be displayed. + */ +function theme_taxonomy_list_block($terms) { + $items = array(); + $odd_even = array('even', 'odd'); + $i = 0; + foreach ($terms as $tid => $term) { + ++$i; + $items[] = array('data' => theme('taxonomy_list_term_block', $term), 'class' => $odd_even[$i & 1]); + } + return theme('item_list', $items, NULL, 'ul', array('class' => 'taxonomy-list-block')); +} + +/** + * Theme the term for a block. + */ +function theme_taxonomy_list_term_block($term) { + $output = '
' + . $term->image + . $term->title + . $term->desc + .'
'; + return $output; +} + +/** + * Implementation of hook_block(). + */ +function taxonomy_list_block($op = 'list', $delta = 0, $edit = array()) { + global $user; + switch ($op) { + case 'list': + $vocabularies = taxonomy_get_vocabularies(); + foreach ($vocabularies as $vocabulary) { + $blocks[$vocabulary->vid]['info'] = t('Taxonomy List for !name', array('!name' => $vocabulary->name)); + } + return $blocks; + + case 'view': + // $delta is the vid. +// $block['content'] = taxonomy_list_show($delta, 'all', 'block', 1); + $tree = taxonomy_list_get_tree($delta); + $block['content'] = theme_taxonomy_list_block($tree); + return $block; + + case 'configure': + $form = array(); + return $form; + + case 'save': + return; + } // end switch($op) +} + +/** + * Menu callback; presents the admin settings form. + */ +function taxonomy_list_admin_settings() { + $form = array(); + + $form['taxonomy_list_info'] = array( + '#value' => t('

The taxonomy_list module enable the URL to browse into each vocabulary, using the format of :

') + . t('"taxonomy/vocabulary/<vid>"') + . t('

Together with the taxonomy_image.module, the list can be displayed with a image icon.

') + ); + + // General settings. + $form['general'] = array( + '#type' => 'fieldset', + '#title' => t('General settings'), + '#collapsible' => TRUE, + '#collapsed' => FALSE, + ); + + $sep_opts = array( + ' & ' => 'ampersand (&)', + ' | ' => 'vertical bar (pipe)', + ', ' => 'comma (,)', + ' • ' => 'bullet', + ' – ' => 'en-dash (–)', + ' — ' => 'em-dash (—)', + ' _ ' => 'underscore', + ); + $form['general']['taxonomy_list_title_separator'] = array( + '#type' => 'radios', + '#title' => t('Title separator'), + '#default_value' => variable_get('taxonomy_list_title_separator', ' & '), + '#options' => $sep_opts, + '#description' => t('This is the character that separates multiple vocabulary names in the page title.'), + '#prefix' => '
', + '#suffix' => '
', + ); + + $theme_opts = array( + 'table' => t('Table - Show terms in a table (legacy method).'), + 'list' => t('List - Show terms as a list.'), + 'directory' => t('Directory - Show terms as a directory of content.'), + ); + $form['general']['taxonomy_list_format'] = array( + '#type' => 'radios', + '#title' => t('List Format'), + '#default_value' => variable_get('taxonomy_list_format', 'table'), + '#options' => $theme_opts, + '#description' => t('The method, or layout, for displaying the terms.'), + ); + + $form['general']['taxonomy_list_list_mode'] = array( + '#type' => 'radios', + '#title' => t('List Mode'), + '#default_value' => variable_get('taxonomy_list_list_mode', 0), + '#options' => array( + '0' => t("Hierarchical - Subcategories set off to show the hierarchy."), + '1' => t('Flat - All terms are listed as the same level in the grid.'), + ), + '#description' => t('Whether Taxonomy List displays the hierarchy of the terms.'), + ); + + $form['general']['taxonomy_list_cell_per_row'] = array( + '#type' => 'textfield', + '#title' => t('Terms per row'), + '#size' => 5, + '#default_value' => variable_get('taxonomy_list_cell_per_row', 2), + '#description' => t('Number of terms to be displayed on the same row.'), + ); + + $form['general']['taxonomy_list_show_description'] = array( + '#type' => 'checkbox', + '#title' => t('Show parent descriptions?'), + '#default_value' => variable_get('taxonomy_list_show_description', TRUE), + '#description' => t('Should we display the description with parent terms in the directory view?'), + ); + + // Taxonomy Image. + if (module_exists('taxonomy_image')) { + $form['general']['taxonomy_list_show_image'] = array( + '#type' => 'checkbox', + '#title' => t('Show taxonomy image?'), + '#default_value' => variable_get('taxonomy_list_show_image', 1), + '#description' => t('The Taxonomy Image module is available; should we display the image with the term?'), + ); + } + + // Link settings. + $form['link'] = array( + '#type' => 'fieldset', + '#title' => t('Link options'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + $form['link']['taxonomy_list_edit_link'] = array( + '#type' => 'checkbox', + '#title' => t('Add "edit term" link'), + '#default_value' => variable_get('taxonomy_list_edit_link', FALSE), + '#description' => t('Should I add an "edit term" link to the display for authorized users?'), + ); + + if (module_exists('search')) { + $form['link']['taxonomy_list_search_link'] = array( + '#type' => 'checkbox', + '#title' => t('Add "search for term" link'), + '#default_value' => variable_get('taxonomy_list_search_link', FALSE), + '#description' => t('Should I add an "search for term" link to the display for authorized users?'), + ); + } + + $form['link']['taxonomy_list_rss_link'] = array( + '#type' => 'checkbox', + '#title' => t('Add RSS link'), + '#default_value' => variable_get('taxonomy_list_rss_link', FALSE), + '#description' => t('Should I add an RSS link (icon) to the display?'), + ); + + $form['link']['taxonomy_list_show_children'] = array( + '#type' => 'checkbox', + '#title' => t('Show children when clicked'), + '#default_value' => variable_get('taxonomy_list_show_children', FALSE), + '#description' => t('If this is a parent term, show the content for children when the link is clicked upon?'), + ); + + // Optional settings. + $form['optional'] = array( + '#type' => 'fieldset', + '#title' => t('Optional information'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + $form['optional']['taxonomy_list_types'] = array( + '#type' => 'checkbox', + '#title' => t('Show content types'), + '#default_value' => variable_get('taxonomy_list_types', FALSE), + '#description' => t('Do you want to display a list of the content types for the vocabulary?'), + ); + + $form['optional']['taxonomy_list_related'] = array( + '#type' => 'checkbox', + '#title' => t('Show related terms'), + '#default_value' => variable_get('taxonomy_list_related', FALSE), + '#description' => t('If there are related terms, should they be listed?'), + ); + + $form['optional']['taxonomy_list_synonyms'] = array( + '#type' => 'checkbox', + '#title' => t('Show synonyms for the term'), + '#default_value' => variable_get('taxonomy_list_synonyms', FALSE), + '#description' => t('If there are synonyms for the term, should they be listed?'), + ); + + $form['optional']['taxonomy_list_show_parents'] = array( + '#type' => 'checkbox', + '#title' => t('Show parents of the term'), + '#default_value' => variable_get('taxonomy_list_show_parents', FALSE), + '#description' => t('If this is a child term, show the parent structure?'), + ); + + // Counting settings. + $form['count'] = array( + '#type' => 'fieldset', + '#title' => t('Count content'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + $count_opts = array( + 'none' => t('No count.'), + 'all' => t('Count all content types.'), + 'by_type' => t('Count by content type.'), + 'not_zero' => t("Count by type, don't show zero counts."), + ); + $form['count']['taxonomy_list_count'] = array( + '#type' => 'radios', + '#title' => t('Count content types'), + '#default_value' => variable_get('taxonomy_list_count', 0), + '#options' => $count_opts, + '#description' => t('How Taxonomy List counts the content types for terms.'), + '#prefix' => '
', + '#suffix' => '
', + ); + + if (module_exists('node_type_filter')) { + $form['count']['taxonomy_list_count']['#description'] .= ' '. t('The "Count by type" options will generate a link to show that type within that term.'); + } + + $form['count']['taxonomy_list_noshow'] = array( + '#type' => 'checkbox', + '#title' => t('Hide terms with no content?'), + '#default_value' => variable_get('taxonomy_list_noshow', FALSE), + '#description' => t('Do not show the term if there is no content using the term. Requires one of the counting options above.'), + ); + + return system_settings_form($form); +}