Merge pull request #12214 from woocommerce/product-crud-wc_get_products
[Product CRUD] Add a wc_get_products wrapper
This commit is contained in:
commit
b037108c93
|
@ -14,6 +14,153 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* Products wrapper for get_posts.
|
||||
*
|
||||
* This function should be used for product retrieval so that we have a data agnostic
|
||||
* way to get a list of products.
|
||||
*
|
||||
* Args:
|
||||
* status array|string List of statuses to find. Default: any. Options: any, draft, pending, private and publish.
|
||||
* type array|string Product type, e.g. Default: all. Options: all, simple, external, variable, variation, grouped.
|
||||
* parent int post/product parent
|
||||
* skus array Limit result set to products with specific SKUs.
|
||||
* categories array Limit result set to products assigned a specific category, e.g. 9,14.
|
||||
* tags array Limit result set to products assigned a specific tag, e.g. 9,14.
|
||||
* limit int Maximum of products to retrieve.
|
||||
* offset int Offset of products to retrieve.
|
||||
* page int Page of products to retrieve. Ignored when using the 'offset' arg.
|
||||
* exclude array Product IDs to exclude from the query.
|
||||
* orderby string Order by date, title, id, modified, rand etc
|
||||
* order string ASC or DESC
|
||||
* return string Type of data to return. Allowed values:
|
||||
* ids array of Product ids
|
||||
* objects array of product objects (default)
|
||||
* paginate bool If true, the return value will be an array with values:
|
||||
* 'products' => array of data (return value above),
|
||||
* 'total' => total number of products matching the query
|
||||
* 'max_num_pages' => max number of pages found
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param array $args Array of args (above)
|
||||
* @return array|stdClass Number of pages and an array of product objects if
|
||||
* paginate is true, or just an array of values.
|
||||
*/
|
||||
function wc_get_products( $args ) {
|
||||
$args = wp_parse_args( $args, array(
|
||||
'status' => array( 'draft', 'pending', 'private', 'publish' ),
|
||||
'type' => array_merge( array_keys( wc_get_product_types() ), array( 'variation' ) ),
|
||||
'parent' => null,
|
||||
'sku' => '',
|
||||
'category' => array(),
|
||||
'tag' => array(),
|
||||
'limit' => get_option( 'posts_per_page' ),
|
||||
'offset' => null,
|
||||
'page' => 1,
|
||||
'exclude' => array(),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'return' => 'objects',
|
||||
'paginate' => false,
|
||||
) );
|
||||
|
||||
// Handle some BW compatibility arg names where wp_query args differ in naming.
|
||||
$map_legacy = array(
|
||||
'numberposts' => 'limit',
|
||||
'post_status' => 'status',
|
||||
'post_parent' => 'parent',
|
||||
'posts_per_page' => 'limit',
|
||||
'paged' => 'page',
|
||||
);
|
||||
|
||||
foreach ( $map_legacy as $from => $to ) {
|
||||
if ( isset( $args[ $from ] ) ) {
|
||||
$args[ $to ] = $args[ $from ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate WP_Query args.
|
||||
*/
|
||||
$wp_query_args = array(
|
||||
'post_type' => array( 'product', 'product_variation' ),
|
||||
'post_status' => $args['status'],
|
||||
'posts_per_page' => $args['limit'],
|
||||
'meta_query' => array(),
|
||||
'fields' => 'ids',
|
||||
'orderby' => $args['orderby'],
|
||||
'order' => $args['order'],
|
||||
'tax_query' => array(
|
||||
array(
|
||||
'taxonomy' => 'product_type',
|
||||
'field' => 'slug',
|
||||
'terms' => $args['type'],
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! empty( $args['sku'] ) ) {
|
||||
$wp_query_args['meta_query'][] = array(
|
||||
'key' => '_sku',
|
||||
'value' => $args['sku'],
|
||||
'compare' => 'LIKE',
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $args['category'] ) ) {
|
||||
$wp_query_args['tax_query'][] = array(
|
||||
'taxonomy' => 'product_cat',
|
||||
'field' => 'term_id',
|
||||
'terms' => $args['category'],
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $args['tag'] ) ) {
|
||||
$wp_query_args['tax_query'][] = array(
|
||||
'taxonomy' => 'product_tag',
|
||||
'field' => 'term_id',
|
||||
'terms' => $args['tag'],
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! is_null( $args['parent'] ) ) {
|
||||
$wp_query_args['post_parent'] = absint( $args['parent'] );
|
||||
}
|
||||
|
||||
if ( ! is_null( $args['offset'] ) ) {
|
||||
$wp_query_args['offset'] = absint( $args['offset'] );
|
||||
} else {
|
||||
$wp_query_args['paged'] = absint( $args['page'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $args['exclude'] ) ) {
|
||||
$wp_query_args['post__not_in'] = array_map( 'absint', $args['exclude'] );
|
||||
}
|
||||
|
||||
if ( ! $args['paginate'] ) {
|
||||
$wp_query_args['no_found_rows'] = true;
|
||||
}
|
||||
|
||||
// Get results.
|
||||
$products = new WP_Query( $wp_query_args );
|
||||
|
||||
if ( 'objects' === $args['return'] ) {
|
||||
$return = array_map( 'wc_get_product', $products->posts );
|
||||
} else {
|
||||
$return = $products->posts;
|
||||
}
|
||||
|
||||
if ( $args['paginate'] ) {
|
||||
return (object) array(
|
||||
'products' => $return,
|
||||
'total' => $products->found_posts,
|
||||
'max_num_pages' => $procuts->max_num_pages,
|
||||
);
|
||||
} else {
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function for returning products, uses the WC_Product_Factory class.
|
||||
*
|
||||
|
|
|
@ -7,6 +7,103 @@
|
|||
*/
|
||||
class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
|
||||
|
||||
/**
|
||||
* Tests wc_get_products().
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_wc_get_products() {
|
||||
$test_cat_1 = wp_insert_term( 'Testing 1', 'product_cat' );
|
||||
$test_tag_1 = wp_insert_term( 'Tag 1', 'product_tag' );
|
||||
$test_tag_2 = wp_insert_term( 'Tag 2', 'product_tag' );
|
||||
|
||||
$product = WC_Helper_Product::create_simple_product();
|
||||
$product->set_tag_ids( array( $test_tag_1['term_id'] ) );
|
||||
$product->set_category_ids( array( $test_cat_1['term_id'] ) );
|
||||
$product->set_sku( 'GET TEST SKU SIMPLE' );
|
||||
$product->save();
|
||||
|
||||
$product_2 = WC_Helper_Product::create_simple_product();
|
||||
$product_2->set_category_ids( array( $test_cat_1['term_id'] ) );
|
||||
$product_2->save();
|
||||
|
||||
$external = WC_Helper_Product::create_simple_product();
|
||||
$external->set_category_ids( array( $test_cat_1['term_id'] ) );
|
||||
$external->set_sku( 'GET TEST SKU EXTERNAL' );
|
||||
$external->save();
|
||||
|
||||
$external_2 = WC_Helper_Product::create_simple_product();
|
||||
$external_2->set_tag_ids( array( $test_tag_2['term_id'] ) );
|
||||
$external_2->save();
|
||||
|
||||
$grouped = WC_Helper_Product::create_grouped_product();
|
||||
|
||||
$variation = WC_Helper_Product::create_variation_product();
|
||||
$variation->set_tag_ids( array( $test_tag_1['term_id'] ) );
|
||||
$variation->save();
|
||||
|
||||
$draft = WC_Helper_Product::create_simple_product();
|
||||
$draft->set_status( 'draft' );
|
||||
$draft->save();
|
||||
|
||||
$this->assertEquals( 10, count( wc_get_products( array( 'return' => 'ids' ) ) ) );
|
||||
|
||||
// test status
|
||||
$products = wc_get_products( array( 'return' => 'ids', 'status' => 'draft' ) );
|
||||
$this->assertEquals( array( $draft->get_id() ), $products );
|
||||
|
||||
// test type
|
||||
$products = wc_get_products( array( 'return' => 'ids', 'type' => array( 'variable', 'variation' ) ) );
|
||||
$this->assertEquals( 3, count( $products ) );
|
||||
$this->assertContains( $variation->get_id(), $products );
|
||||
|
||||
// test parent
|
||||
$products = wc_get_products( array( 'return' => 'ids', 'parent' => $variation->get_id() ) );
|
||||
$this->assertEquals( 2, count( $products ) );
|
||||
|
||||
// test skus
|
||||
$products = wc_get_products( array( 'return' => 'ids', 'sku' => 'GET TEST SKU' ) );
|
||||
$this->assertEquals( 2, count( $products ) );
|
||||
$this->assertContains( $product->get_id(), $products );
|
||||
$this->assertContains( $external->get_id(), $products );
|
||||
|
||||
// test categories
|
||||
$products = wc_get_products( array( 'return' => 'ids', 'category' => array( $test_cat_1['term_id'] ) ) );
|
||||
$this->assertEquals( 3, count( $products ) );
|
||||
|
||||
// test tags
|
||||
$products = wc_get_products( array( 'return' => 'ids', 'tag' => array( $test_tag_1['term_id'] ) ) );
|
||||
$this->assertEquals( 2, count( $products ) );
|
||||
|
||||
$products = wc_get_products( array( 'return' => 'ids', 'tag' => array( $test_tag_2['term_id'] ) ) );
|
||||
$this->assertEquals( 1, count( $products ) );
|
||||
|
||||
$products = wc_get_products( array( 'return' => 'ids', 'tag' => array( $test_tag_1['term_id'], $test_tag_2['term_id'] ) ) );
|
||||
$this->assertEquals( 3, count( $products ) );
|
||||
|
||||
// test limit
|
||||
$products = wc_get_products( array( 'return' => 'ids', 'limit' => 5 ) );
|
||||
$this->assertEquals( 5, count( $products ) );
|
||||
|
||||
// test offset
|
||||
$products = wc_get_products( array( 'return' => 'ids', 'limit' => 5 ) );
|
||||
$products_offset = wc_get_products( array( 'return' => 'ids', 'limit' => 5, 'offset' => 5 ) );
|
||||
$this->assertEquals( 5, count( $products ) );
|
||||
$this->assertEquals( 5, count( $products_offset ) );
|
||||
$this->assertNotEquals( $products, $products_offset );
|
||||
|
||||
// test page
|
||||
$products_page_1 = wc_get_products( array( 'return' => 'ids', 'limit' => 5 ) );
|
||||
$products_page_2 = wc_get_products( array( 'return' => 'ids', 'limit' => 5, 'page' => 2 ) );
|
||||
$this->assertEquals( 5, count( $products_page_1 ) );
|
||||
$this->assertEquals( 5, count( $products_page_2 ) );
|
||||
$this->assertNotEquals( $products_page_1, $products_page_2 );
|
||||
|
||||
// test exclude
|
||||
$products = wc_get_products( array( 'return' => 'ids', 'limit' => 200, 'exclude' => array( $product->get_id() ) ) );
|
||||
$this->assertNotContains( $product->get_id(), $products );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test wc_get_product().
|
||||
*
|
||||
|
@ -17,12 +114,12 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
|
|||
// Create product
|
||||
$product = WC_Helper_Product::create_simple_product();
|
||||
|
||||
$product_copy = wc_get_product( $product->id );
|
||||
$product_copy = wc_get_product( $product->get_id() );
|
||||
|
||||
$this->assertEquals( $product->id, $product_copy->id );
|
||||
$this->assertEquals( $product->get_id(), $product_copy->get_id() );
|
||||
|
||||
// Delete Product
|
||||
WC_Helper_Product::delete_product( $product->id );
|
||||
WC_Helper_Product::delete_product( $product->get_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,13 +131,15 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
|
|||
// Create product
|
||||
$product = WC_Helper_Product::create_simple_product();
|
||||
|
||||
update_post_meta( $product->id, '_manage_stock', 'yes' );
|
||||
update_post_meta( $product->get_id(), '_manage_stock', 'yes' );
|
||||
|
||||
wc_update_product_stock( $product->id, 5 );
|
||||
$this->assertEquals( 5, $product->stock );
|
||||
wc_update_product_stock( $product->get_id(), 5 );
|
||||
|
||||
$product = new WC_Product_Simple( $product->get_id() );
|
||||
$this->assertEquals( 5, $product->get_stock_quantity() );
|
||||
|
||||
// Delete Product
|
||||
WC_Helper_Product::delete_product( $product->id );
|
||||
WC_Helper_Product::delete_product( $product->get_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,10 +151,10 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
|
|||
// Create product
|
||||
$product = WC_Helper_Product::create_simple_product();
|
||||
|
||||
update_post_meta( $product->id, '_regular_price', wc_format_decimal( 10 ) );
|
||||
update_post_meta( $product->id, '_price', wc_format_decimal( 5 ) );
|
||||
update_post_meta( $product->id, '_sale_price', wc_format_decimal( 5 ) );
|
||||
update_post_meta( $product->id, '_featured', 'yes' );
|
||||
update_post_meta( $product->get_id(), '_regular_price', wc_format_decimal( 10 ) );
|
||||
update_post_meta( $product->get_id(), '_price', wc_format_decimal( 5 ) );
|
||||
update_post_meta( $product->get_id(), '_sale_price', wc_format_decimal( 5 ) );
|
||||
update_post_meta( $product->get_id(), '_featured', 'yes' );
|
||||
|
||||
wc_get_product_ids_on_sale(); // Creates the transient for on sale products
|
||||
wc_get_featured_product_ids(); // Creates the transient for featured products
|
||||
|
@ -65,7 +164,7 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
|
|||
$this->assertFalse( get_transient( 'wc_products_onsale' ) );
|
||||
$this->assertFalse( get_transient( 'wc_featured_products' ) );
|
||||
|
||||
WC_Helper_Product::delete_product( $product->id );
|
||||
WC_Helper_Product::delete_product( $product->get_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,14 +180,14 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
|
|||
// Create product
|
||||
$product = WC_Helper_Product::create_simple_product();
|
||||
|
||||
update_post_meta( $product->id, '_regular_price', wc_format_decimal( 10 ) );
|
||||
update_post_meta( $product->id, '_price', wc_format_decimal( 5 ) );
|
||||
update_post_meta( $product->id, '_sale_price', wc_format_decimal( 5 ) );
|
||||
update_post_meta( $product->get_id(), '_regular_price', wc_format_decimal( 10 ) );
|
||||
update_post_meta( $product->get_id(), '_price', wc_format_decimal( 5 ) );
|
||||
update_post_meta( $product->get_id(), '_sale_price', wc_format_decimal( 5 ) );
|
||||
|
||||
$this->assertEquals( array( $product->id ), wc_get_product_ids_on_sale() );
|
||||
$this->assertEquals( array( $product->get_id() ), wc_get_product_ids_on_sale() );
|
||||
|
||||
// Delete Product
|
||||
WC_Helper_Product::delete_product( $product->id );
|
||||
WC_Helper_Product::delete_product( $product->get_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,12 +203,12 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
|
|||
// Create product
|
||||
$product = WC_Helper_Product::create_simple_product();
|
||||
|
||||
update_post_meta( $product->id, '_featured', 'yes' );
|
||||
update_post_meta( $product->get_id(), '_featured', 'yes' );
|
||||
|
||||
$this->assertEquals( array( $product->id ), wc_get_featured_product_ids() );
|
||||
$this->assertEquals( array( $product->get_id() ), wc_get_featured_product_ids() );
|
||||
|
||||
// Delete Product
|
||||
WC_Helper_Product::delete_product( $product->id );
|
||||
WC_Helper_Product::delete_product( $product->get_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,16 +256,20 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
|
|||
public function test_wc_product_has_unique_sku() {
|
||||
$product_1 = WC_Helper_Product::create_simple_product();
|
||||
|
||||
$this->assertEquals( true, wc_product_has_unique_sku( $product_1->id, $product_1->sku ) );
|
||||
$this->assertEquals( true, wc_product_has_unique_sku( $product_1->get_id(), $product_1->get_sku() ) );
|
||||
|
||||
$product_2 = WC_Helper_Product::create_simple_product();
|
||||
$this->assertEquals( false, wc_product_has_unique_sku( $product_2->id, $product_2->sku ) );
|
||||
// we need to manually set a sku, because WC_Product now uses wc_product_has_unique_sku before setting
|
||||
// so we need to manually set it to test the functionality.
|
||||
update_post_meta( $product_2->get_id(), '_sku', $product_1->get_sku() );
|
||||
|
||||
WC_Helper_Product::delete_product( $product_1->id );
|
||||
$this->assertEquals( false, wc_product_has_unique_sku( $product_2->get_id(), $product_1->get_sku() ) );
|
||||
|
||||
$this->assertEquals( true, wc_product_has_unique_sku( $product_2->id, $product_2->sku ) );
|
||||
WC_Helper_Product::delete_product( $product_1->get_id() );
|
||||
|
||||
WC_Helper_Product::delete_product( $product_2->id );
|
||||
$this->assertEquals( true, wc_product_has_unique_sku( $product_2->get_id(), $product_2->get_sku() ) );
|
||||
|
||||
WC_Helper_Product::delete_product( $product_2->get_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -178,9 +281,9 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
|
|||
// Create product
|
||||
$product = WC_Helper_Product::create_simple_product();
|
||||
|
||||
$this->assertEquals( $product->id, wc_get_product_id_by_sku( $product->sku ) );
|
||||
$this->assertEquals( $product->get_id(), wc_get_product_id_by_sku( $product->get_sku() ) );
|
||||
|
||||
// Delete Product
|
||||
WC_Helper_Product::delete_product( $product->id );
|
||||
WC_Helper_Product::delete_product( $product->get_id() );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue