Inserting terms in an Hierarchical Taxonomy

I’m really having a few issues with inserting terms. Here is my scenario: I have a taxonomy called veda_release_type:

//Release Type and Region
        $labels = array(
            'name'=> _x('Release Types/Regions', 'taxonomy general name' ),
            'singular_name' => _x('Release Type/Region', 'taxonomy singular name'),
            'search_items' => __('Search Release Types/Regions'),
            'popular_items' => __('Popular Release Types/Regions'),
            'all_items' => __('All Release Types/Regions'),
            'edit_item' => __('Edit Release Type/Regions'),
            'edit_item' => __('Edit Release Type/Region'),
            'update_item' => __('Update Release Type/Region'),
            'add_new_item' => __('Add New Release Type/Region'),
            'new_item_name' => __('New Release Type/Region Name'),
            'separate_items_with_commas' => __('Seperate Release Types/Regions with Commas'),
            'add_or_remove_items' => __('Add or Remove Release Types/Regions'),
            'choose_from_most_used' => __('Choose from Most Used Release Types/Regions')
        );
        $args = array( 
            'hierarchical' =>true,  
            'labels' => $labels,  
            'query_var' => true,  
            'rewrite' => array('slug' =>'release_type')     
        );
        register_taxonomy('veda_release_type', 'veda_release',$args);

It’s obviously hierchical. Top level contains release types ieDVD, blu-ray. The level under that are regions ie. Region 1, Region 2, etc. So, the Hierarchy that I want is:
DVD
–Region 0
–Region 1
–Region 2
–Region 3
–Region 4
–Region 5
–Region 6
Blu-Ray
–Region A
–Region B
–Region C

Read More

I created a function called insert_term in my class to check if a term exists then insert it if it doesn’t:

public function insert_term ($term, $taxonomy, $args = array()) {
        if (isset($args['parent'])) {
            $parent = $args['parent'];
        } else {
            $parent = 0;
        }
        $result = term_exists($term, $taxonomy, $parent);
        if ($result == false || $result == 0) {
            return wp_insert_term($term, $taxonomy, $args);             
        } else {
            return (array) $result;
        }       
}

And then I call said function to insert the terms:

    $dvd = $this->insert_term('DVD','veda_release_type');
    $this->insert_term('Region 0','veda_release_type',array('parent'=>$dvd['term_id']));
    $this->insert_term('Region 1','veda_release_type',array('parent'=>$dvd['term_id']));
    $this->insert_term('Region 2','veda_release_type',array('parent'=>$dvd['term_id']));
    $this->insert_term('Region 3','veda_release_type',array('parent'=>$dvd['term_id']));
    $this->insert_term('Region 4','veda_release_type',array('parent'=>$dvd['term_id']));
    $this->insert_term('Region 5','veda_release_type',array('parent'=>$dvd['term_id']));
    $this->insert_term('Region 6','veda_release_type',array('parent'=>$dvd['term_id']));

    $bd = $this->insert_term('Blu-Ray', 'veda_release_type');
    $this->insert_term('Region A','veda_release_type',array('parent'=>$bd['term_id']));
    $this->insert_term('Region B','veda_release_type',array('parent'=>$bd['term_id']));
    $this->insert_term('Region C','veda_release_type',array('parent'=>$bd['term_id']));

The problem I’m having is that even though the terms get inputed in the database, they don’t show up on the taxonomy page. At most, the top level terms show up. I have to try various things until it sorta forces WordPress to recognize the sublevel terms. Has anyone run into this or can recommend a better way?

EDIT:
Noticed something else: I tried deleting the terms off the database then deactivating and reactivating the plugin that declares the terms. The two parent terms show up in the terms page, but the child terms do not. The child terms DO show up in the “Parent” drop down menu where you want to create a new term. When I add a term whose parent is one of the child terms and refresh the page, THEN the child terms show up.
enter image description here

Related posts

Leave a Reply

7 comments

  1. The hierarchy is cached and it’s not invalidated properly. This is a bug, still unresolved as of WP 3.1.

    A workaround would be to call delete_option("{$taxonomy}_children"); directly.

    See the _get_term_hierarchy() function.

  2. My 2 cents – I am building an extension for the WooCommerce plugin that allows catalog category/product management via an uploaded CSV file. I ran into this same issue when generating the categories. The solution to clear the cached WooCommerce categories was to call delete_option("product_cat_children"); after the loop that creates the categories and sub-categories. Hope this helps someone else!

  3. You could possibly be receiving an object back from term_exists($term, $taxonomy, $parent) if the taxonomy is set when called. It’s set in the sample code you posted, so i’m assuming that’s the issue.

    Your inserts statements are expecting an array when they reference keys..

    Eg.

    $bd['term_id']
    $dvd['term_id']
    

    ..but you may actually be getting an object back from term_exists.

    A quick way to determine if that’s the problem would be to update this line.

    return $result;
    

    to..

    return is_object( $result ) ? (array) $result : $result;
    

    If i’m right and that is the problem, that should fix it, though i’d not call that an elegant fix.

    Hopefully that’s the answer/help you were looking for.. 🙂

  4. Thanks. This question helped a lot.
    I was struggling with unit tests and found i had to do

    delete_option('veda_release_type');
    wp_cache_flush();
    

    after adding my top level categories, and then do it again after adding the second level categories to allow wordpress to clear everything and let the unit tests pass. This works around the need for a “second page load / extra refresh” referred to in another answer here.

  5. my solution:

    (maybe it was needed to clean the cache records..)

    $PARENT_CAT= wp_insert_term('Parent_category_NAME','category',  array('slug'=> 'Parent_category_NAME'));
    delete_option("category_children");
    wp_cache_flush();
    
        $child= wp_insert_term('children_category_NAME','category',array( 'slug'=>'children_category_NAME', 'parent' =>$PARENT_CAT['term_id']));
        delete_option("category_children");
        wp_cache_flush();
    
  6. I have got the same issue on woocommerce product_cat taxonomy once generate category by rest API and I have tried below solution and it works fine 🙂

    add_action( 'admin_init', 'updateTermChildren' );
    function updateTermChildren(){    
       _get_term_hierarchy('product_cat');
    }`