Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Cannot figured it out... I need to count how many posts there are for each taxonomy term form each month.

share|improve this question

2 Answers 2

This is a long answer and there is a lot of code, please note that it is all not tested.

My solution use a function that create a multidimensional array where key are year, month, term id and the value are the term count.

The function also accept as argument an array of args to pass to WP_Query, limiting the term counting to desidered posts, so you can count terms of a taxonomy in a specific period using WP_Query time options or only for posts that respond to another taxonomy query using tax_query options, and so on.

Data ireturned by function are very rich and can be manipulated in a lot of ways, as example I will post a function that return the counting for a specific term in a specific month.

Anyway, here you are:

function set_cont_taxonomy_term_for_months($taxonomy = 'category', $query_args = '')  {
  $defaults = array(
    'posts_per_page' => -1,
  );
  $args = wp_parse_args($query_args, $defaults);
  $query =  new WP_Query( $args );

  $output = array();

  if ( $query->have_posts() ) : while( $query->have_posts() ) :  $query->the_post();
    $terms =  wp_get_object_terms( get_the_ID(), $taxonomy, array('fields' => 'ids') );
    if ( is_array($terms) && ! empty($terms) ) {
      global $post;
      $year = (int) substr($post->post_date, 4, 0);
      $month = (int) substr($post->post_date, 5, 2);
      if ( ! isset($output[$year]) ) $output[$year] =  array();
      if ( ! isset($output[$year][$month]) ) $output[$year][$month] = array();
      foreach ( $terms as $term ) {
        $output[$year][$month][$term] = isset($output[$year][$month][$term]) ? $output[$year][$month][$term] + 1 : 1;
      }
    }
  endwhile;
  endif;
  wp_reset_postdata();
  return $output;
}

The output of this function is an array which an inner item is something like:

$output[2013][7][132] = 5

that is: in the July 2013 the term with ID 132 was used 5 times

Note that this assertion is valid 'in general' (for all posts) only if second argument of function is empty (as is by default) otherwise is valid only for posts responding to the query args array passed as second param to function.

Now, you can use the array generated by this function with this other one:

function get_month_term_count($term_id = 0,  $year = '', $month = '', $taxonomy = 'category', $query_args = array() ) {
   if ( ! $term_id ) return 0;
   if ( ! $year ) $year = (int)date('Y');
   if ( ! $month ) $year = (int)date('n');
   $count = (array) set_cont_taxonomy_term_for_months( $taxonomy, $query_args );
   return ( empty($count) || ! isset($count[$year][$month][$termid]) ) ? 0 : $count[$year][$month][$termid];
}

The output of this function is a number, that is the counting for a given term id in a given month for a given query posts.

Use it is a lot easier than explain:

Following code shows how many times category with id '3' is used in posts of current month:

$cat = get_term(3);
$today = getdate();
$m = ($today["year"] * 100 ) + $today["mon"];
$count = get_month_term_count( 3, $today['year'], $today['mon'], 'category', array('m' =>$m) );
sprintf( __('In current month category %s is used %d times.'), $cat->name, $count);

As I previous said, the data generated by the set_cont_taxonomy_term_for_months are very rich, as example, following code shows tag counting in all the months of current year:

$today = getdate();
$count = set_cont_taxonomy_term_for_months( 'post_tag', array('year' => $today["year"] ) );

if ( ! empty($count) ) {
  foreach ( $count as $year => $year_array ) {
    echo '<h1>' __('Year: ') . $year '</h1>';
    foreach ( $year_array as $month => $month_array ) {
      echo '<h2>';
      _e('Month ') . date_i18n( "F", mktime(0, 0, 0, $month, 1, $year ) );
      echo '</h2>';
      echo '<ul>'; 
      foreach ( $month_array as $tag_id => $count ) {
        $tag = get_term($tag_id);
        if ( ! is_wp_error($tag) && ! empty($tag) ) {
           printf( __('<li>Tag %s used %d times</li>'), $tag->name, $count );
        }
      }
      echo '</ul>';
    }
  }
}

If you have a lot of posts, doing 3 nested foreach cycles will slow down the script, so try to use the function set_cont_taxonomy_term_for_months passing $query_args as selective as possible and, if you can, write functions to return desired informations without perform cycles, just like I do with with get_month_term_count function.

Hope it helps.

Edit:

I have changed the 3 nested loops in my last example, now it should works.

share|improve this answer

One method you might want to research is wp_get_archives http://codex.wordpress.org/Function_Reference/wp_get_archives

You might also be able to use the_date() to sort out posts in a given month. http://codex.wordpress.org/Function_Reference/the_date

I would try to find a function that can store results in an array, and then use count() on the array to learn it's contents...

Good luck!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.