Skip to main content

wc_get_products and product queries

wc_get_products and WC_Product_Query provide a standard way of retrieving products that is safe to use and will not break due to database changes in future WooCommerce versions. Building custom WP_Queries or database queries is likely to break your code in future versions of WooCommerce as data moves towards custom tables for better performance. This is the best-practices way for plugin and theme developers to retrieve multiple products. wc_get_products and WC_Product_Query are similar to WordPress get_posts and WP_Query. Just like those, you pass in an array of arguments defining the criteria for the search.

Basic usage

Examples

Here are a few examples:

// Get downloadable products created in the year 2016.
$products = wc_get_products( array(
'downloadable' => true,
'date_created' => '2016-01-01...2016-12-31',
) );
// Get 10 most recent product IDs in date descending order.
$query = new WC_Product_Query( array(
'limit' => 10,
'orderby' => 'date',
'order' => 'DESC',
'return' => 'ids',
) );
$products = $query->get_products();
// Get products containing a specific SKU.
// Does partial matching, so this will get products with SKUs "PRDCT-1", "PRDCT-2", etc.
$query = new WC_Product_Query();
$query->set( 'sku', 'PRDCT' );
$products = $query->get_products();

Note that wc_get_products() is mostly a shortcut to WC_Product_Query::get_products().

API reference

MethodDescription
wc_get_products( $args )Retrieve products matching query $args.
WC_Product_Query::get_query_vars()Get an array of all of the current query variables set on the query object.
WC_Product_Query::get( string $key, mixed $default = '' )Get the value of a query variable or the default if the query variable is not set.
WC_Product_Query::set( string $key, mixed $value )Set a query variable to a value.
WC_Product_Query::get_products()Get all products matching the current query variables.

Query parameters/arguments that can be used with these functions are described below.

Query parameters reference

General

ParameterDescription
statusAccepts a string or array of strings: one or more of 'draft', 'pending', 'private', 'publish', or a custom status. See ProductStatus constant class.
typeAccepts a string or array of strings: one or more of 'external', 'grouped', 'simple', 'variable', or a custom type. See ProductType constant class.
includeAccepts an array of integers: only includes products with IDs in the array.
excludeAccepts an array of integers: excludes products with IDs in the array.
parentAccepts an integer: post ID of the product parent.
parent_excludeAccepts an array of integers: excludes products with parent IDs in the array.
orderAccepts a string: 'DESC' or 'ASC'. Use with 'orderby'. Default: 'DESC'.
orderbyAccepts a string: 'none', 'ID', 'name', 'type', 'rand', 'date', 'modified'. Default: 'date'.
returnReturn type. Accepts a string: 'ids' or 'objects'. Default: 'objects'.

Examples

// Get draft products.
$products = wc_get_products( array( 'status' => 'draft' ) );
// Using constant class for status.
$products = wc_get_products( array( 'status' => \Automattic\WooCommerce\Enums\ProductStatus::DRAFT ) );
// Get external products.
$products = wc_get_products( array( 'type' => 'external' ) );
// Get external products limited to specific IDs.
$args = array(
'type' => 'external',
'include' => array( 134, 200, 210, 340 ),
);
$products = wc_get_products( $args );
// Get products that aren't the current product.
$products = wc_get_products( array( 'exclude' => array( $product->get_id() ) ) );
// Get products with a specific parent.
$products = wc_get_products( array( 'parent' => 20 ) );
// Get most recently modified products.
$args = array(
'orderby' => 'modified',
'order' => 'DESC',
);
$products = wc_get_products( $args );
// Get some random products.
$products = wc_get_products( array( 'orderby' => 'rand' ) );
// Return only product IDs.
$products = wc_get_products( array( 'return' => 'ids' ) );

Product archive URL query parameters

The query parameters in this reference are PHP arguments for wc_get_products() and WC_Product_Query. Storefront product archives, including the shop page and product category pages, can also read query parameters from the URL to build the main catalog query. For example, the orderby URL query parameter changes the catalog sort order.

To link visitors to a catalog view that lists products with prices before products without prices, sort the archive by price from high to low:

https://example.com/shop/?orderby=price-desc
https://example.com/product-category/clothing/?orderby=price-desc

The price-desc value maps to the "Price: high to low" catalog sort. Products with no price or a zero price are sorted after products with a higher price. Use orderby=price for the "Price: low to high" catalog sort.

Pagination

ParameterDescription
limitAccepts an integer: maximum number of results to retrieve or -1 for unlimited. Default: site posts_per_page setting.
pageAccepts an integer: page of results to retrieve. Does nothing if 'offset' is used.
offsetAccepts an integer: amount to offset product results.
paginateAccepts a boolean: true for pagination, or false for not. Default: false. If enabled, modifies the return results to give an object with fields: products (array of found products), total (number of found products), and max_num_pages (total number of pages).

Examples

// Get latest 3 products.
$products = wc_get_products( array( 'limit' => 3 ) );
// First 3 products.
$args = array(
'limit' => 3,
'page' => 1,
);
$page_1_products = wc_get_products( $args );

// Second 3 products.
$args = array(
'limit' => 3,
'page' => 2,
);
$page_2_products = wc_get_products( $args );
// Get products with extra info about the results.
$results = wc_get_products( array( 'paginate' => true ) );
echo $results->total . " products found\n";
echo 'Page 1 of ' . $results->max_num_pages . "\n";
if ( count( $results->products ) > 0 ) {
echo 'First product id is: ' . $results->products[0]->get_id() . "\n";
}
// Get second to fifth most-recent products.
$args = array(
'limit' => 4,
'offset' => 1,
);
$products = wc_get_products( $args );

Product lookup

ParameterDescription
skuAccepts a string: product SKU to match on. Does partial matching on the SKU.
nameAccepts a string: the product name (title) to match on. Case sensitivity depends on the collation of the WordPress posts table.
tagAccepts an array: limit results to products assigned to specific tags by slug.
product_tag_idAccepts an integer or array of integers: limit results to products assigned to specific tags by ID.
categoryAccepts an array: limit results to products assigned to specific categories by slug.
product_category_idAccepts an integer or array of integers: limit results to products assigned to specific categories by ID.

Examples

// Get products with "PRDCT" in their SKU (e.g. PRDCT-1 and PRDCT-2).
$products = wc_get_products( array( 'sku' => 'PRDCT' ) );
// Get a product named "Test Product".
$products = wc_get_products( array( 'name' => 'Test Product' ) );
// Get products with the "Excellent" or "Modern" tags.
$products = wc_get_products( array( 'tag' => array( 'excellent', 'modern' ) ) );
// Get products by tag IDs.
$products = wc_get_products( array( 'product_tag_id' => array( 17, 23 ) ) );
// Get shirts.
$products = wc_get_products( array( 'category' => array( 'shirts' ) ) );
// Get products by category IDs.
$products = wc_get_products( array( 'product_category_id' => array( 17, 23 ) ) );

Dimensions & pricing

ParameterDescription
weightAccepts a float: the weight measurement to match on.
lengthAccepts a float: the length measurement to match on.
widthAccepts a float: the width measurement to match on.
heightAccepts a float: the height measurement to match on.
priceAccepts a float: the current price to match on.
regular_priceAccepts a float: the regular price to match on.
sale_priceAccepts a float: the sale price to match on.
total_salesAccepts an integer: gets products with that many sales.

Examples

// Get products 5.5 units wide and 10 units long.
$args = array(
'width' => 5.5,
'length' => 10,
);
$products = wc_get_products( $args );
// Get products that currently cost 9.99.
$products = wc_get_products( array( 'price' => 9.99 ) );
// Get products that have never been purchased.
$products = wc_get_products( array( 'total_sales' => 0 ) );

Product settings

ParameterDescription
virtualAccepts a boolean: limit to virtual products.
downloadableAccepts a boolean: limit to downloadable products.
featuredAccepts a boolean: limit to featured products.
sold_individuallyAccepts a boolean: limit to products sold individually.
manage_stockAccepts a boolean: limit to products with stock management enabled.
reviews_allowedAccepts a boolean: limit to products that allow reviews.
backordersAccepts a string: 'yes', 'no', or 'notify'.
visibilityAccepts a string: 'visible', 'catalog', 'search', or 'hidden'. See CatalogVisibility constant class.
download_limitAccepts an integer: the download limit or -1 for unlimited.
download_expiryAccepts an integer: the download expiry (days) or -1 for unlimited.

Examples

// Get downloadable products that don't allow reviews.
$args = array(
'downloadable' => true,
'reviews_allowed' => false,
);
$products = wc_get_products( $args );
// Get products that allow backorders.
$products = wc_get_products( array( 'backorders' => 'yes' ) );
// Get products that show in the catalog.
$products = wc_get_products( array( 'visibility' => 'catalog' ) );
// Using constant class for visibility.
$products = wc_get_products( array( 'visibility' => \Automattic\WooCommerce\Enums\CatalogVisibility::CATALOG ) );
// Get products with unlimited downloads.
$products = wc_get_products( array( 'download_limit' => -1 ) );

Stock & inventory

ParameterDescription
stock_quantityAccepts an integer: the quantity of a product in stock.
stock_statusAccepts a string: 'outofstock', 'instock', or 'onbackorder'. See ProductStockStatus constant class.

Examples

// Get products that only have one left in stock.
$products = wc_get_products( array( 'stock_quantity' => 1 ) );
// Get out of stock products.
$products = wc_get_products( array( 'stock_status' => 'outofstock' ) );
// Using constant class for stock status.
$products = wc_get_products( array( 'stock_status' => \Automattic\WooCommerce\Enums\ProductStockStatus::OUT_OF_STOCK ) );

Tax & shipping

ParameterDescription
tax_statusAccepts a string: 'taxable', 'shipping', or 'none'. See ProductTaxStatus constant class.
tax_classAccepts a string: a tax class slug.
shipping_classAccepts a string or array of strings: one or more shipping class slugs.

Examples

// Get taxable products.
$products = wc_get_products( array( 'tax_status' => 'taxable' ) );
// Using constant class for tax status.
$products = wc_get_products( array( 'tax_status' => \Automattic\WooCommerce\Enums\ProductTaxStatus::TAXABLE ) );
// Get products in the "Reduced Rate" tax class.
$products = wc_get_products( array( 'tax_class' => 'reduced-rate' ) );
// Get products in the "Bulky" shipping class.
$products = wc_get_products( array( 'shipping_class' => 'bulky' ) );

Reviews & ratings

ParameterDescription
average_ratingAccepts a float: the average rating.
review_countAccepts an integer: the number of reviews.

Examples

// Get products with all 5-star ratings.
$products = wc_get_products( array( 'average_rating' => 5.0 ) );
// Get products with 1 review.
$products = wc_get_products( array( 'review_count' => 1 ) );

Date

Date arguments receive values following the standard format described below, allowing for more flexible queries.

ParameterDescription
date_createdMatches product creation date. Accepts a string in standard format.
date_modifiedMatches product modification date. Accepts a string in standard format.
date_on_sale_fromMatches sale start date. Accepts a string in standard format.
date_on_sale_toMatches sale end date. Accepts a string in standard format.

Standard format

  • YYYY-MM-DD - Matches on products during that one day in site timezone.
  • >YYYY-MM-DD - Matches on products after that one day in site timezone.
  • >=YYYY-MM-DD - Matches on products during or after that one day in site timezone.
  • <YYYY-MM-DD - Matches on products before that one day in site timezone.
  • <=YYYY-MM-DD - Matches on products during or before that one day in site timezone.
  • YYYY-MM-DD...YYYY-MM-DD - Matches on products during or in between the days in site timezone.
  • TIMESTAMP - Matches on products during that one second in UTC timezone.
  • >TIMESTAMP - Matches on products after that one second in UTC timezone.
  • >=TIMESTAMP - Matches on products during or after that one second in UTC timezone.
  • <TIMESTAMP - Matches on products before that one second in UTC timezone.
  • <=TIMESTAMP - Matches on products during or before that one second in UTC timezone.
  • TIMESTAMP...TIMESTAMP - Matches on products during or in between the seconds in UTC timezone.

Examples

// Get downloadable products created in the year 2016.
$products = wc_get_products( array(
'downloadable' => true,
'date_created' => '2016-01-01...2016-12-31',
) );

Adding support for custom parameters

It is possible to add support for custom parameters in wc_get_products() or WC_Product_Query. To do this you need to filter the generated query.

/**
* Handle a custom 'customvar' query var to get products with the 'customvar' meta.
* @param array $query - Args for WP_Query.
* @param array $query_vars - Query vars from WC_Product_Query.
* @return array modified $query
*/
function handle_custom_query_var( $query, $query_vars ) {
if ( ! empty( $query_vars['customvar'] ) ) {
if ( ! isset( $query['meta_query'] ) ) {
$query['meta_query'] = array();
}
$query['meta_query'][] = array(
'key' => 'customvar',
'value' => sanitize_text_field( $query_vars['customvar'] ),
);
}

return $query;
}
add_filter( 'woocommerce_product_data_store_cpt_get_products_query', 'handle_custom_query_var', 10, 2 );

Usage:

$products = wc_get_products( array( 'customvar' => 'somevalue' ) );