【プラグインなし】WordPressでお問い合わせフォームを設置する方法。セキュリティ対策も - inokawablog

    【プラグインなし】WordPressでお問い合わせフォームを設置する方法。セキュリティ対策も

    WordPressでお問い合わせフォームを設置する方法をプラグインなし場合を紹介します。

    コピペだけでも大丈夫です。こちらのサイトを参考にしました。

    セキュリティ対策としてGoogleのreCAPTCHA v2のチェックボックスを実装します。

    ※GoogleのreCAPTCHAはローカル環境では使用することはできません。注意して下さい。

     

    プラグインなしのお問い合わせフォームを設置

    まずは、GoogleのreCAPTCHA v2の設定を行います。

     

    GoogleのreCAPTCHA v2の設定

    こちらのGoogleのreCAPTCHAのサイトに移動してください。右上のAdmin consoleをクリックし、

    必要な情報を入力していきます。今回はreCAPTCHA v2を使用します。「私はロボットではありません」チェックボックスを選択して下さい。ドメインは設置をするサイトのドメインをしてして下さい。

     

    recaptchaのサイトキーとシークレットキー

    recaptchaのサイトキーとシークレットキーが表示されるのでメモっておいて下さい。

     

    実行ファイルの作成

    メールの送信とバリデーションをするphpファイルを別で作成(sendmail.php)し、ajaxで実行します。

    sendmail.phpはテーマディレクトリ直下に設置して下さい。

     

    sendmail.php

    <?php
    
    $url = 'https://www.google.com/recaptcha/api/siteverify';
    $post_data = array(
      'secret' => 'recaptchaのシークレットキー',
      'response' => $_REQUEST['g-recaptcha-response'],
      'remoteip' => $_SERVER['REMOTE_ADDR'],
    );
    $options = array(
      'http' => array(
        'method' => 'POST',
        'header' => 'Content-type: application/x-www-form-urlencoded',
        'content' => http_build_query($post_data),
      )
    );
    $context = stream_context_create($options);
    $res = json_decode(file_get_contents($url, false, $context));
    
    if($res->success == 1) {
    
    	// 認証成功の処理
    	header('Content-type: application/json');
    	// PHP5.1.0以上はタイムゾーンの定義が必須
    	date_default_timezone_set('Asia/Tokyo');
    
    	// --------------------------
    	// 個別設定項目(3つ)
    	// 送信先メールアドレス
    	$to = '送信先メールアドレス';
    	// メールタイトル
    	$subject = 'お問い合わせフォームより';
    	// ドメイン(リファラチェックと送信元メールアドレスに利用)
    	$domain = 'サイトのドメイン';
    	// --------------------------
    
    	//変数初期化
    	$errflg =0;    // エラー判定フラグ
    	$dispmsg ='';  // 画面出力内容
    
    	// 入力項目
    	$nameval = '';   // 名前
    	$mailval = '';   // メールアドレス
    	$post_subject = '';    // 件名
    	$textval = '';   // 内容
    	$referrer = '';  // 遷移元画面
    
    	if(isset($_POST['nameval'])){ $nameval = $_POST['nameval']; }
    	if(isset($_POST['mailval'])){ $mailval = $_POST['mailval']; }
    	if(isset($_POST['subject'])){ $post_subject = $_POST['subject']; }
    	if(isset($_POST['textval'])){ $textval = $_POST['textval']; }
    	if(isset($_POST['referrer'])){ $referrer = $_POST['referrer']; }
    
    	if(strpos($_SERVER['HTTP_REFERER'], $domain) === false){
    		// リファラチェック
    		$dispmsg = '<p id="errmsg">【リファラチェックエラー】お問い合わせフォームから入力されなかったため、メール送信できませんでした。</p>';
    		$errflg = 1;
    	}else if($nameval == '' || $mailval == '' || $textval == ''){
    		//必須チェック
    		$dispmsg = '<p id="errmsg">【エラー】名前・メールアドレス・内容は必須項目です。</p>';
    		$errflg = 1;
    	}else if(!preg_match("/^[\.!#%&\-_0-9a-zA-Z\?\/\+]+\@[!#%&\-_0-9a-z]+(\.[!#%&\-_0-9a-z]+)+$/", $mailval) || count( explode('@',$mailval) ) !=2){
    		//メールアドレスチェック
    		$dispmsg .= '<p id="errmsg">【エラー】メールアドレスの形式が正しくありません。</p>';
    		$errflg = 1;
    	}else{
    		// メールデータ作成
    		$subject = "=?iso-2022-jp?B?".base64_encode(mb_convert_encoding($subject,'JIS','UTF-8'))."?=";
    		$message= '名前:'.$nameval."\n";
    		$message.='メール:'.$mailval."\n";
    		$message.='件名:'.$post_subject."\n";
    		$message.="\n――――――――――――――――――――――――――――――\n\n";
    		$message.=$textval;
    		$message.="\n\n――――――――――――――――――――――――――――――\n";
    		$message.='送信日時:'.date( "Y/m/d (D) H:i:s", time() )."\n";
    		$message.='送信元IPアドレス:'.@$_SERVER["REMOTE_ADDR"]."\n";
    		$message.='送信元ホスト名:'.getHostByAddr(getenv('REMOTE_ADDR'))."\n";
    		$message.='リファラURL:'.$referrer."\n";
    		$message.='お問い合わせページ:'.@$_SERVER['HTTP_REFERER']."\n";
    		$message= mb_convert_encoding($message,'JIS','UTF-8');
    		$fromName = mb_encode_mimeheader(mb_convert_encoding($nameval,'JIS','UTF-8'));
    		$header ='From: '.$fromName.'<wordpress@'.$domain.'>'."\n";
    		$header.='Reply-To: '.$mailval."\n";
    		$header.='Content-Type:text/plain;charset=iso-2022-jp\nX-Mailer: PHP/'.phpversion();
    		// メール送信
    		$retmail = mail($to,$subject,$message,$header);
    
    		if( $retmail ){
    			$dispmsg ='<p id="posted_message">お問い合わせありがとうございます。確認次第返答させていただきます。</p>';
    		}else{
    			$dispmsg .= '<p id="errmsg">【エラー】メール送信に失敗しました。</p>';
    			$errflg = 1;
    		}
    	}
    	$result = array('errflg'=>$errflg, 'dispmsg'=>$dispmsg, 'recaptcha' => true);
    	echo json_encode( $result );
    
    }else{
    	// 認証失敗の処理
    	$result = array('errflg'=>'', 'dispmsg'=>'', 'recaptcha' => false);
    	echo json_encode( $result );
    }
    
    
    // HTMLエスケープ処理
    function hsc_utf8($str) {
    	return htmlspecialchars($str, ENT_QUOTES,'UTF-8');
    }
    
    ?>

     

    送信先とドメインを設定してください。

    reCAPTCHAで自動にg-recaptcha-responseというパラメータが付与されます。これは、reCAPTCHAが実装されており、さらにユーザーがreCAPTCHAの認証を経た場合は、このパラメータが追加されます。

    認証を通っていない(チェックしていない)場合は、空になります。

     

    そして、stream_context_createでWebAPIを叩き、レスポンスで条件分岐をしています。

     

    表示するphpファイル

    <div class="contact-wrap">
    	<div class="page-title">
    		<h1>お問い合わせページ</h1>
    	</div>
    	<div id="mail-form-wrap">
    		<form id="mail-form">
    			<div class="mail-form-items-wrap">
    				<div class="mail-form-items">
    					<label for="nameval">名前<span class="require">*</span></label>
    					<input type="text" name="nameval" id="nameval" placeholder="お名前を入力して下さい。" required />
    				</div>
    				<div class="mail-form-items">
    					<label for="mailval">メールアドレス<span class="require">*</span></label>
    					<input type="email" name="mailval" id="mailval" placeholder="メールアドレスを入力して下さい。"  required />
    				</div>
    				<div class="mail-form-items">
    					<label for="post_subject">件名</label> <input
    					type="text" name="post_subject" id="subject" placeholder="件名を入力して下さい。" />
    				</div>
    				<div class="mail-form-items">
    					<label for="textval">内容<span class="require">*</span></label>
    					<textarea name="textval" id="textval" rows="10" placeholder="お問い合わせ内容を入力して下さい。" required></textarea>
    				</div>
    			</div>
    			<div class="contact-form-wrap">
    				<div class="g-recaptcha" data-callback="clearcall" data-sitekey="{recaptchaのサイトキー}"></div>
    			  <p class="contact-submit">
    						<input type="submit" value="送信" id="submit">
    						<input id="referrer" type="hidden" name="referrer" />
    			  </p>
    			</div>
    		</form>
    	</div>
    	<div id="dispmsg"></div>
    </div>
    
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
    
    <script>
    jQuery(function ($) {
      $("#referrer").val(document.referrer);
      $("#mail-form").submit(function(){
        $.ajax({
          url : "<?php echo get_template_directory_uri(); ?>/sendmail.php",
          type: 'POST',
          dataType: 'json',
          data: $(this).serialize()
        }).done( function(data){
    			if (data.recaptcha) {
    				$("#posted_message_wrap").empty();
    				$("#posted_message_wrap").html(data.dispmsg);
    				if(data.errflg != 1){
                                            //recaptch認証に成功し、メールも送信できた場合
    					$("#mail-form").remove();
    				}
    			}else{
    				alert('メール送信に失敗しました');
    			}
        }).fail( function(data){
          alert('メール送信に失敗しました');
        })
        return false;
      });
    });
    
    </script>

     

    url : “<?php echo get_template_directory_uri(); ?>/sendmail.php”

    で、メール送信用のphpファイルを対象にajaxを行います。

    返却値がerrflgとdispmsgとrecaptchなので、recaptchの判定をrecaptchで行い、errflgで送信成功かどうかの判定を行い、失敗と成功でそれぞれの処理を分けています。送信した場合に、メッセージを表示するためdispmsgにhtml()でDOMを操作しています。

    成功した場合、お問い合わせフォームをremoveで消しています。

     

    表示部でのrecaptchaの設定は、

    <div class="g-recaptcha" data-callback="clearcall" data-sitekey="6Le96rQUAAAAAI4Y3TI4PzVWDvNp4t07z3xeNWt5"></div>
    
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>

    だけです。

    recaptchaの判定は、if (data.recaptcha) {}です。

     

    簡単でしたね。お疲れ様です。

    送信が完了したら、送信完了のアニメーションと組み合わせるとリッチな感じになります。文字だけでは味気ない気もします。Lottieというものを使えば簡単に、しかも軽量にアニメーションを実装することができます。

    実際にこのサイトのお問い合わせにもアニメーションが設定してあります。