wp_update_post()は既存投稿IDと変更項目を確定し、WP_Errorを確認して更新する
公開日: 執筆:佐藤
wp_update_post()で既存投稿を更新するときは、投稿IDと変更する項目だけを配列へ入れます。第二引数へtrueを渡し、返り値がWP_Errorなら処理を止め、投稿IDが返ったときだけ更新後の処理へ進みます。
外部入力をすべて配列へ移したり、現在の投稿データを画面から送り返したりする必要はありません。変更を許可する項目を呼出側で限定してください。
IDは更新する既存投稿を指定する
WordPress 3.9.2の公式Coreでは、wp_update_post()が配列のIDから既存投稿を取得します。該当する投稿がなければ、第二引数がtrueのときはinvalid_postのWP_Error、falseのときは0を返します。
題名だけを変えるなら、必要な配列は次の二項目です。
$post_data = array(
'ID' => $post_id,
'post_title' => $post_title
);
投稿IDが正しいことと、実行者がその投稿を編集できることは別です。IDを受け取ったら、投稿の存在だけでなく、current_user_can( 'edit_post', $post_id )で権限を確認します。
省略した項目は既存値と結合される
wp_update_post()は既存投稿の項目を取得し、新しく渡した配列を重ねます。新しい値が同名の既存値を上書きし、省略した項目は既存値を引き継ぎます。その配列をwp_insert_post()へ渡して更新します。
題名だけを直す処理へ、本文、公開状態、投稿者、公開日まで入れると、意図しない変更の範囲が増えます。変更しない項目は、画面のhidden入力へ入れて送り返さず、配列から外してください。
とくにpost_statusを省略すれば、既存の公開状態を引き継ぎます。公開状態を変える機能を作るなら、題名更新とは別の操作として権限と確認画面を設けます。
外部入力を整えてから更新する
次は、題名だけを更新する説明用の仮例です。nonceの確認は、この関数を呼ぶ前に終えているものとします。
function satolab_update_post_title( $post_id, $raw_title ) {
$post_id = absint( $post_id );
if ( ! $post_id || ! current_user_can( 'edit_post', $post_id ) ) {
return new WP_Error( 'cannot_edit_post', 'この投稿は更新できません。' );
}
if ( ! is_string( $raw_title ) ) {
return new WP_Error( 'invalid_post_title', '題名の形式が正しくありません。' );
}
$post_title = trim( wp_strip_all_tags( $raw_title ) );
if ( '' === $post_title ) {
return new WP_Error( 'empty_post_title', '題名を入力してください。' );
}
$result = wp_update_post(
wp_slash(
array(
'ID' => $post_id,
'post_title' => $post_title
)
),
true
);
if ( is_wp_error( $result ) ) {
return $result;
}
return $result;
}
cannot_edit_postなどのcodeとmessageは仮例です。実装では、利用者へ表示する説明と、管理者が原因を調べる記録を分けます。
WP_Errorを確認してから次へ進む
成功時の返り値は投稿IDです。失敗時にWP_Errorを受け取れば、無効な投稿IDなどの理由を分けて扱えます。
更新後に投稿メタや分類も変えるなら、is_wp_error()を通過してから実行します。投稿IDが返ったことは、続く更新まで成功したことを意味しません。各処理の結果を分けて記録してください。
同じ投稿を複数人や定期処理が更新する場合は、呼出前に取得した値がまだ有効かも確認します。管理画面の編集ロックがあることを理由に、独自処理による上書きまで防げると決めつけてはいけません。
nonceと権限は呼出側で確認する
wp_update_post()は、独自フォームから届いた要求が正規の画面から送られたかを判断する関数ではありません。管理画面から実行するなら、同じactionを使うnonceと、投稿単位の編集権限を呼出側で確認します。
更新機能を外部へ委託しても、変更を許可する項目、失敗記録、再実行する条件はサイト所有者が確認できるようにします。関数を呼べたことと、意図した投稿だけを更新できることを同じにしないでください。
最初の一手は、下書き一件の題名だけを変える処理を作り、正しいID、存在しないID、権限のないIDで返り値を分けて確認することです。
関連記事

