transition_post_statusのアクションフックで$postを使う時の注意点

Post Status Transitions « WordPress Codex

transition_post_statusは投稿の状態が変更されたときに呼び出されるフック。以下のように使う。


add_action('transition_post_status', function($new_status, $old_status, $post) {
  if ($new_status == 'future') {
    send_publish_notify_mail($post);
  }
}, 10, 3);

function send_publish_notify_mail($post) {
  ...
}

ここで引数の$postを関数間で引き回すのがめんどくさかったので以下のようにglobal $postをつかっていたところ、ちょっとハマった。


add_action('transition_post_status', function($new_status, $old_status, $post) {
  if ($new_status == 'future') {
    send_publish_notify_mail();
  }
}, 10, 3);

function send_publish_notify_mail() {
  global $post;
  ...
}

簡潔に原因を述べると・・・

global $postには更新前の$postが入ってる。
$post->post_statusが$old_statusと同様になる。

コールバック引数の$postは更新後の$post。
$post->post_statusは$new_statusと同じになる。

transition_post_statusは更新後に呼び出されるフックのはずだが、globalな$postはDBからの再読み込みがされていないのだろう。
これを利用して新旧の値を比較して何かするといったこともできそうだ。

が、アンドキュメンテッドな挙動なので、これをアテにして処理を書くのはやめた方がいいと思われる。

つまり結論としてはglobalのではなくコールバックの引数でわたってくる$postを使いましょうと言うことだ。