Query and save only IDs of products when fetching products by shortcode

This commit is contained in:
Claudio Sanches 2017-11-16 15:14:36 -02:00
parent 97a1972caa
commit 01983e6b96
2 changed files with 40 additions and 16 deletions

View File

@ -5,7 +5,7 @@
* @author Automattic
* @category Shortcodes
* @package WooCommerce/Shortcodes
* @version 3.2.0
* @version 3.2.4
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -195,7 +195,12 @@ class WC_Shortcode_Products {
// Categories.
$this->set_categories_query_args( $query_args );
return apply_filters( 'woocommerce_shortcode_products_query', $query_args, $this->attributes, $this->type );
$query_args = apply_filters( 'woocommerce_shortcode_products_query', $query_args, $this->attributes, $this->type );
// Always query only IDs.
$query_args['fields'] = 'ids';
return $query_args;
}
/**
@ -450,16 +455,16 @@ class WC_Shortcode_Products {
}
/**
* Get products.
* Get products IDs.
*
* @since 3.2.0
* @return WP_Query
* @since 3.2.4
* @return array
*/
protected function get_products() {
protected function get_products_ids() {
$transient_name = $this->get_transient_name();
$products = get_transient( $transient_name );
$ids = get_transient( $transient_name );
if ( false === $products || ! is_a( $products, 'WP_Query' ) ) {
if ( false === $ids ) {
if ( 'top_rated_products' === $this->type ) {
add_filter( 'posts_clauses', array( __CLASS__, 'order_by_rating_post_clauses' ) );
$products = new WP_Query( $this->query_args );
@ -468,7 +473,9 @@ class WC_Shortcode_Products {
$products = new WP_Query( $this->query_args );
}
set_transient( $transient_name, $products, DAY_IN_SECONDS * 30 );
$ids = wp_parse_id_list( $products->posts );
set_transient( $transient_name, $ids, DAY_IN_SECONDS * 30 );
}
// Remove ordering query arguments.
@ -476,7 +483,7 @@ class WC_Shortcode_Products {
WC()->query->remove_ordering_args();
}
return $products;
return $ids;
}
/**
@ -492,20 +499,23 @@ class WC_Shortcode_Products {
$classes = $this->get_wrapper_classes( $columns );
$woocommerce_loop['columns'] = $columns;
$woocommerce_loop['name'] = $this->type;
$products = $this->get_products();
$products_ids = $this->get_products_ids();
ob_start();
if ( $products->have_posts() ) {
// Prime caches before grabbing objects.
update_post_caches( $products->posts, array( 'product', 'product_variation' ) );
if ( $products_ids ) {
// Prime meta cache to reduce future queries.
update_meta_cache( 'post', $products_ids );
update_object_term_cache( $products_ids, 'product' );
do_action( "woocommerce_shortcode_before_{$this->type}_loop", $this->attributes );
woocommerce_product_loop_start();
while ( $products->have_posts() ) {
$products->the_post();
foreach ( $products_ids as $product_id ) {
$post_object = get_post( $product_id );
$GLOBALS['post'] =& $post_object; // WPCS: override ok.
setup_postdata( $post_object );
// Set custom product visibility when quering hidden products.
add_action( 'woocommerce_product_is_visible', array( $this, 'set_product_as_visible' ) );

View File

@ -70,6 +70,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'posts_per_page' => -1,
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'fields' => 'ids',
);
$this->assertEquals( $expected, $shortcode->get_query_args() );
@ -88,6 +89,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'posts_per_page' => -1,
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'fields' => 'ids',
);
$this->assertEquals( $expected2, $shortcode2->get_query_args() );
@ -106,6 +108,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'post__in' => array( '1', '2', '3' ),
'fields' => 'ids',
);
$expected3['meta_query'][] = array(
'key' => '_sku',
@ -135,6 +138,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'meta_key' => '',
'fields' => 'ids',
);
$expected4['tax_query'][] = array(
'taxonomy' => 'product_cat',
@ -164,6 +168,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'posts_per_page' => 12,
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'fields' => 'ids',
);
$this->assertEquals( $expected5, $shortcode5->get_query_args() );
@ -184,6 +189,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'p' => '1',
'fields' => 'ids',
);
$this->assertEquals( $expected6, $shortcode6->get_query_args() );
@ -208,6 +214,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'post__in' => array_merge( array( 0 ), wc_get_product_ids_on_sale() ),
'fields' => 'ids',
);
$this->assertEquals( $expected7, $shortcode7->get_query_args() );
@ -230,6 +237,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'meta_key' => 'total_sales',
'fields' => 'ids',
);
$this->assertEquals( $expected8, $shortcode8->get_query_args() );
@ -253,6 +261,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'posts_per_page' => 12,
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'fields' => 'ids',
);
$this->assertEquals( $expected9, $shortcode9->get_query_args() );
@ -285,6 +294,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'include_children' => false,
),
) ),
'fields' => 'ids',
);
$this->assertEquals( $expected10, $shortcode10->get_query_args() );
@ -315,6 +325,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'operator' => 'IN',
),
) ),
'fields' => 'ids',
);
$this->assertEquals( $expected11, $shortcode11->get_query_args() );
@ -341,6 +352,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'include_children' => false,
),
),
'fields' => 'ids',
);
$this->assertEquals( $expected12, $shortcode12->get_query_args() );
@ -373,6 +385,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'include_children' => false,
),
),
'fields' => 'ids',
);
$this->assertEquals( $expected13, $shortcode13->get_query_args() );
@ -405,6 +418,7 @@ class WC_Test_Shortcode_Products extends WC_Unit_Test_Case {
'include_children' => false,
),
),
'fields' => 'ids',
);
$this->assertEquals( $expected14, $shortcode14->get_query_args() );