WordPressで問い合わせフォームをプラグインなしの自作実装

WEB制作

投稿日:

今回、問い合わせフォームを実装するにあたって久々に「WordPress + ◯◯」系のキーワードで調べていて色々とEvernoteのwebクリッパーに追加していたら、そういえばWordPressにも似たような機能あったなと思い出したので追加しようとしたんですが、WordPress4.9から削除されていたことに衝撃を受けました。

その名も「Press This」

結構、便利な機能だったような気もしますが使っている人は少数派だったんでしょうね。
Evernoteもちょっと前まではWebに携わってる人はみんな入れてたような気もしますが、改悪が続いたせいかすっかり過去の遺物と化してしまいましたね。

それでも私は使い続けます!(なぜなら代替アプリが見つからないから…)

環境によっては【WP Mail SMTP】などのプラグインが必要

プラグインなしでと言いつつ、環境によってはプラグインが必要になります。

例えば、Webサイトはコアサーバーやさくら、エックスサーバーなどを利用しているけどメールアドレスはgmailなどドメインが別になるものはSMTPの認証が必要になります。

私の環境はコアサーバーを利用していて、メールサーバーも同様なのでプラグインなしで作成しました。

Webサイトと問い合わせ用のメールアドレスのドメインが別という方はインストールしてご使用ください。

WP Mail SMTPダウンロード

テーマ内に問い合わせ用のテンプレートを追加

実装方法はちょっと調べるとたくさん出てくると思いますが、ARA WEB BLOGさんのサンプルを元に作成させていただいております。

以下6つのテンプレートを使用しているテーマディレクトリ内へ作成します。
ちなみに私はSTINGER8を子テーマ化して使用しているので同テーマであればそのまま追加してもらえれば動作すると思います。

  • contact-index.php
  • contact-input.php
  • contact-check.php
  • contact-confirm.php
  • contact-sendmail.php
  • contact-completion.php

お問い合わせページテンプレート

contact-index.php

<?php
/*******************************
 固定ページ お問い合わせ
 Template Name: contact-index
*******************************/
get_header(); ?>
<nav id="breadcrumb">
  <ol itemscope itemtype="http://schema.org/BreadcrumbList">
    <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="<?php echo home_url(); ?>" itemprop="item"><span itemprop="name">HOME</span></a> >
      <meta itemprop="position" content="1"/>
    </li>
    <?php 
    $postcat = get_the_category();
    $catid = $postcat[0]->cat_ID;
    $allcats = array( $catid );

  while ( !$catid == 0 ) {
    $mycat = get_category( $catid );
    $catid = $mycat->parent;
    array_push( $allcats, $catid );
  }
  array_pop( $allcats );
  $allcats = array_reverse( $allcats );
  $i = 2;
  foreach ( $allcats as $catid ): ?>
    <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="<?php echo get_category_link( $catid ); ?>" itemprop="item">
    <span itemprop="name"><?php echo esc_html( get_cat_name( $catid ) ); ?></span> </a>
      >
      <meta itemprop="position" content="<?php echo $i; ?>"/>
    </li>
    <?php  
  $i++; 
  endforeach; ?>
  </ol>
</nav>
<div id="content" class="clearfix">
	<div id="contentInner">
		<div class="st-main contact">
      
      <div id="st-page" <?php post_class('post'); ?>>
      <?php if(!is_front_page()){ ?>
        <h1 class="entry-title"><?php the_title(); //タイトル ?></h1>
      <?php } ?>
        
      <?php
      /* ↑↑↑↑↑↑↑↑↑↑ ここから上部は page.php のヘッダーのコピペ ↑↑↑↑↑↑↑↑↑↑  */

      // エラーメッセージと不正アクセスフラグ
      $error_mes = "";
      $noindexaccess = true;
      // 問い合わせ先
      $mail = get_option('admin_email');

      // メアドに表示する名前
      define('WEBMST_NAME', get_bloginfo('name') );
      // お問い合わせ用メアド
      define('WEBMST_MAIL', $mail);
      // 送信先メールアドレス
      $mailto = WEBMST_MAIL;

      #--------------------------------------------------------------
      # 全体のコントロール
      #--------------------------------------------------------------
      switch($_POST["action"]):

      case "completion":
      /////////////////////////////////////////////////////////////////////////////
      // メール送信処理と完了画面を表示

          include('contact-check.php');
          if(!$error_mes){
              include('contact-sendmail.php');
              include('contact-completion.php');
          }
          else{
              die("<p>エラーが発生しました。<br />もう一度送信しなおしてください。</p>");
          }
          break;
      case "confirm":
      /////////////////////////////////////////////////////////////////////////////
      // エラーがあれば再入力、なければ確認画面表示

          include('contact-check.php');
          if($error_mes):
              include('contact-input.php');
          else:
              include('contact-confirm.php');
          endif;

          break;
      default:
      /////////////////////////////////////////////////////////////////////////////
      // 新規入力画面を表示

          include('contact-input.php');

      endswitch;

      /* ↓↓↓↓↓↓↓↓↓↓ ここから下部は page.php のフッターのコピペ ↓↓↓↓↓↓↓↓↓↓  */
      ?>      
      </div>
		</div><!-- /st-main -->
	</div>
	<!-- /#contentInner -->
	<?php get_sidebar(); ?>
</div>
<!--/#content -->
<?php get_footer(); ?>

フォーム入力用テンプレート

バリデーションに関しては、追々カスタマイズしてjsでのリアルタイム判定へ変更しようと思います。

contact-input.php

<?php
/*******************************
 固定ページ お問い合わせ
 お問い合わせフォーム 入力画面
*******************************/
// 不正アクセスチェック
if(!$noindexaccess){
    header("HTTP/1.0 404 Not Found");exit();
}
?>
<ul class="step-wrap">
  <li class="step-item current"><span>内容入力</span></li>
  <li class="step-item"><span>内容確認</span></li>
  <li class="step-item"><span>完了</span></li>
</ul>

<div style="color:red;">
<?php // エラーメッセージがあったら表示する
echo ($error_mes)?'
---------------------<br />
 入力エラーです<br />
---------------------<br />'.$error_mes:"";?>
</div>
 
<form name="toiawase" method="post" enctype="multipart/form-data" action="<?php echo esc_url( home_url( '/contact/' ) ); ?>">
    <div class="form-item">
        <div class="label"><label>名前</label><span>必須</span></div>
        <input type="text" name="namae" size="40" maxlength="60" value="<?php echo ($namae)?$namae:"";?>" required />
    </div>
    <div class="form-item">
        <div class="label"><label>メールアドレス</label><span>必須</span></div>
        <input type="email" name="email" size="40" maxlength="200" value="<?php echo ($email)?$email:"";?>" required />
    </div>
    <div class="form-item">
        <div class="label"><label>メッセージ</label><span>必須</span></div>
        <textarea name="message" cols="40" rows="10" required><?php echo ($message)?$message:"";?></textarea>
    </div>
    <div class="form-item form-btn">
        <input type="submit" value="送信する" />
        <input type="hidden" name="action" value="confirm">
    </div>
</form>

フォームチェック用テンプレート

contact-check.php

<?php
/*******************************
 固定ページ お問い合わせ
 お問い合わせフォーム 文字列チェック
*******************************/
// 不正アクセスチェック
if(!$noindexaccess){
    header("HTTP/1.0 404 Not Found");exit();
}
 
/* 危険文字列置換ファンクション */
function Chk_StrMode($str){
 
    // タグを除去
    $str = strip_tags($str);
    // 空白を除去
    $str = mb_ereg_replace("^( ){0,}","",$str);
    $str = mb_ereg_replace("( ){0,}$","",$str);
    $str = trim($str);
    // 特殊文字を HTML エンティティに変換する
    $str = htmlspecialchars($str);
     
    return $str;
}
/* 未入力チェックファンクション */
function Chk_InputMode($str,$mes){  
    $errmes = "";
    if($str == ""){$errmes .= "{$mes}<br>\n";}
    return $errmes;
}
 
/* メールアドレスチェックファンクション 2017.9.1現在 参考サイト:http://wepicks.net/phpsample-preg-mail/ */
function CheckEmailAddress($sMailaddress) {
    if(preg_match('/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22))(?:\.(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-[a-z0-9]+)*)|(?:\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\]))$/iD', $sMailaddress)){
        list($username,$domain)=explode('@',$sMailaddress);
        if(!checkdnsrr($domain,'MX')){
            return false;
        }
    return true;
    }
return false;
}
 
#----------------------------------------------------------------------------------
# データの受け取りと危険文字列置換  ※Chk_StrMode(文字列);
#----------------------------------------------------------------------------------
$param = array();
 
// 引数を元に文字列処理及び変換処理を行う
foreach($_POST as $k=>$e):
    $params[$k] = Chk_StrMode($e);
endforeach;
 
// 変数に入れる
extract($params);
 
#----------------------------------------------------------------------------------
# エラーチェック   ※Chk_InputMode(文字列,モード,エラーメッセージ);
#----------------------------------------------------------------------------------
$error_mes .= Chk_InputMode($namae,"・お名前をご記入ください。<br />\n");
 
$error_mes .= Chk_InputMode($email,"・メールアドレスをご記入ください。<br />\n");
 
// メールアドレスチェック
if($email){ 
    if(CheckEmailAddress($email) != true){
        $error_mes .= "・メールアドレスの形式に誤りがあります。<br />\n";
    }
}
$error_mes .= Chk_InputMode($message,"・お問い合わせ内容をご記入ください。<br />\n");
?>

入力内容の確認

contact-confirm.php

<?php
/*******************************
 固定ページ お問い合わせ
 お問い合わせフォーム 確認画面
*******************************/
// 不正アクセスチェック
if(!$noindexaccess){
    header("HTTP/1.0 404 Not Found");exit();
}?>
 
<script>
//2重送信防止スクリプト
var flg_Submit = false;
function Fnk_DoubleSubmit(){
  if(flg_Submit){
    alert("処理中です。");return false;
  }
  else{
    flg_Submit = true;return true;
  }
}
</script>
<ul class="step-wrap">
  <li class="step-item"><span>内容入力</span></li>
  <li class="step-item current"><span>内容確認</span></li>
  <li class="step-item"><span>完了</span></li>
</ul>

<p>以下の内容でよろしければ[送信する]ボタンを押してください。</p>
<form name="toiawase2" method="post" enctype="multipart/form-data" action="<?php echo esc_url( home_url( '/contact/' ) ); ?>" onsubmit="return Fnk_DoubleSubmit();">
    <div class="form-item">
        <div class="label"><label>名前</label><span>必須</span></div>
        <p style="background:#f8f8f8;"><?php echo ($namae)?$namae:"";?></p><input name="namae" type="hidden" value="<?php echo ($namae)?$namae:"";?>" />
    </div>
    <div class="form-item">
        <div class="label"><label>メールアドレス</label><span>必須</span></div>
        <p style="background:#f8f8f8;"><?php echo ($email)?$email:"";?></p><input name="email" type="hidden" value="<?php echo ($email)?$email:"";?>" />
    </div>
    <div class="form-item">
        <div class="label"><label>メッセージ</label><span>必須</span></div>
        <p style="background:#f8f8f8;"><?php echo ($message)?nl2br($message):"";?></p><input name="message" type="hidden" value="<?php echo ($message)?$message:"";?>" />
    </div>
    <div class="form-item form-btn">
        <input type="submit" value="送信する" />
        <input type="hidden" name="action" value="completion">
    </div>
</form>

送信用のプログラム

contact-sendmail.php

<?php
/*******************************
 固定ページ お問い合わせ
 お問い合わせフォーム メール送信
*******************************/
// 不正アクセスチェック
if(!$noindexaccess){
    header("HTTP/1.0 404 Not Found");exit();
}
 
#-------------------------------------------------------------------------------------------
# メール送信処理1(お客様への返信メール)
#-------------------------------------------------------------------------------------------
// メール本文
$mailbody = "この度はお問い合わせいただきありがとうございます。
1週間以上経過しても返信がない場合は、
お手数をお掛けいたしますが、下記までお問い合わせください。
 
────────────────────────────────
 <お問い合わせ先>
 ".WEBMST_NAME."
 E-MAIL: ".WEBMST_MAIL."
────────────────────────────────";
 
// 件名とフッター
$subject = WEBMST_NAME."Mail from Form";
$headers = "Reply-To: ".mb_encode_mimeheader(WEBMST_NAME)."<".WEBMST_MAIL.">\n";
$headers .= "Return-Path: ".WEBMST_MAIL."<".WEBMST_MAIL.">\n";
$headers .= "From:".mb_encode_mimeheader(WEBMST_NAME)."<".WEBMST_MAIL.">\n";
 
// メール送信(失敗時:強制終了)
$usrmail_result = mb_send_mail($email,$subject,$mailbody,$headers);
if(!$usrmail_result)die("メール送信に失敗しました。<br />\n
                         誠に申し訳ございませんがこちらまでご連絡ください。“".WEBMST_MAIL."”");
 
#-------------------------------------------------------------------------------------------
# メール送信処理2(送信先は $mailto宛)
#-------------------------------------------------------------------------------------------
// 件名を設定
$subject = "【お問い合わせ】";
 
// Headerとbodyとsubjectを設定(送信元はお客様 $email)
$headers = "Reply-To: ".mb_encode_mimeheader(WEBMST_NAME)."<".WEBMST_MAIL.">\n";
$headers .= "Return-Path: ".mb_encode_mimeheader(WEBMST_NAME)."<".WEBMST_MAIL.">\n";
$headers .= "From:".mb_encode_mimeheader(WEBMST_NAME)."<".WEBMST_MAIL.">\n";
 
// メール本文
$mailbody = "サイトよりお問い合わせを受け付けました。
 
────────────────────────────────
 
■名前: $namae 様より
 
■メールアドレス: $email
 
■メッセージ:
$message
 
────────────────────────────────
";
 
// メール送信実行
if(!empty($mailto)){
    $sendmail_result = mb_send_mail($mailto,$subject,$mailbody,$headers);
     
    if(!$sendmail_result){
        die("<p>メール送信に失敗しました。<br>\n誠に申し訳ございませんが最初から操作をやり直してください。</p>");
    }
}
else{
    die("<p>メールを送信する事が出来ませんでした。<br>\n誠に申し訳ございませんが“".WEBMST_MAIL."”へ直接メールにて<br>お問い合わせしていただけますようお願い申し上げます。</p>");
}
?>

送信完了画面

GAでの計測する場合にはこのページをゴール地点に設定すればカウント可能になります。この辺りはページ遷移ありの方が設定も容易ですね。

contact-completion.php

<?php
/*******************************
 固定ページ お問い合わせ
 お問い合わせフォーム 完了画面
*******************************/
// 不正アクセスチェック
if(!$noindexaccess){
  header("HTTP/1.0 404 Not Found");exit();
}
?>
<ul class="step-wrap">
  <li class="step-item"><span>内容入力</span></li>
  <li class="step-item"><span>内容確認</span></li>
  <li class="step-item current"><span>完了</span></li>
</ul>

<p>メールフォームよりご依頼を受け付けました、ありがとうございます。<br />
後日メールにてご連絡させていただきます。<br />
内容によってはご返信に時間がかかる場合がございますのでご了承下さい。</p>

管理画面の固定ページからテンプレートを選択

前項までの6つのPHPファイルをテーマディレクトリ内に作成したら、管理画面から固定ページ→新規追加と進み【固定ページの属性】で【contact-index】を選択してください。

テンプレート選択項目

おまけ

ついでにざっくりスタイリング用のCSSも載せておきます。レスポンシブ化はしていないので必要に応じて要修正。

.form-item:not(:last-of-type) {
  margin-bottom: 1rem;
}
.form-item .label {
  margin-bottom: 0.5rem;
  display: -webkit-flex;
  display: flex;
  -webkit-align-items: center;
  align-items: center;
}

form input[type="submit"], form input button {
  -moz-transition: 0.5s;
  -o-transition: 0.5s;
  -webkit-transition: 0.5s;
  transition: 0.5s;
  width: 240px;
  height: 48px;
  line-height: 48px;
  display: block;
  margin: 1rem auto;
  background-color: #4a4a4a;
  color: white;
}
form input[type="submit"]:hover, form input button:hover {
  background-color: rgba(238, 208, 105, 0.8);
  color: #4a4a4a;
  border-color: #4a4a4a;
}
form label + span {
  font-size: 8px;
  font-size: 0.66667rem;
  display: inline-block;
  vertical-align: middle;
  *vertical-align: auto;
  *zoom: 1;
  *display: inline;
  background-color: lightcoral;
  color: white;
  padding: 0.2rem;
  margin-left: 0.4rem;
}

.post .step-wrap {
  padding: initial;
  margin: initial;
  border: 1px solid #ccc;
  margin: 1rem auto 2rem auto;
  -moz-border-radius: 4px;
  -webkit-border-radius: 4px;
  border-radius: 4px;
}
.post .step-wrap, .post .step-wrap .step-item {
  display: -webkit-flex;
  display: flex;
  -webkit-justify-content: center;
  justify-content: center;
  -webkit-align-items: center;
  align-items: center;
  height: 60px;
  list-style: none;
}
.post .step-wrap .step-item {
  padding: initial;
  width: calc(100%/3);
  position: relative;
}
.post .step-wrap .step-item.current {
  font-weight: bold;
}
.post .step-wrap .step-item.current, .post .step-wrap .step-item.current:after {
  background: #eed069 !important;
}
.post .step-wrap .step-item:not(:last-child):after {
  z-index: 1;
  content: "";
  width: 42px;
  height: 42px;
  border: 0px;
  border-top: solid 1px #ccc;
  border-right: solid 1px #ccc;
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
  transform: rotate(45deg);
  position: absolute;
  right: -22px;
  background-color: white;
}

まとめ

プラグインなしでの実装は今回で二度目になるんですが、プラグインを使用した場合に比べると手間は増えますし、動作チェックも面倒だったりということもあるので特にこだわりがないようであればプラグインの利用でも良いかなと思います。

今回実装したフォームは実際に当ブログ内に設置しているものなのでデモはこちらをご覧ください。

お問い合わせフォーム

ダブルレクタングルからレスポンシブへ




ダブルレクタングルからレスポンシブへ




-WEB制作
-

執筆者:

関連記事

Android版Chromeでvideoタグの自動再生がされない時の解決方法

かなりハマった上に自動再生に対応したのも最近のせいか、調べてもなかなかヒットしなかったので忘れないうちに備忘録としてメモ。 そもそもの経緯としては製品LPを作成後、PageSpeed Insights …

【PHP】foreachを指定回数で抜ける方法。ループ処理のパフォーマンス比較も

TwitterのAPIを使おうと思い組み込んでみたものの全件取得はうっとうしすぎるので取得数を制限することに。 基本的な事ですがしょっちゅう忘れるので備忘録。 $twObj = new Twitter …

UI/UX

AdobeXDで三角形を作成する方法。正三角形はフォトショかイラレからのコピペの方がオススメ

結論から言うとAdobeXDだけで三角形(正三角形)を作成するよりも、フォトショかイラレで作成してCreativeCloudライブラリで共有した方が100倍早いです。とはいえ、AdobeXDは無料で利 …

Googleアナリティクスのapiを使ってWordPressのPVなどのアクセスデータを取得しよう

よく記事のPVやアクセス数順にランキング形式でサイドバーなどに表示させているブログやウェブサイトをご覧になったことがあるかと思います。 正直な話、JetPack辺りのプラグインを使えば実装も容易なので …

ニックネーム
DeLux
プロフィール

30代の東京生活に疲れたWEBエンジニア。
好きなことで生きて行きたいがためにあれこれと手を出してます。
主にAdobe、Google、Apple、SONY辺りの記事とコーディングやプログラム、たまに動画編集やデザインなどのTips的な記事を更新してます。

ガジェットも大好きなのでその辺りもぼちぼち増やす予定。