WordPressのsave_postフック関連で問題発生(多重投稿・ゴミ箱)した場合のメモ

WordPressのsave_postフックは新規投稿時にも更新時などにも使えて便利なのですが、なんでもかんでもsave_postで済ませてしまうにはいくつか仕様上の問題もあるので対処方法を備忘録として書いておきます。

二重投稿(多重投稿)されてしまう場合

save_postが他関数の内部的に実行されてしまい、多重投稿してしまう問題です。
例として画像をカスタムフィールドからアップロードする場合にありがちな以下のような場合が考えられます。

add_action('save_post', 'save_custom_field_postdata');
function save_custom_field_postdata( $post_id ) {
	//~中略~
	$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
	wp_update_attachment_metadata( $attach_id, $attach_data );
	//~中略~
}

これを投稿時に実行してしまうと画像の登録が複数回行われてしまいます。
そんな時はremove_action()で処理終了後に解除してやればOKです。

add_action('save_post', 'save_custom_field_postdata');
function save_custom_field_postdata( $post_id ) {
	//~中略~
	$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
	wp_update_attachment_metadata( $attach_id, $attach_data );
	//~中略~

	//add_actionで登録した関数をremove_actionで解除
	remove_action('save_post', 'save_custom_field_postdata');
}

これで多重投稿問題は解決するはずです。

ゴミ箱の問題

実はsave_postは「ゴミ箱に入れる」、「ゴミ箱から復元」などのタイミングでも実行されてしまいます。
WordPress的にはゴミ箱も記事の状態変化(更新)であるということなのでしょう。
ゴミ箱周辺でsave_post内の処理を行わせたくない場合は、

add_action('save_post', 'save_custom_field_postdata');
function save_custom_field_postdata( $post_id ) {
	if( !empty($_POST) ){
		update_post_meta( $post_id, 'hoge' , $_POST['hoge'] );
	}
}

こんな感じで$_POSTの有無判定を入れてやればゴミ箱系の更新の場合は処理をスルーしてあげることができます。


投稿更新時の処理を一括で実現できて便利なsave_postフックですが、上記例のように思わぬところで発火してしまうことがあるので使う時は要注意です。