首页 > 解决方案 > 使用 WooCommerce wc_get_products 按价格范围过滤产品

问题描述

我正在使用wc_get_products()获得一堆分页变量产品。而且我只想获得给定价格范围内的产品。问题是产品很多,所以一次只能提取 20 个产品。

根据文档,meta_query()使用wc_get_products().

那我怎么得到这个?

这是我当前的查询:

$products_query = [
    'category' => [ get_queried_object()->slug ],
    'limit' => 20,
    'paginate' => true,
    'paged' => (get_query_var('paged')) ? get_query_var('paged') : 1,
];

$products = wc_get_products( $products_query );

现在请记住,这是在从数据库中查询产品之前需要实现的东西。假设我总共有 100 种产品。由于产品是分页的,那么如果我在_price(ASC)之后订购了产品,那么第1页应该返回20个最便宜的产品。第 3 页应该返回 40-60 的产品(在它们被排序之后)。


解决方案尝试

尝试 1 - 无论如何尝试使用 meta_query

我认为 wc_get_products 受到启发并建立在 WP_Query 之上,所以我尝试了这个:

$products_query = [
    'category' => [ get_queried_object()->slug ],
    'limit' => 20,
    'paginate' => true,
    'paged' => (get_query_var('paged')) ? get_query_var('paged') : 1,
    'meta_query' => [
        'relation' => 'AND',
        [
            'key' => '_price',
            'value' => 100,
            'compare' => '<=',
            'type' => 'NUMERIC'
        ]
    ]
];

$products = wc_get_products( $products_query );

它只是忽略meta_query-part 并返回一个结果,就好像它不存在一样。


尝试 2 - 使用 WP_Query

我所看到的每一个地方,都有指向wc_get_products和远离的箭头wp_query。所以我没有追求这个。


尝试 3 - 原始 SQL

一种解决方案是进行原始 SQL 查询。但是由于产品是可变产品,那么 SQL 查询将是相当多的连接,因为它应该首先找到所有产品 - 然后找到所有变体。然后在最低变化价格之后(如果价格排序是升序)和最高变化价格之后(如果价格排序是降序)对产品进行排序。这显然是可能的,但我希望找到一个更像 WordPress 的解决方案。而且我不擅长 SQL。


尝试 4 - 使用插件

我环顾四周 - WooCommerce 的 sort'n'filter-plugins 是怪物,因为它们将脚本和样式放在左、右和中心。所以这似乎是一个糟糕的解决方案。


尝试 5 - 使用 WooCommerce API

我可以看到min_price并在列出所有产品max_price下提到。所以这可能真的有效。

标签: woocommerce

解决方案


可变产品是按价格过滤的复杂东西......所以以下内容并不完美,但向您展示了一种启用价格范围的方法WC_Product_Query

因此,以下函数将启用自定义价格范围WC_Product_Query查询:

add_filter( 'woocommerce_product_data_store_cpt_get_products_query', 'handle_price_range_query_var', 10, 2 );
function handle_price_range_query_var( $query, $query_vars ) {
    if ( ! empty( $query_vars['price_range'] ) ) {
        $price_range = explode( '|', esc_attr($query_vars['price_range']) );

        if ( is_array($price_range) && count($price_range) == 2 ) {
            $query['meta_query']['relation'] = 'AND';

            $query['meta_query'][] = array(
                'key'     => '_price',
                'value'   => reset($price_range), // From price value
                'compare' => '>=',
                'type'    => 'NUMERIC'
            );

            $query['meta_query'][] = array(
                'key'     => '_price',
                'value'   => end($price_range), // To price value
                'compare' => '<=',
                'type'    => 'NUMERIC'
            );

            $query['orderby'] = 'meta_value_num'; // sort by price
            $query['order'] = 'ASC'; // In ascending order
        }
    }
    return $query;
}

代码位于活动子主题(或活动主题)的 functions.php 文件中。测试和工作。

示例用法

  • 处理浮点数。
  • 第一个价格与第二个价格由管道隔开|

这里我们查询 10.25 美元到 50 美元(价格范围)的产品:

$products = wc_get_products( [
    'limit'       => 20,
    'status'      => 'publish',
    'price_range' => '10.25|50', // The first price is separated from the 2nd one with a pipe
] );

echo '<ul>';

foreach( $products as $product ) {
    echo '<li><a href="'.$product->get_permalink().'">'.$product->get_name().' '.$product->get_price_html().'</a></li>';
}
echo '</ul>';

要仅过滤变量 products,您可以将以下行添加到查询中:

    'type'        => 'variable',

文档: wc_get_products 和 WC_Product_Query


推荐阅读