投稿日:2023年9月16日

仕事上、イベントの申し込みフォームやアンケートフォームを作ることが多々あり、色々な要望を受けます。
以前、こちらの記事 で申し込みをしたユーザーが、アンケートフォームでどのような回答をしたか、紐付けたい。
という内容のものを書きました。

このような感じです。

▲申し込みフォーム。今回は名前とメールアドレスのみにしました。

▲送信すると確認メールが届きます。
アンケートフォームに遷移するURLには下図のようにContact Form 7の返信メールにシリアルナンバー(ID)とユーザー名をパラメータで付与するようにしてあります。
しかし、これではユーザー名がURL欄に表示され不信感を与える可能性があります。

URL

▲露骨に名前が表示されると不信感を与えます。

ユーザー名をエンコード表示するよう下のようなプログラムを書きました。

//ブラウザのURLの氏名をエンコードする
jQuery(function ($) {
  // アンケートフォームページにパラメータから取得したID値と氏名を入力
  let query = location.search; //パラメータを取得
  let valueAmpersand = query.split(/=|&/); //「=」か「&」で分割
  $("#receiptNum").val(decodeURIComponent(valueAmpersand[1])); //デコードして「申し込み時の受付番号」にid値を入力
  $("#name").val(decodeURIComponent(valueAmpersand[3])); //デコードして「氏名」に氏名を入力

  // ▼▼▼ URLパラメータを書き換える
  let urlSearchParams = new URLSearchParams(location.search); //パラメータ
  urlSearchParams.set("person", valueAmpersand[3]); //personパラメータにエンコードされた氏名をセット
  history.replaceState("", "", `?${urlSearchParams.toString()}`); //履歴エントリーを置換

  // ▼▼▼ リロードした場合
  if (window.performance) {
    if (window.performance.navigation.type === 1) {
      urlSearchParams.set("person", decodeURIComponent(valueAmpersand[3])); //personパラメータにエンコードされた氏名をセット
      history.replaceState("", "", `?${urlSearchParams.toString()}`); //履歴エントリーを置換
      $("#name").val(decodeURIComponent(decodeURIComponent(valueAmpersand[3]))); //パーセントエンコードのためデコードが2回必要
    }
  }
});

▲エンコードされました。
上のプログラムではアンケートフォームに受付番号(ID)とユーザー名が自動で入力されるようデコードする処理も書かれています。

▲受付番号(ID)とユーザー名が自動で入力されます。

▲申し込みフォーム(IDと名前)とアンケートフォーム(感想)のデータをそれぞれのデータベースから取得し、結合表示させたところです。
CSVダウンロードボタンをクリックすると結合したCSVをダウンロードします。

ソースコードです。

<?php
session_start();
?>
<!DOCTYPE html>
<html lang="ja">

<head>
  <!-- 省略 -->
</head>

<body>
  <?php
  $db_user = "xxxxxxxxxx"; //ユーザー名
  $db_pass = "xxxxxxxxxx"; //パスワード
  $db_host = "xxxxxxxxxx"; //ホスト名
  $db_name01 = "xxxxxxxxxx_test"; //申し込みフォームデータベース名
  $db_name02 = "xxxxxxxxxx_enq"; //アンケートフォームデータベース名
  $db_type = "mysql"; //データベースの種類
  $dns01 = "$db_type:host=$db_host;dbname=$db_name01;charset=utf8"; //申し込みフォームデータベース接続準備
  $dns02 = "$db_type:host=$db_host;dbname=$db_name02;charset=utf8"; //アンケートフォームデータベース接続準備

  try {
    // 申し込みフォームデータベースに接続
    $pdo01 = new PDO($dns01, $db_user, $db_pass);
    $pdo01->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo01->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    // アンケートフォームデータベースに接続
    $pdo02 = new PDO($dns02, $db_user, $db_pass);
    $pdo02->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo02->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
  } catch (PDOException $Exception) {
    die('接続エラー:' . $Exception->getMessage());
  }

  //フィールドform_idを取得
  $idStmt = $pdo01->prepare("SELECT form_id FROM wp_db7_forms");
  $idStmt->bindValue(':form_id', 'form_id', PDO::PARAM_INT);
  $idRes = $idStmt->execute();

  //フィールドform_valueを取得(ここに申し込みフォームの情報が格納されている)
  $val01Stmt = $pdo01->prepare("SELECT form_value FROM wp_db7_forms");
  $val01Stmt->bindValue(':form_value', 'form_value', PDO::PARAM_INT);
  $val01Res = $val01Stmt->execute();

  //フィールドform_valueを取得(ここにアンケートフォームの情報が格納されている)
  $val02Stmt = $pdo02->prepare("SELECT form_value FROM wp_db7_forms");
  $val02Stmt->bindValue(':form_value', 'form_value', PDO::PARAM_INT);
  $val02Res = $val02Stmt->execute();

  //フィールドform_post_idを取得 ※固定ページのID
  $postIdStmt = $pdo01->prepare("SELECT form_post_id FROM wp_db7_forms");
  $postIdStmt->bindValue(':form_post_id', 'form_post_id', PDO::PARAM_INT);
  $postIdRes = $postIdStmt->execute();

  //タイムスタンプform_dateを取得
  $timeStampStmt = $pdo01->prepare("SELECT form_date FROM wp_db7_forms");
  $timeStampStmt->bindValue(':form_date', 'form_date', PDO::PARAM_INT);
  $timeStampRes = $timeStampStmt->execute();

  //flagを取得(チェックボックスのflag)
  $flagStmt = $pdo01->prepare("SELECT flag FROM wp_db7_forms");
  $flagStmt->bindValue(':flag', 'flag', PDO::PARAM_INT);
  $flagRes = $flagStmt->execute();

  // lagが1の数(チェックボックスのflag)
  $flagTrueStmt = $pdo01->prepare("SELECT flag FROM wp_db7_forms  WHERE `flag` = '1'");
  // $flagTrueStmt->bindValue(':flag', 'flag', PDO::PARAM_INT);
  $flagTrueRes = $flagTrueStmt->execute();

  if ($idRes && $val01Res && $postIdRes && $timeStampRes && $flagRes && $val02Res) {
    $postIdData = $postIdStmt->fetchAll(PDO::FETCH_COLUMN); //fetchAllじゃないと取得できない
    $val01Data = $val01Stmt->fetchAll(PDO::FETCH_COLUMN); //testのデータベース
    $val02Data = $val02Stmt->fetchAll(PDO::FETCH_COLUMN); // enqのデータベース
    $idData = $idStmt->fetchAll(PDO::FETCH_COLUMN);
    $timeStampData = $timeStampStmt->fetchAll(PDO::FETCH_COLUMN);
    $flagData = $flagStmt->fetchAll(PDO::FETCH_COLUMN);
    $flagTrueData = $flagTrueStmt->fetchAll(PDO::FETCH_COLUMN);

    // ------------------------------------------------------------------------------------------
    // ▼▼▼ 申し込みフォームから出力
    echo ("<table cellspacing='0' id='csvTarget'><tbody id='trWrap'>"); //tableタグ出力
    foreach ($val01Data as $i => $val01Val) { //ループで書き出し
      $id = $idData[$i]; //ID
      $postId = $postIdData[$i]; // 固定ページのID
      $unserializeArr01 = unserialize($val01Val); //アンシリアル化(復元)
      $nameVal01 = $unserializeArr01["your-name"]; //氏名
      $timeStampVal = $timeStampData[$i]; //タイムスタンプ
      $flagVal = $flagData[$i]; //flag
      $flagTrueCnt = count($flagTrueData); //flagが1の数
      // テーブルコンテンツ作成
      echo ('<tr id="id_' . $id . '"><td>' . $id . '</td><td>' . $nameVal01 . '</td><td class="radioBtn"></td><td class="flag" hidden>' . $flagVal . '</td><td><form name="checkForm"><input type="checkbox" name="checkbox"></form></td></tr>'); //table内trを出力
    }
    echo ("</tbody></table>"); //閉じタグ
    // ------------------------------------------------------------------------------------------

    // ------------------------------------------------------------------------------------------
    // ▼▼▼ アンケートフォームから出力
    echo ("<table cellspacing='0' id='csvTarget02' hidden><tbody id='trWrap02'>"); //tableタグ出力(hiddenで非表示)
    foreach ($val02Data as $j => $val02Val) { //ループで書き出し
      $unserializeArr02 = unserialize($val02Val); //アンシリアル化(復元)
      $nameVal02 = $unserializeArr02["your-name_enq"]; //アンケートの氏名
      $receptionId = $unserializeArr02["text-261"]; //受付時のID
      $radioBtn = $unserializeArr02["radio-554"]; // アンケートのラジオボタン
      // テーブルコンテンツ作成
      echo ('<tr class=id__' . $receptionId . '"><td class="idNum">' . $receptionId . '</td><td class="radioBtnResult">' . $radioBtn[0] . '</td></tr>');
    }
    echo ("</tbody></table>"); //閉じタグ
    // ------------------------------------------------------------------------------------------
  }
  ?>

  <!-- ------------------------------------------------------------------------------------------ -->
  <!-- ▼▼▼ HTML -->
  <div id="inputDisplay">
    <div>
      <input name="inputTxt" id="inputTxt" cols="30" rows="10">
    </div>
  </div>

  <form action="">
    <a id="csvBtn">CSVダウンロード</a>
  </form>
  <!-- ------------------------------------------------------------------------------------------ -->


  <script defer src="form.js"></script>

  <script defer>
    let receptionLength = $('#csvTarget02 tr').length;
    $('#receptionLength').text(receptionLength); // アンケート回答数に値を表示
    for (let l = 0; l < receptionLength; l++) {
      let idNum = $('.idNum').eq(l).text();
      let radioBtnResult = $('.radioBtnResult').eq(l).text();
      $('#csvTarget tr .radioBtn').eq(idNum - 1).text(radioBtnResult);
    }
  </script>
</body>

</html>

▲16〜33行目で2つのデータベースの設定、接続を行っています。
22行目のからの try 文でデータベースから取得する内容を設定しています。
タイムスタンプは今回使用しません。
70行目の if 文からそれぞれのデータベースからのタグ出力を行います。ループで登録数分出力します。
97行目、アンケートフォームからの出力は table hidden で非表示にしています。この非表示の table から内容だけを取得し、128行目の script で申し込みフォームの table ID値を照合させ出力する仕様にしています。

CSV書き出しのJavaScriptはこちらの記事 を参照してください。

まとめ

Contact Form 7 Database Addon – CFDB7 は申し込み内容をデータベースに保存するとても便利なWordPressプラグインです。
しかし、複数のフォームを作った場合でも、独自に作るテーブルwp_db7_formsに全て保存してしまいます。
これではフォームごとの取得が困難です。

なので、今回のようにWordPressサイトを2つ構築しています。

プロ アドオンとして Contact form 7 Column Based MySQL Database Addon という便利なプラグインが発売されています。
検証してみたいと思います。

最後まで読んでいただき、ありがとうございました。

関連記事
Pocket