Woocommerce 中具有产品类别的产品变体 WP_Query
Product variation WP_Query with a product category in Woocommerce
使用 Woocommerce,我正在尝试为产品变体 post 类型制作 WP_Query 产品类别 'Apple'。
$args = array(
'product_cat' => 'Apple',
'post_type' => array('product', 'product_variation'),
'post_status' => 'publish',
'key' => '_visibility',
'value' => 'visible',
'posts_per_page' => 100,
'taxonomy' => 'pa_size',
'meta_value' => '39',
'meta_query' => array(
array(
'key' => '_stock',
'value' => 0,
'compare' => '>'
)
)
);
但我无法在这个查询中使用它。如果我删除 'product_cat' => 'Apple'
,则查询有效。为什么?
这个 WP_Query
关于 Woocommerce 产品有很多错误:
- 对于产品类别和产品属性,您最好通常使用
tax_query
。
- 对于产品可见性,自 Woocommerce 3 起,它由
product_visibility
分类法处理 'exclude-from-search'
和 'exclude-from-catalog'
术语。
关于产品变体的重要说明:
- 产品类别(或产品标签)不由产品变体处理,而是由父变量产品处理
- 变体的产品属性作为 post 元数据 处理,带有前缀为“
attribute_
”的 meta_key
和 met_value
那是 词条 .
- 产品变体中未处理产品可见性,因为它们未显示在存档页面中。
- 它们不会显示在存档页面中(如前所述)。
因此,当使用 WP_Query
时,您 不能同时查询 "product" post 类型和 "product_variation" post 输入 因为它们确实不同。
为了使您的查询适用于 "product_variation" post 类型,您需要一个小实用函数来获取产品类别 (或任何自定义分类法)的父变量产品作为产品标签...):
// Utility function to get the parent variable product IDs for a any term of a taxonomy
function get_variation_parent_ids_from_term( $term, $taxonomy, $type ){
global $wpdb;
return $wpdb->get_col( "
SELECT DISTINCT p.ID
FROM {$wpdb->prefix}posts as p
INNER JOIN {$wpdb->prefix}posts as p2 ON p2.post_parent = p.ID
INNER JOIN {$wpdb->prefix}term_relationships as tr ON p.ID = tr.object_id
INNER JOIN {$wpdb->prefix}term_taxonomy as tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN {$wpdb->prefix}terms as t ON tt.term_id = t.term_id
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
AND p2.post_status = 'publish'
AND tt.taxonomy = '$taxonomy'
AND t.$type = '$term'
" );
}
代码进入您的活动子主题(或活动主题)的 function.php 文件。测试和工作。 下面WP_Query
需要…
此处WP_Query
代码用于产品变体(仅)与特定产品类别和特定变体属性值相关:
// Settings
$cat_name = 'Apple'; // Product category name
$attr_taxonomy = 'pa_size'; // Product attribute
$attribute_term_slugs = array('39'); // <== Need to be term SLUGs
$query = new WP_Query( array(
'post_type' => 'product_variation',
'post_status' => 'publish',
'posts_per_page' => 100,
'post_parent__in' => get_variation_parent_ids_from_term( $cat_name, 'product_cat', 'name' ), // Variations
'meta_query' => array(
'relation' => 'AND',
array(
'key' => '_stock',
'value' => 0,
'compare' => '>'
),
array(
'key' => 'attribute_'.$attr_taxonomy, // Product variation attribute
'value' => $attribute_term_slugs, // Term slugs only
'compare' => 'IN',
),
),
) );
// Display the queried products count
echo '<p>Product count: ' . $query->post_count . '<p>';
// Displaying raw output for posts
print_pr($query->posts);
已测试并有效。
有一些方法可以做到这一点,您可以循环产品并检查产品是否 variable
如果为真,您可以添加另一个循环以包含变体,但如果您必须这样做对于 WP_Query
出于任何原因,您可以使用 posts_join
过滤器,当您使用 tax_query
时,它将添加一个 LEFT JOIN
sql 语句来比较 post ID
column in wp_posts
table with term relationship object_id
column in wp_term_relationships
table,语句如下所示:
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
我们在这里需要做的就是添加一个 OR
语句,使查询也查找 post 父 ID 并进行如下语句:(在 Woocommerce 产品变体中有一个 post parent 即产品本身)
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id OR wp_posts.post_parent = wp_term_relationships.object_id)
长话短说,我们该怎么做?
我们将使用一个posts_join过滤器来做到这一点,但请记住我们需要在wp_query被触发后立即移除过滤器(你也可以制作一些独特的变量并且只改变join
声明如果该变量存在
function dornaweb_include_parent_categories_join($joins, $wp_query) {
/*
* You can make a condition to make sure this code will only run on your intended query
* Altough removing the filter after wp_query also do it
*/
if ($wp_query->query['my_include_parent_posts_cat_variable']) {
global $wpdb;
$find = "{$wpdb->prefix}posts.ID = {$wpdb->prefix}term_relationships.object_id";
$joins = str_replace($find, $find . " OR {$wpdb->prefix}posts.post_parent = {$wpdb->prefix}term_relationships.object_id", $joins);
}
return $joins;
}
add_filter( 'posts_join' , "dornaweb_include_parent_categories_join", 99, 2);
$products_list = new \WP_Query([
'post_type' => ['product', 'product_variation'],
'posts_per_page' => 15,
'paged' => !empty($_GET['page']) ? absint($_GET['page']) : 1,
'tax_query' => [
[
'taxonomy' => 'product_cat',
'terms' => [$category],
]
],
'my_include_parent_posts_cat_variable' => true
]);
remove_filter( 'posts_join' , "dornaweb_include_parent_categories_join", 99, 2);
使用 Woocommerce,我正在尝试为产品变体 post 类型制作 WP_Query 产品类别 'Apple'。
$args = array(
'product_cat' => 'Apple',
'post_type' => array('product', 'product_variation'),
'post_status' => 'publish',
'key' => '_visibility',
'value' => 'visible',
'posts_per_page' => 100,
'taxonomy' => 'pa_size',
'meta_value' => '39',
'meta_query' => array(
array(
'key' => '_stock',
'value' => 0,
'compare' => '>'
)
)
);
但我无法在这个查询中使用它。如果我删除 'product_cat' => 'Apple'
,则查询有效。为什么?
这个 WP_Query
关于 Woocommerce 产品有很多错误:
- 对于产品类别和产品属性,您最好通常使用
tax_query
。 - 对于产品可见性,自 Woocommerce 3 起,它由
product_visibility
分类法处理'exclude-from-search'
和'exclude-from-catalog'
术语。
关于产品变体的重要说明:
- 产品类别(或产品标签)不由产品变体处理,而是由父变量产品处理
- 变体的产品属性作为 post 元数据 处理,带有前缀为“
attribute_
”的meta_key
和met_value
那是 词条 . - 产品变体中未处理产品可见性,因为它们未显示在存档页面中。
- 它们不会显示在存档页面中(如前所述)。
因此,当使用 WP_Query
时,您 不能同时查询 "product" post 类型和 "product_variation" post 输入 因为它们确实不同。
为了使您的查询适用于 "product_variation" post 类型,您需要一个小实用函数来获取产品类别 (或任何自定义分类法)的父变量产品作为产品标签...):
// Utility function to get the parent variable product IDs for a any term of a taxonomy
function get_variation_parent_ids_from_term( $term, $taxonomy, $type ){
global $wpdb;
return $wpdb->get_col( "
SELECT DISTINCT p.ID
FROM {$wpdb->prefix}posts as p
INNER JOIN {$wpdb->prefix}posts as p2 ON p2.post_parent = p.ID
INNER JOIN {$wpdb->prefix}term_relationships as tr ON p.ID = tr.object_id
INNER JOIN {$wpdb->prefix}term_taxonomy as tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN {$wpdb->prefix}terms as t ON tt.term_id = t.term_id
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
AND p2.post_status = 'publish'
AND tt.taxonomy = '$taxonomy'
AND t.$type = '$term'
" );
}
代码进入您的活动子主题(或活动主题)的 function.php 文件。测试和工作。 下面WP_Query
需要…
此处WP_Query
代码用于产品变体(仅)与特定产品类别和特定变体属性值相关:
// Settings
$cat_name = 'Apple'; // Product category name
$attr_taxonomy = 'pa_size'; // Product attribute
$attribute_term_slugs = array('39'); // <== Need to be term SLUGs
$query = new WP_Query( array(
'post_type' => 'product_variation',
'post_status' => 'publish',
'posts_per_page' => 100,
'post_parent__in' => get_variation_parent_ids_from_term( $cat_name, 'product_cat', 'name' ), // Variations
'meta_query' => array(
'relation' => 'AND',
array(
'key' => '_stock',
'value' => 0,
'compare' => '>'
),
array(
'key' => 'attribute_'.$attr_taxonomy, // Product variation attribute
'value' => $attribute_term_slugs, // Term slugs only
'compare' => 'IN',
),
),
) );
// Display the queried products count
echo '<p>Product count: ' . $query->post_count . '<p>';
// Displaying raw output for posts
print_pr($query->posts);
已测试并有效。
有一些方法可以做到这一点,您可以循环产品并检查产品是否 variable
如果为真,您可以添加另一个循环以包含变体,但如果您必须这样做对于 WP_Query
出于任何原因,您可以使用 posts_join
过滤器,当您使用 tax_query
时,它将添加一个 LEFT JOIN
sql 语句来比较 post ID
column in wp_posts
table with term relationship object_id
column in wp_term_relationships
table,语句如下所示:
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
我们在这里需要做的就是添加一个 OR
语句,使查询也查找 post 父 ID 并进行如下语句:(在 Woocommerce 产品变体中有一个 post parent 即产品本身)
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id OR wp_posts.post_parent = wp_term_relationships.object_id)
长话短说,我们该怎么做?
我们将使用一个posts_join过滤器来做到这一点,但请记住我们需要在wp_query被触发后立即移除过滤器(你也可以制作一些独特的变量并且只改变join
声明如果该变量存在
function dornaweb_include_parent_categories_join($joins, $wp_query) {
/*
* You can make a condition to make sure this code will only run on your intended query
* Altough removing the filter after wp_query also do it
*/
if ($wp_query->query['my_include_parent_posts_cat_variable']) {
global $wpdb;
$find = "{$wpdb->prefix}posts.ID = {$wpdb->prefix}term_relationships.object_id";
$joins = str_replace($find, $find . " OR {$wpdb->prefix}posts.post_parent = {$wpdb->prefix}term_relationships.object_id", $joins);
}
return $joins;
}
add_filter( 'posts_join' , "dornaweb_include_parent_categories_join", 99, 2);
$products_list = new \WP_Query([
'post_type' => ['product', 'product_variation'],
'posts_per_page' => 15,
'paged' => !empty($_GET['page']) ? absint($_GET['page']) : 1,
'tax_query' => [
[
'taxonomy' => 'product_cat',
'terms' => [$category],
]
],
'my_include_parent_posts_cat_variable' => true
]);
remove_filter( 'posts_join' , "dornaweb_include_parent_categories_join", 99, 2);