之前做過一個需求是要讓訂單建立的 N 天後,去執行一些任務,這邊先以增加訂單備註為範例,我當時不知道是怎麼想的,我是設計成每天午夜十二點的重複排程,時間一到就會去撈出所有訂單,然後去拿今天的時間跟訂單建立時間做比較,也就是今天時間 – 訂單時間 > 5,就會寫入該訂單的備註。
這樣的寫法很複雜,因為要去做時間的計算,而且萬一訂單量非常龐大,每晚撈出所有訂單對於資料庫是不小的負擔,後來轉念才想通,我只要在訂單建立的時候建立只屬於該訂單的排程,然後把執行時間設為五天後不就解決了?
但還有一個問題是如果每張訂單都有屬於自己的排程,那麼我該如何分辨這個排程是屬於哪張訂單?一開始我想的是以訂單編號當作排程名稱,然後在執行後去抓出排程名稱的 ID,但這樣在註冊排程時又會變得太繁雜,好在 Action Schedule 有提供參數的功能,可以在註冊時就一併把訂單 ID 紀錄起來,之後就能拿到這個參數做處理,實際作法如下:
<?php
add_action( 'woocommerce_new_order', 'set_order_note_cron', 10, 2 );
function set_order_note_cron( $order_id, $order ) {
as_schedule_single_action( strtotime( current_time( 'Y-m-d H:i:s' ) . '+5 days - 8 hour' ), 'order_note_cron', array( $order_id ) );
}
我們先在訂單成立時使用as_schedule_single_action
註冊單次排程,並且以現在時間的五天後作為觸發時間,同時以 order_note_cron
作為排程名稱,而最後就是要傳給排程的參數,用陣列的方式存放訂單 ID,接下來就可以把新增訂單備註的函式掛在這個排程上。
<?php
add_action( 'order_note_cron', 'order_note', 10, 1 );
public function order_note( $order_id ) {
$order = wc_get_order( $order_id );
$order->add_order_note( '這張訂單超過五天囉~' )
}