Refactor `ProductQuery::merge_queries` to accept multiple queries (https://github.com/woocommerce/woocommerce-blocks/pull/7697)
This commit is contained in:
parent
58423a2025
commit
653e838d79
|
@ -48,6 +48,13 @@ class ProductQuery extends AbstractBlock {
|
|||
*/
|
||||
protected $is_custom_inherit_global_query_implementation_enabled = false;
|
||||
|
||||
/**
|
||||
* All query args from WP_Query.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $valid_query_vars;
|
||||
|
||||
/**
|
||||
* Initialize this block type.
|
||||
*
|
||||
|
@ -186,42 +193,17 @@ class ProductQuery extends AbstractBlock {
|
|||
* @return array
|
||||
*/
|
||||
private function merge_queries( ...$queries ) {
|
||||
$valid_query_vars = array_keys( ( new WP_Query() )->fill_query_vars( array() ) );
|
||||
$valid_query_vars = array_merge(
|
||||
$valid_query_vars,
|
||||
// fill_query_vars doesn't include these vars so we need to add them manually.
|
||||
array(
|
||||
'date_query',
|
||||
'exact',
|
||||
'ignore_sticky_posts',
|
||||
'lazy_load_term_meta',
|
||||
'meta_compare_key',
|
||||
'meta_compare',
|
||||
'meta_query',
|
||||
'meta_type_key',
|
||||
'meta_type',
|
||||
'nopaging',
|
||||
'offset',
|
||||
'order',
|
||||
'orderby',
|
||||
'page',
|
||||
'post_type',
|
||||
'posts_per_page',
|
||||
'suppress_filters',
|
||||
'tax_query',
|
||||
)
|
||||
);
|
||||
|
||||
$merged_query = array_reduce(
|
||||
$queries,
|
||||
function( $acc, $query ) use ( $valid_query_vars ) {
|
||||
function( $acc, $query ) {
|
||||
if ( ! is_array( $query ) ) {
|
||||
return $acc;
|
||||
}
|
||||
if ( empty( array_intersect( $valid_query_vars, array_keys( $query ) ) ) ) {
|
||||
// If the $query doesn't contain any valid query keys, we unpack/spread it then merge.
|
||||
if ( empty( array_intersect( $this->get_valid_query_vars(), array_keys( $query ) ) ) ) {
|
||||
return $this->merge_queries( $acc, ...array_values( $query ) );
|
||||
}
|
||||
return array_merge_recursive( $acc, $query );
|
||||
return $this->array_merge_recursive_replace_non_array_properties( $acc, $query );
|
||||
},
|
||||
array()
|
||||
);
|
||||
|
@ -450,9 +432,11 @@ class ProductQuery extends AbstractBlock {
|
|||
|
||||
return array(
|
||||
'meta_query' => array(
|
||||
'relation' => 'AND',
|
||||
$max_price_query,
|
||||
$min_price_query,
|
||||
array(
|
||||
'relation' => 'AND',
|
||||
$max_price_query,
|
||||
$min_price_query,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -499,8 +483,10 @@ class ProductQuery extends AbstractBlock {
|
|||
|
||||
return array(
|
||||
'tax_query' => array(
|
||||
'relation' => 'AND',
|
||||
$queries,
|
||||
array(
|
||||
'relation' => 'AND',
|
||||
$queries,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -542,6 +528,112 @@ class ProductQuery extends AbstractBlock {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return or initialize $valid_query_vars.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_valid_query_vars() {
|
||||
if ( ! empty( $this->valid_query_vars ) ) {
|
||||
return $this->valid_query_vars;
|
||||
}
|
||||
|
||||
$valid_query_vars = array_keys( ( new WP_Query() )->fill_query_vars( array() ) );
|
||||
$this->valid_query_vars = array_merge(
|
||||
$valid_query_vars,
|
||||
// fill_query_vars doesn't include these vars so we need to add them manually.
|
||||
array(
|
||||
'date_query',
|
||||
'exact',
|
||||
'ignore_sticky_posts',
|
||||
'lazy_load_term_meta',
|
||||
'meta_compare_key',
|
||||
'meta_compare',
|
||||
'meta_query',
|
||||
'meta_type_key',
|
||||
'meta_type',
|
||||
'nopaging',
|
||||
'offset',
|
||||
'order',
|
||||
'orderby',
|
||||
'page',
|
||||
'post_type',
|
||||
'posts_per_page',
|
||||
'suppress_filters',
|
||||
'tax_query',
|
||||
)
|
||||
);
|
||||
|
||||
return $this->valid_query_vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge two array recursively but replace the non-array values instead of
|
||||
* merging them. The merging strategy:
|
||||
*
|
||||
* - If keys from merge array doesn't exist in the base array, create them.
|
||||
* - For array items with numeric keys, we merge them as normal.
|
||||
* - For array items with string keys:
|
||||
*
|
||||
* - If the value isn't array, we'll use the value comming from the merge array.
|
||||
* $base = ['orderby' => 'date']
|
||||
* $new = ['orderby' => 'meta_value_num']
|
||||
* Result: ['orderby' => 'meta_value_num']
|
||||
*
|
||||
* - If the value is array, we'll use recursion to merge each key.
|
||||
* $base = ['meta_query' => [
|
||||
* [
|
||||
* 'key' => '_stock_status',
|
||||
* 'compare' => 'IN'
|
||||
* 'value' => ['instock', 'onbackorder']
|
||||
* ]
|
||||
* ]]
|
||||
* $new = ['meta_query' => [
|
||||
* [
|
||||
* 'relation' => 'AND',
|
||||
* [...<max_price_query>],
|
||||
* [...<min_price_query>],
|
||||
* ]
|
||||
* ]]
|
||||
* Result: ['meta_query' => [
|
||||
* [
|
||||
* 'key' => '_stock_status',
|
||||
* 'compare' => 'IN'
|
||||
* 'value' => ['instock', 'onbackorder']
|
||||
* ],
|
||||
* [
|
||||
* 'relation' => 'AND',
|
||||
* [...<max_price_query>],
|
||||
* [...<min_price_query>],
|
||||
* ]
|
||||
* ]]
|
||||
*
|
||||
* $base = ['post__in' => [1, 2, 3, 4, 5]]
|
||||
* $new = ['post__in' => [3, 4, 5, 6, 7]]
|
||||
* Result: ['post__in' => [1, 2, 3, 4, 5, 3, 4, 5, 6, 7]]
|
||||
*
|
||||
* @param array $base First array.
|
||||
* @param array $new Second array.
|
||||
*/
|
||||
private function array_merge_recursive_replace_non_array_properties( $base, $new ) {
|
||||
foreach ( $new as $key => $value ) {
|
||||
if ( is_numeric( $key ) ) {
|
||||
$base[] = $value;
|
||||
} else {
|
||||
if ( is_array( $value ) ) {
|
||||
if ( ! isset( $base[ $key ] ) ) {
|
||||
$base[ $key ] = array();
|
||||
}
|
||||
$base[ $key ] = $this->array_merge_recursive_replace_non_array_properties( $base[ $key ], $value );
|
||||
} else {
|
||||
$base[ $key ] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product-related query variables from the global query.
|
||||
*
|
||||
|
@ -582,3 +674,4 @@ class ProductQuery extends AbstractBlock {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue