繁体   English   中英

Woocommerce 中具有产品类别的产品变体 WP_Query

[英]Product variation WP_Query with a product category in Woocommerce

使用 Woocommerce,我正在尝试为产品类别“Apple”的产品变体帖子类型制作 WP_Query。

$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' ,则查询有效。 为什么?

这个关于 Woocommerce 产品的WP_Query有很多错误:

  • 对于产品类别产品属性,您最好通常使用tax_query代替。
  • 对于Product visibility ,自 Woocommerce 3 起,它由product_visibility分类法处理'exclude-from-search''exclude-from-catalog'术语。

有关产品变体的重要说明:

  • 产品类别(或产品标签)不由产品变体处理,而是由父变量产品处理
  • 变体的产品属性作为后元数据处理, meta_key前面加上“ attribute_ _”, met_value术语 slug
  • 产品可见性不在产品变体中处理,因为它们不显示在存档页面中。
  • 它们不会显示在存档页面中(如前所述)。

因此,当使用WP_Query时,您不能同时查询“product”帖子类型和“product_variation”帖子类型,因为它们确实不同

为了使您的查询适用于“product_variation”帖子类型,您需要一个小实用函数来获取产品类别的父变量产品(或任何自定义分类法作为产品标签......)

// 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 语句,将wp_posts表中的帖子ID列与wp_term_relationships表中的术语关系object_id列进行比较,该语句如下所示:

LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)

我们在这里需要做的就是添加一个OR语句,使查询也查找发布父 ID 并进行如下语句:(在 Woocommerce 产品变体中有一个发布父,它是产品本身)

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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM