phpwordpresswoocommerceproductcustom-taxonomy

Get all simple products that have global product attribute brand in WooCommerce


In woocommerce I's trying to retrieve all products that have global attribute brand. from my prior understandings and also some googling I have done this so far:

function handle_custom_query_var($query, $query_vars)
{
    if (!empty($query_vars['with_brand'])) {
        $query['meta_query'][] = array(
            'key' => 'pa_brand',
        'field'    => 'term_id', 
        'compare' => 'EXISTS'
        );
    }
    return $query;
}
add_filter('woocommerce_product_data_store_cpt_get_products_query', 'handle_custom_query_var', 10, 2);

$args = array(
    'status' => 'publish',
    'type' => 'simple',
    'limit' => 50,
    'paginate' => true,
    'page' => $request['page'],
    'with_brand' => true
);  
$results = wc_get_products($args);

but still I'm getting simple products with no brand attribute. what I'm doing wrong?

PS: kindly ignore unrelated parameters inside wc_get_products arguments.

I also tried

'operator' => 'IN'

instead of

'compare' => 'EXISTS'

but it did not work either.


Solution

  • You need to use a tax_query and 'compare' has to be replaced with 'operator' like:

    add_filter('woocommerce_product_data_store_cpt_get_products_query', 'handle_pa_brand_product_attribute', 10, 2);
    
    function handle_pa_brand_product_attribute($query, $query_vars)
    {
        if ( isset($query_vars['brand']) && $query_vars['brand'] === 'EXISTS' ) {
            $query['tax_query'][] = array(
                'taxonomy'  => 'pa_brand',
                'operator'  => esc_attr($query_vars['brand']),
            );
        }
        return $query;
    }
    

    Then your WC_Product_Query will be:

        $args = array(
            'status'    => 'publish',
            'type'      => 'simple',
            'limit'     => 50,
            'paginate'  => true,
            'page'      => $request['page'],
            'brand'     => 'EXISTS',
        );  
        $results = wc_get_products($args);
    

    Tested and works.


    Addition: handling multiple product attributes.

    You can handle multiple product attributes (here we use "Brand" and "Color"):

    add_filter('woocommerce_product_data_store_cpt_get_products_query', 'handle_specific_product_attributes', 10, 2);
    
    function handle_specific_product_attributes($query, $query_vars)
    {
        // "Brand" with "EXISTS" parameter
        if ( isset($query_vars['brand']) && $query_vars['brand'] === 'EXISTS' ) {
            $query['tax_query'][] = array(
                'taxonomy'  => 'pa_brand',
                'operator'  => esc_attr($query_vars['brand']),
            );
        }
    
        // "Color" with term "slug" parameter
        if ( isset($query_vars['color']) && ! empty($query_vars['color']) ) {
            $terms = (array) implode(',', esc_attr($query_vars['color']));
    
            $query['tax_query'][] = array(
                'taxonomy'  => 'pa_color',
                'field'     => 'slug',
                'terms'     => $terms,
            );
        }
        return $query;
    }
    

    Then an example of WC_Product_Query using both:

        $args = array(
            'status'    => 'publish',
            'type'      => 'simple',
            'limit'     => 50,
            'paginate'  => true,
            'page'      => $request['page'],
            'brand'     => 'EXISTS',
            'color'     => 'red,green',
        );  
        $results = wc_get_products($args);