Search code examples
phpwordpresswoocommerceproductcustom-taxonomy

Handling a custom taxonomy in WooCommerce wc_get_products function


I register a taxonomy using the standard action:

add_action( 'init', 'product_brand_order_taxonomy' );
function product_brand_order_taxonomy()  {
    $labels = array(
        'name'                       => 'Brand Heirarchy',
        'singular_name'              => 'Brand Heirarchy',
        'menu_name'                  => 'Brand Heirarchy',
        'all_items'                  => 'All Brand Heirarchies',
        'parent_item'                => 'Parent Brand Heirarchy',
        'parent_item_colon'          => 'Parent Brand Heirarchy:',
        'new_item_name'              => 'New Brand Heirarchy Name',
        'add_new_item'               => 'Add New Brand Heirarchy',
        'edit_item'                  => 'Edit Brand Heirarchy',
        'update_item'                => 'Update Brand Heirarchy',
        'separate_items_with_commas' => 'Separate Brand Heirarchy with commas',
        'search_items'               => 'Search Brand Heirarchies',
        'add_or_remove_items'        => 'Add or remove Brand Heirarchies',
        'choose_from_most_used'      => 'Choose from the most used Brand Heirarchies',
    );
    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => true,
        'public'                     => true,
        'show_ui'                    => true,
        'show_admin_column'          => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => true,
    );
    register_taxonomy( 'brand_heirarchy', 'product', $args );
    register_taxonomy_for_object_type( 'brand_heirarchy', 'product' );
}

Later I'd like to get products based on some arguments. I'd also like the brand_heirarchy to be included in the result.

$products = array(
    'post_status' => 'publish',
    'limit' => -1,
    'category' => $parent_brand_slugs
);

$products = wc_get_products($product_args);

In the returned data it will give me category_ids like

[category_ids] => Array
    (
        [0] => 30
        [1] => 27
        [2] => 25
        [3] => 24
    )

But I would like to have it also return the ids of the brand_heirarchy that are associated with the products.

Most things I see is about how to filter products by a custom taxonomy, I just want to know what taxonomies are as associated with a product.

I ran across this saying Woocommerce doesn't allow this: https://github.com/woocommerce/woocommerce/issues/13138

I looked at using this filter woocommerce_product_object_query_args but couldn't figure it out. There is also a product search filter, but it didn't look like it applied.

At this point, it seems my best bet is to loop over each product and use something like wp_get_object_terms( $data['id'], 'brand_heirarchy' ); but that seems inefficient.

Been a long time since I've done Wordpress so really asking if there's a more efficient way I should be getting the taxonomies associated with each product.

Thanks.


Solution

  • It is completely possible to handle a custom taxonomy using wc_get_products(). You didn't search in the right place as this is handled within WC_Product_Data_Store_CPT class using the available filter hook woocommerce_product_data_store_cpt_get_products_query.

    So for your custom product taxonomy brand_heirarchy, you will use the following:

    add_filter( 'woocommerce_product_data_store_cpt_get_products_query', 'handle_custom_product_query_var', 10, 2 );
    function handle_custom_product_query_var( $query_args, $query_vars ) {
        if ( ! empty( $query_vars['brand'] ) ) {
            $query_args['tax_query'][] = array(
                'taxonomy'          => 'brand_heirarchy',
                'field'             => 'slug',
                'terms'             => $query_vars['brand'],
            );
        }
        return $query_args;
    }
    

    Then now you can use your custom taxonomy in wc_get_products() function like:

    $products = wc_get_products( array(
        'status' => 'publish',
        'limit' => -1,
        'brand' => $brand_slugs // array
    ) );
    

    Now it should work.


    Addition: Targeting WooCommerce product taxonomies

    1). Product Categories:

    You can use "category" argument with term slugs or "product_category_id" with term Ids.

    2). Product Tags:

    You can use "tag" argument with term slugs or "product_tag_id" with term Ids.

    3). Product attributes (global attributes):

    Note that all product attributes taxonomy always start with "pa_".

    You can use the following function to handle a product attribute query ("Size" attribute):

    add_filter( 'woocommerce_product_data_store_cpt_get_products_query', 'handle_custom_product_attr_size', 10, 2 );
    function handle_custom_product_attr_size( $query_args, $query_vars ) {
        if ( ! empty( $query_vars['size'] ) ) {
            $query_args['tax_query'][] = array(
                'taxonomy'          => 'pa_size',
                'field'             => 'slug', // or 'term_id'
                'terms'             => $query_vars['size'],
            );
        }
        return $query_args;
    }
    

    Code goes in functions.php file of your child theme (or in a plugin).

    Then for example for "Size" product attribute, you will use

    $products = wc_get_products( array(
        'status' => 'publish',
        'limit' => -1,
        'size' => 'medium',
    ) );
    

    Related documentation: