Getting WooCommerce product related child categories

This can backfire if the timing goes haywire or completely puncture a tire if you run over a bed-of-nails which will make your car go nowhere. We need to consider a few things here other wise a tomato or bicycle can be labelled as a 1967 Ford Mustang Shelby GT500, or the make will be Mustang Shelby GT500 and the model Ford,and we would not want that.

So lets look at a plan here to avoid silly stuff as above

  • Get the terms assigned to a post (car)

  • Determine if the top level term for all terms are Make, which for all purposes will be the term with ID of 27

  • We need to determine where does the post terms fit in with the hierarchy, ie, is the term a child or child term. To avoid any other deeper levels, we will only focus on children and grandchildren

  • Once we are sure that

    • the top level parent from any given post term is 27

    • and that the term is a child or grandchild

    then we can output our terms according to your needs

Lets look at how we will do it: (NOTE: The code is not fully tested and requires at least PHP 5.4. All code is commented for ease of understanding)

You will first need to understand, a post (or car) can only have one child and one grandchild term. If there are more, the last child and grandchild will be used

function get_car_info( $taxonomy = 'product_cat', $top_level_parent = 27 )
{
    // Make sure that we have a valid taxonomy before we start. If not, return false
    $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING );
    if ( !taxonomy_exists( $taxonomy ) )
        return false;

    // Make sure our $top_level_parent is 27, if not, validate int value
    if ( 27 !== $top_level_parent )
        $top_level_parent = filter_var( $top_level_parent, FILTER_VALIDATE_INT );

    // Now that everything is safe and sanitized/validated, lets get the current post
    global $post;

    // Now we need to get the terms attached to the post (or car)
    $terms = get_the_terms( $post->ID, $taxonomy );
    /**
     * Make sure we actually have terms, if not, return false
     * Just a note, we already made sure the taxonomy is valid, so $terms should never
     * return a WP_Error object
     */
    if ( !$terms )
        return false;

    // Great, we have terms, now the real work starts
    // Set our variables which will store our brand and model
    $brand = '';
    $model="";

    // We need to loop through the array of terms ...
    foreach ( $terms as $term ) {
        // ...check if the term is not top level, if so, skip the term
        if ( 0 == $term->parent )
            continue;

        /**
         * Check if the term parent is equal to $top_level_parent, if so, the term is
         * a direct child term, which mean it is the brand, so lets set $brand
         */
        if ( $term->parent == $top_level_parent ) {
            $brand = $term->name; // Adjust as needed, this output the name
            continue; // Lets move on and avoid any unnecessary work
        }

        /**
         * We have reached this point, so our term is not a top level parent or a 
         * direct child from the top level term. This term is a grandchild or even a 
         * lower level child. We now need to know where in the hierarchy this term fits in
         */
        $term_ancestor = get_ancestors( $term->term_id, $taxonomy );
        // Make sure this is a true grandchild, $term_ancestor should only have two values
        if ( 2 != count( $term_ancestor ) )
            continue;

        /**
         * Now that we know the term is a true grandchild, we need to make sure that it
         * is a true grandchild, we actually make sure that it is a grandchild to  $top_level_parent
         */
        if ( $top_level_parent != end( $term_ancestor ) )
            continue;

        /**
         * OK, we have reached the end here, the term is true grandchild of $top_level_parent,
         * so lets set $model
         */
        $model = $term->name;
    } // endforeach $terms

    /**
     * We are nearly done, make sure that we actually have values in $model and $brand
     * before we return any values to avoid silly output
     */
    if (    !$brand
         || !$model
    )
        return false;

    // YEAH!!! We are finally here, lets return our output
    return 'MAKE: ' . $brand . '</br>MODEL: ' . $model;
} 

Just a few notes before we look at how to use it, I have set two parameters to the function,

  • the first being $taxonomy which is set to the default woocommerce taxonomy product_cat

  • and the second parameter called $top_level_parent which is set to 27

This is to make the function dynamic. Should the taxonomy or term parent change in future, you can simply pass the new values to the function without modifying the function

You should also add any extra markup etc to suite your exact need, or even modify existing code

Finally, you can add the following inside the loop to display the model and brand of the car, or nothing if the post is about tomatoes or bicycles

echo get_car_info();