0

Normal behaviour of get_terms is not to return terms if there are no posts assigned to. But this is not the case, I can see terms assigned in admin and also checked the database and all seems fine. Also check this code:

$p = get_post(5018); // correctly returns the post

// works: returns the assigned term
$post_terms = wp_get_post_terms($p->ID, 'solutions_sectors', array("fields" => "all"));

// now the opposite:
$first = $post_terms[0];
$tid = $first->term_id;
// works: gives a list of post ids
$term_posts = get_objects_in_term($tid, 'solutions_sectors');

// still, this will output an empty array:
$terms = get_terms(array('taxonomy' => 'solutions_sectors');

// while this will output the right array (obviously):
$terms = get_terms(array('taxonomy' => 'solutions_sectors', 'hide_empty' => false));

So, my posts do have the terms, but get_terms seems not to realise it. Why?

Please note the following:

  • I'm using custom post types with custom taxonomies

  • I'm using polylang as the languages plugin (but all the posts and terms seems to be correctly translated and assigned)

Luca Reghellin
  • 7,426
  • 12
  • 73
  • 118

2 Answers2

3

Found the problem: the count field of the term_taxonomy table was empty, and this is because I bulk-saved my posts using wp_insert_post() during a custom import.

wp_insert_post() seems to have a bug: it correctly applies specified terms to the new post but doesn't update the term_taxonomy count.

The solutions here is a one-shot call to wp_update_term_count_now()`.

Since I have to retrieve all the terms ids on a file executed prior to the taxonomies creation, I've got to wrap the code in an init action.

add_action('init','reset_counts', 11, 0);
function reset_counts(){
  // I'm currently using polylang so first I get all the languages
  $lang_slugs = pll_languages_list(array('fields' => 'slug'));

  foreach($lang_slugs as $lang){
    $terms_ids = get_terms(array(
      'taxonomy' => 'solutions_sectors'
      ,'fields' => 'ids'
      ,'lang' => $lang
      ,'hide_empty' => false
    ));

    // it's important to perform the is_array check 
    if(is_array($terms_ids)) wp_update_term_count_now($terms_ids, 'solutions_sectors');
  }
}

That did the trick. After running it is important to comment out the init action call.

Luca Reghellin
  • 7,426
  • 12
  • 73
  • 118
2

If get_terms doesnt works for some strange reason with custom taxonomy not showing registered try using WP_Term_Query:

$term_query = new WP_Term_Query( array( 
    'taxonomy' => 'regions', // <-- Custom Taxonomy name..
    'orderby'                => 'name',
    'order'                  => 'ASC',
    'child_of'               => 0,
    'parent' => 0,
    'fields'                 => 'all',
    'hide_empty'             => false,
    ) );


// Show Array info
echo "<pre>";
print_r($term_query->terms);
echo "</pre>";


//Render html
if ( ! empty( $term_query->terms ) ) {
foreach ( $term_query ->terms as $term ) {
echo $term->name .", ";
echo $term->term_id .", ";
echo $term->slug .", ";
echo "<br>";
}
} else {
echo '‘No term found.’';
}

Get all args from here: https://developer.wordpress.org/reference/classes/WP_Term_Query/__construct/

samjco-com
  • 365
  • 5
  • 14
  • 2
    It seems in 2021 `get_terms()` is buggy, at least for custom taxonomies. Using exactly the same arguments array in `get_terms()` as in `WP_Term_Query()` got me different results, with the latter being correct. Perhaps this could be down to caching of terms, which I do not fully understand? – Ian Nov 25 '21 at 10:38