【プラグインなし】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というものを使えば簡単に、しかも軽量にアニメーションを実装することができます。

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