Search code examples
phpwordpresswoocommerceproducttaxonomy-terms

Get Woocommerce products by name and category with wc_get_products()


I have a very simple WooCommerce Product Query - I need one product by name having specific category id.

$args = array(
    'status'     => 'publish', // Only published products
    'return'     => 'objects', // Return the product objects (WC_Product)
    'limit'=> 1,
    'product_category_id'   => array( 6 ), // Filter by category ID
    'name' => 'test'
);
$products = wc_get_products($args);

I found that this doesn't produce the results that I expect.

  1. It returns products with slug "test" and does not check what is the name/title of the product which is not what it should do according the documentation for wc_get_products and WC_Product_Query.

  2. It doesn't respect the category id filter. If there is a product with slug "test" it will be returned even if it is not in category 6 for example. (if I remove the "name" parameter the query correctly returns only products from category with ID 6.

I have read that there could be issues due to some internal WC cache and I have saved manually all the tested products and categories. I have tried with safe mode with only WC, 2024 theme and test plugin containing only the code above.

Am I doing something wrong?


Solution

  • As an alternative, you could try to use a WP_Query instead, embedded in a function, to get the product object(s) from the name and category(ies) ID(s).

    Also

    function get_product_objects_from( $name, $categories_ids ) {
        global $wpdb;
    
        $product_ids = (array) get_posts( array(
            'posts_per_page'  => 1, // limit
            'post_type'       => 'product',
            'post_status'     => 'publish',
            'title'           => $name,
            'fields'          => 'ids', // return
            'tax_query'       => array( array(
                'taxonomy' => 'product_cat',
                'field'    => 'term_id',
                'terms'    => $categories_ids,
            )),
        ));
        return $product_ids ? array_map('wc_get_product', $product_ids) : null;
    }
    

    Usage:

    $product_objects = get_product_object_from( 'test', [6] );
    echo '<pre>'. print_r( $product_objects, true ) . '</pre>'; // Output product objects 
    

    Tested and works.


    Addition:

    As it seems that there is a bug related to WC_Product_Query whith your query, you should report it. When this issue will be solved, you will be able to use your code.

    Note that both codes are actually effective: Only WooCommerce orders use their own tables when HPOS is enabled and this process took some years. For Products, WooCommerce is still using completely WordPress wp_posts table which handle the product name and for product categories it also use WordPress dedicated tables…