WordPressで投稿時に、投稿した記事の中に特定の文字が入っているか確認し、入っていればそのまま保存し、入っていなければ警告を表示して保存を中断するというバリデーションの処理方法を紹介したいと思います。
save_postでは無理
この処理を考え始めた当初は、save_postにバリデーション用の関数をフックすれば良いかと考えました。しかし調べていると、save_postはDBにデータをインサート後に実行されるようなので、そこでチェックをしても”時すでに遅し”であることが判明しました。ついでに言うとsave_postにフックした関数で仮にバリデーションエラーとしてfalseをリターンしてもWordPress側では戻り値の確認をしていないので、そのまま処理が続行されてしまいます。
Ajaxを利用する
そこで今回紹介するのはAjaxを利用する方法です。
原理としては、公開ボタンを押したときに動作するAjaxを定義し、そこから呼ばれたPHP側の処理で投稿された記事のバリデーションを行います。
以下は投稿された記事に「hoge」という文字が入っているか確認する場合の例です。functions.phpに記述しています。
add_action('admin_head-post-new.php', 'my_publish_admin_hook'); // 新規投稿画面でのみ関数を呼び出す
add_action('admin_head-post.php', 'my_publish_admin_hook'); // 投稿編集画面でのみ関数を呼び出す
function my_publish_admin_hook(){
global $post;
if (is_admin() && $post->post_type == 'post'){ //投稿の場合
?>
<script language="javascript" type="text/javascript">
jQuery(document).ready(function() {
jQuery('#publish').click(function() {
if(jQuery(this).data("valid")) {
return true;
}
var form_data = jQuery('#post').serializeArray();
var data = {
action: 'my_pre_submit_validation',
security: '<?php echo wp_create_nonce( 'pre_publish_validation' ); ?>',
form_data: jQuery.param(form_data),
};
jQuery.post(ajaxurl, data, function(response) {
if (response.indexOf('true') > -1 || response == true) {
jQuery('#publish').data("valid", true).trigger('click');
} else {
alert("エラー: " + response);
jQuery("#publish").data("valid", false);
}
jQuery('#ajax-loading').hide();
jQuery('#publish').removeClass('button-primary-disabled');
jQuery('#save-post').removeClass('button-disabled');
});
return false;
});
});
</script>
<?php
}
}
add_action('wp_ajax_my_pre_submit_validation', 'pre_submit_validation');
function pre_submit_validation(){
//簡単なセキュリティのチェック
check_ajax_referer( 'pre_publish_validation', 'security' );
parse_str( $_POST['form_data'], $vars );
//含まれているべき文字列
$must_text = 'hoge';
//バリデーションの実行
if(strpos($vars['content'], $must_text) === false){
echo '投稿記事中に"' . $must_text . '"が見つかりませんでした。';
die();
}
//問題が無い場合はtrueを返す
echo 'true';
die();
}
最後に
今回は記事を投稿する前に、記事の中身を確認する方法をご紹介しました。
今回紹介した方法を応用すれば、必須の文字列の存在確認だけではなく、記事の長さの確認や、カスタムフィールドがある場合は、その中身の確認もできますね。

