Introduce transient caching to grid block queries (https://github.com/woocommerce/woocommerce-blocks/pull/605)
* Utlise WC Query to handle sorting rather than setting query args manually * Implement transient caching
This commit is contained in:
parent
75ec6a48c2
commit
3a73be7dbb
|
@ -36,13 +36,6 @@ abstract class WGPB_Block_Grid_Base {
|
|||
*/
|
||||
protected $content = '';
|
||||
|
||||
/**
|
||||
* Query args.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $query_args = array();
|
||||
|
||||
/**
|
||||
* Initialize block.
|
||||
*
|
||||
|
@ -52,7 +45,6 @@ abstract class WGPB_Block_Grid_Base {
|
|||
public function __construct( $attributes = array(), $content = '' ) {
|
||||
$this->attributes = $this->parse_attributes( $attributes );
|
||||
$this->content = $content;
|
||||
$this->query_args = $this->parse_query_args();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,63 +68,15 @@ abstract class WGPB_Block_Grid_Base {
|
|||
),
|
||||
);
|
||||
|
||||
return wp_parse_args( $attributes, $defaults );
|
||||
}
|
||||
$attributes = wp_parse_args( $attributes, $defaults );
|
||||
|
||||
/**
|
||||
* Parse query args.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parse_query_args() {
|
||||
$query_args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'publish',
|
||||
'ignore_sticky_posts' => true,
|
||||
'no_found_rows' => false,
|
||||
'orderby' => '',
|
||||
'order' => '',
|
||||
);
|
||||
|
||||
if ( isset( $this->attributes['orderby'] ) ) {
|
||||
if ( 'price_desc' === $this->attributes['orderby'] ) {
|
||||
$query_args['orderby'] = 'price';
|
||||
$query_args['order'] = 'DESC';
|
||||
} elseif ( 'price_asc' === $this->attributes['orderby'] ) {
|
||||
$query_args['orderby'] = 'price';
|
||||
$query_args['order'] = 'ASC';
|
||||
} elseif ( 'date' === $this->attributes['orderby'] ) {
|
||||
$query_args['orderby'] = 'date';
|
||||
$query_args['order'] = 'DESC';
|
||||
} else {
|
||||
$query_args['orderby'] = $this->attributes['orderby'];
|
||||
}
|
||||
if ( ! empty( $attributes['rows'] ) && ! empty( $attributes['columns'] ) ) {
|
||||
$attributes['limit'] = intval( $attributes['columns'] ) * intval( $attributes['rows'] );
|
||||
} else {
|
||||
$attributes['limit'] = -1;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->attributes['rows'] ) ) {
|
||||
$this->attributes['limit'] = intval( $this->attributes['columns'] ) * intval( $this->attributes['rows'] );
|
||||
}
|
||||
|
||||
$query_args['posts_per_page'] = intval( $this->attributes['limit'] );
|
||||
$query_args['meta_query'] = WC()->query->get_meta_query(); // phpcs:ignore WordPress.DB.SlowDBQuery
|
||||
$query_args['tax_query'] = array(); // phpcs:ignore WordPress.DB.SlowDBQuery
|
||||
|
||||
$this->set_block_query_args( $query_args );
|
||||
|
||||
$ordering_args = WC()->query->get_catalog_ordering_args( $query_args['orderby'], $query_args['order'] );
|
||||
$query_args['orderby'] = $ordering_args['orderby'];
|
||||
$query_args['order'] = $ordering_args['order'];
|
||||
if ( $ordering_args['meta_key'] ) {
|
||||
$query_args['meta_key'] = $ordering_args['meta_key']; // phpcs:ignore WordPress.DB.SlowDBQuery
|
||||
}
|
||||
|
||||
// Categories.
|
||||
$this->set_categories_query_args( $query_args );
|
||||
|
||||
// Always query only IDs.
|
||||
$query_args['fields'] = 'ids';
|
||||
|
||||
return $query_args;
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,6 +86,31 @@ abstract class WGPB_Block_Grid_Base {
|
|||
*/
|
||||
abstract protected function set_block_query_args( &$query_args );
|
||||
|
||||
/**
|
||||
* Set orderby/order query args.
|
||||
*
|
||||
* @param array $query_args Query args.
|
||||
*/
|
||||
protected function set_ordering_query_args( &$query_args ) {
|
||||
$orderby = '';
|
||||
$order = '';
|
||||
|
||||
if ( isset( $this->attributes['orderby'] ) ) {
|
||||
if ( 'price_desc' === $this->attributes['orderby'] ) {
|
||||
$orderby = 'price';
|
||||
$order = 'DESC';
|
||||
} elseif ( 'price_asc' === $this->attributes['orderby'] ) {
|
||||
$orderby = 'price';
|
||||
$order = 'ASC';
|
||||
} else {
|
||||
$orderby = $this->attributes['orderby'];
|
||||
}
|
||||
}
|
||||
|
||||
// This handles orderby queries and hooks in custom orderby functions.
|
||||
$query_args = array_merge( $query_args, WC()->query->get_catalog_ordering_args( $orderby, $order ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set categories query args.
|
||||
*
|
||||
|
@ -149,8 +118,7 @@ abstract class WGPB_Block_Grid_Base {
|
|||
*/
|
||||
protected function set_categories_query_args( &$query_args ) {
|
||||
if ( ! empty( $this->attributes['categories'] ) ) {
|
||||
$categories = array_map( 'absint', $this->attributes['categories'] );
|
||||
|
||||
$categories = array_map( 'absint', $this->attributes['categories'] );
|
||||
$query_args['tax_query'][] = array(
|
||||
'taxonomy' => 'product_cat',
|
||||
'terms' => $categories,
|
||||
|
@ -166,30 +134,60 @@ abstract class WGPB_Block_Grid_Base {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all product query args for WP_Query.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_products_query_args() {
|
||||
$query_args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'publish',
|
||||
'fields' => 'ids',
|
||||
'ignore_sticky_posts' => true,
|
||||
'no_found_rows' => false,
|
||||
'posts_per_page' => intval( $this->attributes['limit'] ),
|
||||
'tax_query' => array(), // phpcs:ignore WordPress.DB.SlowDBQuery
|
||||
'meta_query' => array(), // phpcs:ignore WordPress.DB.SlowDBQuery
|
||||
);
|
||||
$this->set_ordering_query_args( $query_args );
|
||||
$this->set_categories_query_args( $query_args );
|
||||
$this->set_block_query_args( $query_args );
|
||||
|
||||
return $query_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the query and return an array of product IDs
|
||||
*
|
||||
* @return array List of product IDs
|
||||
*/
|
||||
protected function get_products() {
|
||||
if ( 'product-top-rated' === $this->block_name ) {
|
||||
add_filter( 'posts_clauses', array( WC()->query, 'order_by_rating_post_clauses' ) );
|
||||
$query = new WP_Query( $this->query_args );
|
||||
remove_filter( 'posts_clauses', array( WC()->query, 'order_by_rating_post_clauses' ) );
|
||||
} else {
|
||||
$query = new WP_Query( $this->query_args );
|
||||
}
|
||||
$query_hash = md5( wp_json_encode( $this->attributes ) . __CLASS__ );
|
||||
$transient_name = 'wc_block_' . $query_hash;
|
||||
$transient_value = get_transient( $transient_name );
|
||||
$transient_version = WC_Cache_Helper::get_transient_version( 'product_query' );
|
||||
|
||||
$results = wp_parse_id_list( $query->posts );
|
||||
if ( isset( $transient_value['value'], $transient_value['version'] ) && $transient_value['version'] === $transient_version ) {
|
||||
$results = $transient_value['value'];
|
||||
} else {
|
||||
$query = new WP_Query( $this->get_products_query_args() );
|
||||
$results = wp_parse_id_list( $query->posts );
|
||||
$transient_value = array(
|
||||
'version' => $transient_version,
|
||||
'value' => $results,
|
||||
);
|
||||
set_transient( $transient_name, $transient_value, DAY_IN_SECONDS * 30 );
|
||||
|
||||
// Remove ordering query arguments which may have been added by get_catalog_ordering_args.
|
||||
WC()->query->remove_ordering_args();
|
||||
}
|
||||
|
||||
// Prime caches to reduce future queries.
|
||||
if ( is_callable( '_prime_post_caches' ) ) {
|
||||
_prime_post_caches( $results );
|
||||
}
|
||||
|
||||
// Remove ordering query arguments which may have been added by get_catalog_ordering_args.
|
||||
WC()->query->remove_ordering_args();
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,14 +22,25 @@ class WGPB_Block_Product_Best_Sellers extends WGPB_Block_Grid_Base {
|
|||
*/
|
||||
protected $block_name = 'product-best-sellers';
|
||||
|
||||
/**
|
||||
* Get the block's attributes.
|
||||
*
|
||||
* @param array $attributes Block attributes. Default empty array.
|
||||
* @return array Block attributes merged with defaults.
|
||||
*/
|
||||
protected function parse_attributes( $attributes ) {
|
||||
$attributes = parent::parse_attributes( $attributes );
|
||||
|
||||
// Force orderby to popularity.
|
||||
$attributes['orderby'] = 'popularity';
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set args specific to this block
|
||||
*
|
||||
* @param array $query_args Query args.
|
||||
*/
|
||||
protected function set_block_query_args( &$query_args ) {
|
||||
$query_args['meta_key'] = 'total_sales'; // phpcs:ignore WordPress.DB.SlowDBQuery
|
||||
$query_args['order'] = 'DESC';
|
||||
$query_args['orderby'] = 'meta_value_num';
|
||||
}
|
||||
protected function set_block_query_args( &$query_args ) {}
|
||||
}
|
||||
|
|
|
@ -22,13 +22,25 @@ class WGPB_Block_Product_New extends WGPB_Block_Grid_Base {
|
|||
*/
|
||||
protected $block_name = 'product-new';
|
||||
|
||||
/**
|
||||
* Get the block's attributes.
|
||||
*
|
||||
* @param array $attributes Block attributes. Default empty array.
|
||||
* @return array Block attributes merged with defaults.
|
||||
*/
|
||||
protected function parse_attributes( $attributes ) {
|
||||
$attributes = parent::parse_attributes( $attributes );
|
||||
|
||||
// Force orderby to date.
|
||||
$attributes['orderby'] = 'date';
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set args specific to this block
|
||||
*
|
||||
* @param array $query_args Query args.
|
||||
*/
|
||||
protected function set_block_query_args( &$query_args ) {
|
||||
$query_args['orderby'] = 'date';
|
||||
$query_args['order'] = 'DESC';
|
||||
}
|
||||
protected function set_block_query_args( &$query_args ) {}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,22 @@ class WGPB_Block_Product_Top_Rated extends WGPB_Block_Grid_Base {
|
|||
protected $block_name = 'product-top-rated';
|
||||
|
||||
/**
|
||||
* This function is not necessary in this block.
|
||||
* Get the block's attributes.
|
||||
*
|
||||
* @param array $attributes Block attributes. Default empty array.
|
||||
* @return array Block attributes merged with defaults.
|
||||
*/
|
||||
protected function parse_attributes( $attributes ) {
|
||||
$attributes = parent::parse_attributes( $attributes );
|
||||
|
||||
// Force orderby to rating.
|
||||
$attributes['orderby'] = 'rating';
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set args specific to this block
|
||||
*
|
||||
* @param array $query_args Query args.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue