The conversion to Field API caused taxonomy_term_count_nodes() to be removed form the API. A lot of contributed modules depend on this function and a lot of users want this feature. Because it used to exist I am marking this a bug.

Comments

Anonymous’s picture

I'm not a big fan of this idea, but I sympathize with the potential frustration of its loss. I wonder if this isn't a call to have a "legacy" module where these functions can be placed. I wouldn't want contrib maintainers to write the same code over and over again because this function has disappeared.

A lot of modules also read $node->taxonomy, which has the convenience of being an array of all terms in all vocabularies for a node. In Drupal 7, we will have to determine which field instance on this bundle has a term's vocabulary in its allowed values. Should we put $node->taxonomy back, too?

If we do restore it, I want to ask: Why should it only count nodes? because it's what Drupal 6 modules expect?

giorgio79’s picture

http://drupal.org/project/term_node_count
This project has views integration etc etc :)

Although a CCK Count module would be cool where we can select the table, or the column for which we want to maintain a summary table :)

catch’s picture

The proper way to fix this would be #603236: Add count facility to field_attach_query(). There's not much time before freeze but let's explore that before we revert here - whether it's a contrib helper module or a core patch.

catch’s picture

Status: Active » Closed (duplicate)

Between #603236: Add count facility to field_attach_query() and http://drupal.org/project/term_node_count there's an ability to get the count in core, and a module implementing what looks to be a nice performant lookup table in contrib (and which should be able to use field hook and field_attach_query() to do what it's doing in D6). So marking this as a duplicate of those two.

I also opened #603868: Rework Term Node Count for D7.

antroxim’s picture

Hi everyone!
It's my first comment at drupal.org and my first "drupal-custom-functioning" experience.
I wrote a simplest function to count nodes by term ID.

Hope someone find it useful.

<?php
/*
 * @param tid
 *   Term ID
 * @param child_count
 *   TRUE - Also count all nodes in child terms (if they exists) - Default
 *   FALSE - Count only nodes related to Term ID
 */
function term_nc($tid, $child_count = TRUE) {
  $tids = array($tid);
  
  if ($child_count){
  $children = taxonomy_get_children($tid);
    if (!empty($children)){
      foreach($children as $child){
        $tids[] = $child->tid;
      }
    }
  }
  
  $tids = implode(" OR tid = ", $tids );
  $sql = "SELECT COUNT(nid) FROM {taxonomy_index} WHERE tid = $tids";
  $count = db_query($sql)->fetchField();
  return  $count;
}
?>
Avorathol’s picture

An improvement of #5, with some recursion to take account of hierarchical children.

/*
 * @param tid
 *   Term ID
 * @param child_count
 *   TRUE - Also count all nodes in child terms (if they exists) - Default
 *   FALSE - Count only nodes related to Term ID
 */
function term_nc($tid, $child_count = TRUE) {
  $tids = array($tid);
  
  if ($child_count){
    term_get_children_ids($tid, &$tids)
  }
  
  $tids = implode(" OR tid = ", $tids );
  $sql = "SELECT COUNT(nid) FROM {taxonomy_index} WHERE tid = $tids";
  $count = db_query($sql)->fetchField();
  return  $count;
}

/**
 * Retrieve ids of term children .
 *
 * @param $tid
 *   The term's ID.
 * @param $tids
 *   An array where ids of term children will be added
 */
function term_get_children_ids($tid, &$tids) {
  $children = taxonomy_get_children($tid);
  if (!empty($children))
  {
    foreach($children as $child)
    {
      $tids[] = $child->tid;
      term_get_children_ids($child->tid, $tids);
    }
  }
}
cegri’s picture

Some tweaks on #6:

1) Modified the handling of the recursive sub-function. I was getting "call_time_pass_reference" errors.

2) Added language criteria. Only nodes in the current language and neutral language (undefined) are counted.

Note: I'm not a programmer. I go around copying, pasting and tweaking others' codes. So, use cautiously. Any improvements are wellcome.


/*
* @param tid
*   Term ID
* @param child_count
*   TRUE - Also count all nodes in child terms (if they exists) - Default
*   FALSE - Count only nodes related to Term ID
*/
function term_nc($tid, $child_count = TRUE) {
  $tids = array($tid);
 
  if ($child_count){
    $tids = array_merge($tids, term_get_children_ids($tid));
  }
  
  global $language;
  $langs = array($language->language);
  $langs[] = 'und';
  
  
  $query = db_select('taxonomy_index', 't');
  $query->condition('tid', $tids, 'IN');
    $query->join('node', 'n', 't.nid = n.nid');
    $query->condition('n.status', 1, '=');
    $query->condition('n.language', $langs, 'IN');

$count = $query->countQuery()->execute()->fetchField();
  return  $count;
}

/**
* Retrieve ids of term children .
*
* @param $tid
*   The term's ID.
* @param $tids
*   An array where ids of term children will be added
*/
function term_get_children_ids($tid) {
  $children = taxonomy_get_children($tid);
  $tids=array();

  if (!empty($children))
  {
    foreach($children as $child)
    {
      $tids[] = $child->tid;
      $tids = array_merge($tids, term_get_children_ids($child->tid));
    }
  }
 
return $tids;
}
?>
leofishman’s picture

Thanks!!