I want to get a list of products of a given category from WP_query, but it won’t work like it should.

I’ve done this :

$args = array( 
    'post_type' => 'product',
    'product_cat' => 17,
);
$products = new WP_Query($args);

But this returns every product from my shop … I have also tried with ‘cat’, ‘category’ and ‘category_name’ attr with same result.

I’ve tried using tax_query :

$args = array( 
    'post_type' => 'product',
    'tax_query' => array(
        'taxonomy' => 'product_cat',
        'terms'    => 17
    ),
);
$products = new WP_Query($args);

And this also returns every products
I have also tried with ‘cat’, ‘category’ and ‘category_name’ with same result.

I have managed using the following code to get regular posts from a given category.

$args = array( 
    'post_type' => 'post',
    'cat'       => 22
);
$posts = new WP_Query($args);

A couple more things :

  • I am certain I have the right category id.
  • tax_query worked for the posts too
  • edit : tax_query returns every products, ignoring my product_cat attr

    I have been looking to do this for days and tried every possible solution of similar questions on stack and other sites without success… Why doesn’t it work for products ?

EDIT : the code snipet with tax_query was wrong so I changed it.

EDIT 2 : I have tried several new Things, here is the summary :

  • disabled all custom hooks : same results
  • instantiated a WC_Product manually by the id of an actual product as an argument. It shows that its category_ids attribute is empty, even though the product does have a category on the admin panel… and the category taxonomy page shows the right stuff too.
  • when I do var_dump(get_the_terms($postID, 'category')); on a regular post it works fine

EDIT 3 :
– disabled all plugins but Woocommerce with same result…
– when I do var_dump(get_post_types());, the product post type does not show. And so naturally, when I do var_dump(get_object_taxonomies('product'));, it returns an empty array.

2 Answers
2

In the end my main problem turned out to be that I was executing code right into functions.php (for testing purpose). The code was executing before woocommerce was initialized and then was failing to fetch products correctly.
Despite that, I couldn’t get Wp_Query to return only products of one given category. It was still returning every product from my database so I found a way around it.

$category; //this is the var containing the wanted category slug
$productPosts = new WP_Query(array(
    'post_type' => 'product'
));

//I could have used $productPosts->have_posts() here but I decided not to use it in my particular context
foreach ($productPosts->posts as $p) {
    $currentProduct = new WC_Product_Variable($p->ID);

    //I can only access category ids with WC_Product so I'm building an array of category slugs instead
    foreach ($currentProduct->get_category_ids() as $catId) {
        if( $term = get_term_by( 'id', $catId, 'product_cat' ) ){
            array_push($categories, $term->name); //push it
        }
    }

    if(in_array($category, $categories)){ //if the current currentProduct has the asked category,
        //push it in $currentProduct into $products array
        array_push($products, $currentProduct);
    }
    else{//current product doesn't have asked category
    }
} //end foreach, we now have all products of asked category... in $products array

This works… But really, it feels wrong. I’m making several database queries for each product I want to include in my final array… Is this how woocommerce is supposed to work ?
Also, I’m not sure how i’m supposed to paginate with this data but anyway it’s not my concern here…

There must be a better way to do this but I couldn’t find it for now…

Leave a Reply

Your email address will not be published. Required fields are marked *