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(); }
最後に
今回は記事を投稿する前に、記事の中身を確認する方法をご紹介しました。
今回紹介した方法を応用すれば、必須の文字列の存在確認だけではなく、記事の長さの確認や、カスタムフィールドがある場合は、その中身の確認もできますね。