You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce后台订单列表(HPOS)日期范围筛选异常问题

问题:WooCommerce后台订单日期范围筛选,同一日期时无法正确过滤

我尝试在WooCommerce后台订单列表添加「按日期范围筛选」功能,使用了以下PHP代码,但当选择同一日期(如9月1日至9月1日)时,仍会显示该日期前后的订单,请问我哪里出错了?

function ts_add_date_range_filter($post_type) {
    if ('shop_order' === $post_type) {
        ?>
        <label for="from_date"><?php _e('From Date:', 'woocommerce'); ?></label>
        <input type="date" id="from_date" name="from_date" value="<?php echo isset($_GET['from_date']) ? esc_attr($_GET['from_date']) : ''; ?>" />

        <label for="to_date"><?php _e('To Date:', 'woocommerce'); ?></label>
        <input type="date" id="to_date" name="to_date" value="<?php echo isset($_GET['to_date']) ? esc_attr($_GET['to_date']) : ''; ?>" />
        <?php
    }
}
add_action('woocommerce_order_list_table_restrict_manage_orders', 'ts_add_date_range_filter');

function ts_filter_orders_by_date_range($vars) {
    if (!isset($vars['date_query'])) {
        $vars['date_query'] = array();
    }

    if (isset($_GET['from_date']) && !empty($_GET['from_date'])) {
        $vars['date_query'][] = array(
            'after'     => sanitize_text_field($_GET['from_date']),
            'inclusive' => true,
        );
    }

    if (isset($_GET['to_date']) && !empty($_GET['to_date'])) {
        $vars['date_query'][] = array(
            'before'    => sanitize_text_field($_GET['to_date']),
            'inclusive' => true,
        );
    }

    return $vars;
}
add_filter('woocommerce_order_list_table_prepare_items_query_args', 'ts_filter_orders_by_date_range');

错误原因分析
  1. 日期解析逻辑问题:当只传递YYYY-MM-DD格式的日期给before参数时,WordPress会自动将其解析为当天的00:00:00,这意味着当天0点之后创建的订单都会被排除在筛选结果之外,和你期望的「包含当天所有订单」不符。

  2. date_query结构不合理:你将after和before拆分成两个独立的date_query子数组,虽然默认逻辑是AND,但这种写法可能导致潜在的逻辑冲突,正确的做法是将两个条件放在同一个子数组中。


修正后的代码
function ts_add_date_range_filter($post_type) {
    if ('shop_order' === $post_type) {
        ?>
        <label for="from_date"><?php _e('From Date:', 'woocommerce'); ?></label>
        <input type="date" id="from_date" name="from_date" value="<?php echo isset($_GET['from_date']) ? esc_attr($_GET['from_date']) : ''; ?>" />

        <label for="to_date"><?php _e('To Date:', 'woocommerce'); ?></label>
        <input type="date" id="to_date" name="to_date" value="<?php echo isset($_GET['to_date']) ? esc_attr($_GET['to_date']) : ''; ?>" />
        <?php
    }
}
add_action('woocommerce_order_list_table_restrict_manage_orders', 'ts_add_date_range_filter');

function ts_filter_orders_by_date_range($vars) {
    // 初始化date_query数组,确保结构正确
    if (!isset($vars['date_query']) || !is_array($vars['date_query'])) {
        $vars['date_query'] = array(
            'relation' => 'AND', // 显式设置条件关系为AND
        );
    }

    $date_query = array();

    if (isset($_GET['from_date']) && !empty($_GET['from_date'])) {
        $date_query['after'] = sanitize_text_field($_GET['from_date']);
        $date_query['inclusive'] = true;
    }

    if (isset($_GET['to_date']) && !empty($_GET['to_date'])) {
        // 将结束日期设置为当天的23:59:59,确保包含当天所有订单
        $date_query['before'] = sanitize_text_field($_GET['to_date']) . ' 23:59:59';
        $date_query['inclusive'] = true;
    }

    // 如果有筛选条件,添加到date_query中
    if (!empty($date_query)) {
        $vars['date_query'][] = $date_query;
    }

    return $vars;
}
add_filter('woocommerce_order_list_table_prepare_items_query_args', 'ts_filter_orders_by_date_range');

关键修改点
  • 处理结束日期:在to_date的日期后拼接23:59:59,确保WordPress将结束时间识别为当天的最后一秒,包含当天所有时间段的订单。
  • 统一date_query结构:将after和before条件合并到同一个子数组中,并显式设置relation为AND,让筛选逻辑更清晰且避免冲突。

内容的提问来源于stack exchange,提问作者javitoor1001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 20:05:02