使用 WooCommerce wc_get_products 按价格范围过滤产品

Zet*_*eth 4 woocommerce

我使用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 );
Run Code Online (Sandbox Code Playgroud)

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


解决方案尝试

尝试 1 - 尝试使用元查询

我认为 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 );
Run Code Online (Sandbox Code Playgroud)

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


尝试 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下提到。所以这可能确实有效。

Loi*_*tec 8

可变产品是按价格\xe2\x80\xa6 过滤的复杂产品,因此以下内容并不完美,但向您展示了一种在 中启用价格范围的方法WC_Product_Query

\n

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

\n
add_filter( \'woocommerce_product_data_store_cpt_get_products_query\', \'handle_price_range_query_var\', 10, 2 );\nfunction handle_price_range_query_var( $query, $query_vars ) {\n    if ( ! empty( $query_vars[\'price_range\'] ) ) {\n        $price_range = explode( \'|\', esc_attr($query_vars[\'price_range\']) );\n\n        if ( is_array($price_range) && count($price_range) == 2 ) {\n            $query[\'meta_query\'][\'relation\'] = \'AND\';\n\n            $query[\'meta_query\'][] = array(\n                \'key\'     => \'_price\',\n                \'value\'   => reset($price_range), // From price value\n                \'compare\' => \'>=\',\n                \'type\'    => \'NUMERIC\'\n            );\n\n            $query[\'meta_query\'][] = array(\n                \'key\'     => \'_price\',\n                \'value\'   => end($price_range), // To price value\n                \'compare\' => \'<=\',\n                \'type\'    => \'NUMERIC\'\n            );\n\n            $query[\'orderby\'] = \'meta_value_num\'; // sort by price\n            $query[\'order\'] = \'ASC\'; // In ascending order\n        }\n    }\n    return $query;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

代码位于子主题的functions.php 文件中(或插件中)。经过测试并有效。

\n

使用示例

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

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

\n
$products = wc_get_products( [\n    \'limit\'       => 20,\n    \'status\'      => \'publish\',\n    \'price_range\' => \'10.25|50\', // The first price is separated from the 2nd one with a pipe\n] );\n\necho \'<ul>\';\n\nforeach( $products as $product ) {\n    echo \'<li><a href="\'.$product->get_permalink().\'">\'.$product->get_name().\' \'.$product->get_price_html().\'</a></li>\';\n}\necho \'</ul>\';\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
    \'type\'        => \'variable\',\n
Run Code Online (Sandbox Code Playgroud)\n

文档: wc_get_products 和 WC_Product_Query

\n
\n

优化后的代码版本:

\n

(感谢@ChadReitsma

\n
    \'type\'        => \'variable\',\n
Run Code Online (Sandbox Code Playgroud)\n