Switched implementation of variation query parameters in the API from SQL query adjustment to one extra parent query.
This commit is contained in:
parent
4a42e2a7fc
commit
2839dba7d2
|
@ -258,47 +258,6 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Products_Controller
|
|||
return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update JOIN part of WP_Query with parent table and taxonomies, if needed.
|
||||
*
|
||||
* @param string $join JOIN clause from WP_Query.
|
||||
* @param WP_Query $wp_query WP_Query object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parent_product_taxonomies_query_join( $join, $wp_query ) {
|
||||
global $wpdb;
|
||||
|
||||
// TODO: add some more checks here, probably only run in case one of the following filters are active:
|
||||
// category, prod type, visibility, tag, shipping class, attribute; post_type == product_variation.
|
||||
if ( isset( $wp_query->query_vars['post_parent'] ) && isset( $wp_query->query_vars['meta_query'] )
|
||||
&& isset( $wp_query->query_vars['post_type'] ) && 'product_variation' === $wp_query->query_vars['post_type'] ) {
|
||||
$join .= " LEFT JOIN {$wpdb->posts} AS {$this->parent_product_table_name} ON ({$wpdb->posts}.post_parent = {$this->parent_product_table_name}.ID) ";
|
||||
$join .= $this->clauses['join'];
|
||||
}
|
||||
|
||||
return $join;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update WHERE part of WP_Query to match parent product with taxonomies, if needed.
|
||||
*
|
||||
* @param string $where WHERE clause from WP_Query.
|
||||
* @param WP_Query $wp_query WP_Query object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parent_product_taxonomies_query_where( $where, $wp_query ) {
|
||||
// TODO: add some more checks here, probably only run in case one of the following filters are active:
|
||||
// category, prod type, visibility, tag, shipping class, attribute; post_type == product_variation.
|
||||
if ( isset( $wp_query->query_vars['post_parent'] )
|
||||
&& isset( $wp_query->query_vars['post_type'] ) && 'product_variation' === $wp_query->query_vars['post_type'] ) {
|
||||
$where .= $this->clauses['where'];
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare objects query.
|
||||
*
|
||||
|
@ -310,32 +269,55 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Products_Controller
|
|||
$args = parent::prepare_objects_query( $request );
|
||||
|
||||
$args['post_parent'] = $request['product_id'];
|
||||
// TODO: check if WC_Product_Data_Store_CPT::find_matching_product_variation could not be used...
|
||||
// fix the filtering, otherwise taxonomy is not mapped correctly to variable product.
|
||||
$taxonomies = isset( $args['tax_query'] ) ? $args['tax_query'] : array();
|
||||
// maybe do this only if there are taxonomies as categories etc, not attributes and terms?
|
||||
$query_for_parent = new WP_Query( $args );
|
||||
$query_for_parent->parse_tax_query( $query_for_parent->query_vars );
|
||||
|
||||
$this->clauses = $query_for_parent->tax_query->get_sql( $this->parent_product_table_name, 'ID' );
|
||||
$parent_query = new WC_REST_Products_Controller();
|
||||
$parent_request = clone $request;
|
||||
$parent_request['include'] = array( $request['product_id'] );
|
||||
// Shipping class can be set separately for variations and parent product. Unlike for attributes, the parent
|
||||
// does not have all shipping classes of the variations assigned to it, so the parent filtering should ignore
|
||||
// shipping class.
|
||||
$parent_request['shipping_class'] = '';
|
||||
$query_args = $parent_query->prepare_objects_query( $parent_request );
|
||||
$query_results = $parent_query->get_objects( $query_args );
|
||||
|
||||
// this does not work anyway as these are not assigned to variation.
|
||||
// In case the parent does not fulfil the constraints, no variations should be returned.
|
||||
if ( 0 === $query_results['total'] ) {
|
||||
$args['post_parent'] = 0;
|
||||
}
|
||||
|
||||
// Ignore taxonomy queries, as they were already matched against parent (or will be transformed to meta query
|
||||
// later on).
|
||||
unset( $args['tax_query'] );
|
||||
|
||||
// these properties should filter parent product:
|
||||
// - product_type, _visibility_, cat, tag, shipping_class
|
||||
// this will run a bit later.
|
||||
add_filter( 'posts_where', array( $this, 'parent_product_taxonomies_query_where' ), 10, 2 );
|
||||
add_filter( 'posts_join', array( $this, 'parent_product_taxonomies_query_join' ), 10, 2 );
|
||||
|
||||
$GLOBALS['wpdb']->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||
// These properties needs to be transformed to meta query.
|
||||
// Attributes needs to be transformed to meta query, shipping class to taxonomy.
|
||||
foreach ( $taxonomies as $taxonomy ) {
|
||||
if ( in_array( $taxonomy['taxonomy'], array( 'product_type', 'product_visibility', 'product_cat', 'product_tag', 'product_shipping_class' ), true ) ) {
|
||||
// Ignore taxonomies tied to parent product.
|
||||
if ( in_array( $taxonomy['taxonomy'], array( 'product_type', 'product_visibility', 'product_cat', 'product_tag' ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
// Shipping class can be associated with either the parent or the individual variation.
|
||||
if ( 'product_shipping_class' === $taxonomy['taxonomy'] ) {
|
||||
// If requested shipping class is different from parent's shipping class, it's assigned to variation,
|
||||
// so passing the taxonomy query forward to check against variations.
|
||||
if ( $query_results['total'] > 0 && $taxonomy['terms'][0] !== $query_results['objects'][0]->get_shipping_class_id() ) {
|
||||
$args['tax_query'][] = $taxonomy;
|
||||
continue;
|
||||
} else {
|
||||
// In case the request should to return variations with shipping class equal to parent's shipping class,
|
||||
// there are no records in taxonomy relationship table.
|
||||
$args['tax_query'][] = array(
|
||||
'taxonomy' => 'product_shipping_class',
|
||||
'operator' => 'NOT EXISTS',
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Attributes switched to meta query.
|
||||
if ( 'term_id' === $taxonomy['field'] ) {
|
||||
$terms = wc_get_product_terms( 10, $taxonomy['taxonomy'], array( 'fields' => 'slugs' ) );
|
||||
$terms = wc_get_product_terms( $request['product_id'], $taxonomy['taxonomy'], array( 'fields' => 'slugs' ) );
|
||||
$value = isset( $terms[ $taxonomy['terms'][0] ] ) ? $terms[ $taxonomy['terms'][0] ] : null;
|
||||
} else {
|
||||
$value = $taxonomy['terms'][0];
|
||||
|
|
Loading…
Reference in New Issue