WooCommerce技术问询:如何获取订单被标记为已取消的日期?
获取WooCommerce订单取消日期的更优方案
你的当前方法通过遍历所有订单备注筛选取消状态变更记录,虽然可行,但可以通过以下几种方式优化,提升效率和准确性:
一、优化订单备注查询(减少数据读取)
不需要获取所有订单备注,直接通过wc_get_order_notes的参数过滤出仅包含状态变更的系统备注,缩小内容匹配范围,减少遍历的数据量:
function get_cancellation_date_with_timezone($order_id) { $order = wc_get_order($order_id); if (!$order) return false; // 仅获取系统生成的、包含取消状态变更的备注 $notes = wc_get_order_notes([ 'order_id' => $order_id, 'type' => 'system', // 排除用户自定义备注 'search' => 'to Cancelled' // 精准缩小查询范围 ]); foreach ($notes as $note) { // 确认是状态变更到Cancelled的备注 if (strpos($note->content, 'Order status changed from') !== false) { // 直接返回WC自带的日期对象,无需重新实例化 return $note->date_created; } } return false; } // 使用示例 $cancellation_date = get_cancellation_date_with_timezone(1234); if ($cancellation_date) { echo $cancellation_date->format('Y-m-d\TH:i:sP'); }
二、直接查询数据库(极致性能)
如果涉及大量订单批量处理,直接查询存储订单备注的数据库表,避免WooCommerce函数的额外开销:
function get_cancellation_date_db($order_id) { global $wpdb; $date = $wpdb->get_var($wpdb->prepare( "SELECT comment_date_gmt FROM {$wpdb->comments} WHERE comment_post_ID = %d AND comment_type = 'order_note' AND comment_content LIKE %s AND comment_content LIKE %s ORDER BY comment_date_gmt ASC LIMIT 1", $order_id, '%Order status changed from%', '%to Cancelled%' )); if ($date) { // 转换为带站点时区的WC日期对象 $wc_date = new WC_DateTime($date, new DateTimeZone('UTC')); $wc_date->setTimezone(wc_timezone()); return $wc_date; } return false; } // 使用示例 $cancellation_date = get_cancellation_date_db(1234); if ($cancellation_date) { echo $cancellation_date->format('Y-m-d\TH:i:sP'); }
三、利用订单状态过渡记录(简洁方案)
部分WooCommerce版本支持直接读取状态变更历史,代码最简洁,但需注意版本兼容性:
function get_cancellation_date_transition($order_id) { $order = wc_get_order($order_id); if (!$order) return false; // 获取所有状态变更记录 $transitions = $order->get_status_transitions(); foreach ($transitions as $transition) { if ($transition['to'] === 'cancelled') { return new WC_DateTime($transition['date_created'], new DateTimeZone('UTC')); } } return false; }
方案对比
- 优化后的订单备注查询:兼顾效率与代码简洁,适合绝大多数常规场景
- 直接数据库查询:性能最优,适合批量处理大量订单的场景
- 状态过渡记录:代码最简洁,但依赖WooCommerce版本,兼容性稍弱
注意:所有方案都建议先判断订单当前状态是否为
cancelled,避免无效查询。
内容的提问来源于stack exchange,提问作者roboes
相关产品推荐
相关产品推荐

