カスタム投稿毎に管理者向けメールの送信先と各々のサンクスページに表示させる内容を動的に変更させる

先日以下のような相談があり、実装テストを行っていました。

  1. ユーザーがカスタム投稿からお問い合わせフォームに遷移し、入力後送信した場合にそれぞれ異なるメールアドレスに管理者向けメールを送信したい
  2. サンクスページにはそれぞれ異なる電話番号(連絡先)を表示させたい

なおContact Form 7 を使用するものとします

以下に書くことは僕が実際にテストし実装したものです。もしこれが違うよとか、こういった方法があると言った物があればTwitterにメッセージいただくと嬉しいです。

では本編

この記事の目次

下準備

まずテスト実装するにあたり、環境を整えます

  1. カスタム投稿「class」作成(名前は何でもいいです)
  2. Smart Custom Field(以下SCF)でメールアドレスと電話番号の入力欄を作成し、⒈に紐付ける
  3. 記事を数個作成する
  4. 「class」のシングルページ、コンタクトページ(送信先は設定しておく)、サンクスページを作成する

本章ではサンクスページの作り方等は省略します

実装の方法

では上記をどのように実装するか

まずメールアドレスなどをそれぞれカスタムフィールドで各記事毎に設定し、その値を呼び出して設定できればいいわけです

ただ遷移した先のコンタクトページやサンクスページには遷移元のIDが無いため、SCFの情報が取ってこれません

この辺りをどうするか考えながらやっていきます

実装手順

シングルページの情報をvar_dumpして見てみます

<?php
//ID取得
$this_id = get_the_ID(); 
var_dump($this_id);

//メールアドレスを取得
$email = get_post_meta($this_id, 'mail_address');
var_dump($email);

//電話番号を取得
$tel = get_post_meta($this_id, 'tel_number');
var_dump($tel);
?>

すると以下のように表示されますね

メールアドレス・電話番号は適当です

これらの情報を遷移した先で表示させていきます

シングルページのIDをPOSTで送信する

シングルページからコンタクトページへ単純に遷移させるだけだと、遷移先のページではSCFを呼び出すのに必要なIDが取れません。そこでformを使ってPOSTでIDを送信してあげます

<?php
//ID取得
$this_id = get_the_ID(); 
?>

<!-- POSTで送信する -->
<form action="/contact/" method="post">
  <input type="hidden" name="class_id" value="<?php echo $this_id; ?>">
  <input type="submit" value="お問い合わせする">
</form>

valueに送信したい値を入れ、methodはpost、actionは遷移先を指定します

リロードするとボタンが表示されるので、クリックしコンタクトページへ遷移させます

コンタクトページで送信されたIDを確認する

<?php
$class_id = $_POST['class_id']; //POSTで受け取ったID
var_dump($class_id);
?>

formのnameで指定したものを[]内に入れてください

これでIDが表示されれば無事受け取ることができています

ついでにSCFで設定した中身も確認します

<?php
$class_id = $_POST['class_id']; //POSTで受け取ったID
var_dump($class_id);

$email = get_post_meta($class_id, 'mail_address'); //メールアドレス
var_dump($email);

$tel = get_post_meta($class_id, 'tel_number'); //電話番号
var_dump($tel);
?>

フォームを埋めていざ送信!といきたいところですが、コンタクトフォームで作成した送信ボタンでは受け取ったIDを次のコンタクトページに送信することができません

そこでセッションも使用することにします

シングルページでセッションを開始する

シングルページに戻り、セッションを開始させます

<?php
//ID取得
$this_id = get_the_ID();
$s_class = get_the_title($this_id); //タイトル
$s_email = get_post_meta($this_id, 'mail_address')[0]; //メールアドレス
$s_tel = get_post_meta($this_id, 'tel_number')[0]; //電話番号

echo '<h3>session start</h3>';

//セッションスタート
session_start();
$_SESSION['s_this_id'] = $this_id; //IDをセッション
$_SESSION['s_class'] = $s_class; //タイトルをセッション
$_SESSION['s_email'] = $s_email; //メールアドレスをセッション
$_SESSION['s_tel'] = $s_tel; //電話番号をセッション
$_SESSION['s_this_id'] = $this_id; //IDをセッション

echo '<p>s_class = ' . $_SESSION['s_class'] . '</p>';
echo '<p> s_email = ' . $_SESSION['s_email'] . '</p>';
echo '<p>s_tel = ' . $_SESSION['s_tel'] . '</p>';
?>

echo部分は確認のために記述しています

すると以下のような感じで表示されると思います

これでセッションからも情報を取得できるようになりました

コンタクトページでセッションを表示させる

先ほど取ったセッションの情報を呼び出してみます

<?php
$class_id = $_POST['class_id']; //POSTで受け取ったID

//セッションスタート
session_start();
echo '<h3>session start</h3>';

echo '<p>s_this_id = ' . $_SESSION['s_this_id'] . '</p>';
echo '<p>s_class = ' . $_SESSION['s_class'] . '</p>';
echo '<p>s_email = ' . $_SESSION['s_email'] . '</p>';
echo '<p>s_tel = ' . $_SESSION['s_tel'] . '</p>';
?>

これでセッション情報を使用してサンクスページにもSCFで設定した情報を表示できる

…のですが、ここで問題が発生します

複数タブを開くとセッション不具合が起こる

複数タブを開くとセッションが以前の情報のままになり、現在の情報と相違が発生します

例えばカスタム投稿のシングルAページからコンタクトページに遷移し、別の新規タブで同様にシングルBページからコンタクトページに遷移してみてください

下のように現在の情報とセッション情報に相違が出ることが分かります

つまりAページの途中でやめてBページでフォーム送信してしまうと、送信したいアドレスにメールを飛ばすことやサンクスページに意図したものの表示が出来なくなってしまいます

そこで以下のようにifで条件をつけてあげます

<?php
$class_id = $_POST['class_id']; //POSTで受け取ったID

//セッションスタート
session_start();
echo '<h3>session start</h3>';

if ($_SESSION['s_this_id'] == $class_id) {
  //現在ページのIDと渡されたセッションIDが一致する場合
  echo '<p>ページIDとセッションIDが一致します</p>';
} else { //現在ページのIDと渡されたセッションIDが一致しない場合
  echo '<p>$class_id = ' . $class_id . ' and $_SESSION[\'s_this_id\'] = ' . $_SESSION['s_this_id'] . ' are not equal.</p>';
  echo '
    <p>ページIDとセッションIDが異なります</p>
    <p>その場合セッションを一度リセットし、再設定します</p>
    ';
  //セッションをリセット
  unset($_SESSION['s_this_id']);
  unset($_SESSION['s_class']);
  unset($_SESSION['s_email']);
  unset($_SESSION['s_tel']);
  //セッションの再設定
  $this_id = $class_id; //POSTされたIDを代入
  $class_name = get_the_title($this_id); //タイトル(教室名)
  $s_email = get_post_meta($this_id, 'mail_address')[0]; //メールアドレス
  $s_tel = get_post_meta($this_id, 'tel_number')[0]; //電話番号
  $_SESSION['s_this_id'] = $this_id; //IDをセッション
  $_SESSION['s_class'] = $class_name; //タイトルをセッション
  $_SESSION['s_email'] = $s_email; //メールアドレスをセッション
  $_SESSION['s_tel'] = $s_tel; //電話番号をセッション
}

echo '<p>s_this_id = ' . $_SESSION['s_this_id'] . '</p>';
echo '<p>s_class = ' . $_SESSION['s_class'] . '</p>';
echo '<p>s_email = ' . $_SESSION['s_email'] . '</p>';
echo '<p>s_tel = ' . $_SESSION['s_tel'] . '</p>';
?>

現在表示しているページのIDとセッションIDが異なる場合は一度セッションをリセットし、再度セッションしなおします

サンクスページに任意の情報を表示

ここまで来ればあとはセッション情報を引っ張ってくるだけです

<?php if( $_SESSION['s_class'] && $_SESSION['s_email'] ) : ?>
<p class="contact__class"><?php echo $_SESSION['s_class']; ?></p>
<p class="contact__tel">連絡先:<?php echo $_SESSION['s_tel']; ?></p>
<?php endif; ?>

<?php 
  //セッションをリセット
  unset($_SESSION['s_this_id']);
  unset($_SESSION['s_class']);
  unset($_SESSION['s_email']);
  unset($_SESSION['s_tel']);
?>

送信先の書き換え

管理者メールの送信先をfunctions.phpで書き換えます

以下参考にさせていただきました

Gist
コンタクトフォーム7でフォームの送信先を動的に変更したい機会があり、無理やり書き換えることを試みた。 コンタクトフォーム7でフォームの送信先を動的に変更したい機会があり、無理やり書き換えることを試みた。 - WP-contactform7_recipient_overwrite.php
define( "O_SYSTEM_CRYPT_KEY" 	, "kokoniangouKEYwoireteNE!!" ); // 暗号化キー
define( "REPLACE_MAIL_ADDRESS" 	, "sample@example.com" ); //置換対象となるメールアドレス(CF7の送信先で指定)

// コンタクトフォーム7にhiddenフィールドを追加
function oc_wpcf7_form_hidden_fields( $hidden  ) {
  $email = get_post_meta($_SESSION['s_this_id'], 'mail_address')[0]; // 送信したいアドレスをhiddenフィールドに暗号化して設定しておく
	$cript_mail = openssl_encrypt($email, 'AES-128-ECB', O_SYSTEM_CRYPT_KEY);
	$hidden["_wpcf7_mail"] = $cript_mail;
	return $hidden;
}
add_filter( 'wpcf7_form_hidden_fields', 'oc_wpcf7_form_hidden_fields');

// 送信時に書き換え、暗号化解除
function oc_wpcf7_mail_components( $components ) {
	if( $components['recipient'] == REPLACE_MAIL_ADDRESS && $_POST['_wpcf7_mail'] ) {
		$cript_mail = $_POST['_wpcf7_mail'];
		$email = openssl_decrypt($cript_mail, 'AES-128-ECB', O_SYSTEM_CRYPT_KEY);
		if( $email ) {
			$components['recipient'] = $email;
		}
	}
	return $components;
}
add_filter( 'wpcf7_mail_components', 'oc_wpcf7_mail_components');

送信先に設定したメールアドレスをセッションしたものに置き換えています。これによってシングルページ毎に設定したアドレスに管理者メールが飛ぶようになります

ちなみに正しく値が取れているかどうかは以下を試してみると良いです

$file_path =  __DIR__ . '/value_check.log';
file_put_contents($file_path, print_r($email, true));

参考にさせていただきました

TipsWeb
【WordPress/PHP】functions.phpでフックなどの中身の値をデバッグする方法 | TipsWeb WordPress構築をしているときにデバッグは必要不可欠です。 print_rやvar_dumpを用いてデバッグしますよね。 例えば、taxnomony.phpで現在表示中のタームのスラッグを取得...

最後に

それぞれ違うメールアドレスに送信したいという情報がなかなかなくて、最初はパイプ機能を動的にしようと試したり、色々と検索・検証を重ねた結果今のような形になりました

何かの参考になれば嬉しいです

この記事が気に入ったら
フォローしてね!

シェアしてね!!
  • URLをコピーしました!

著者

Webコーダー。
ドライブとコーヒーとガジェットが好き。
「Code Widgit」は「Code With it」と「gadget」を合わせた造語。

この記事の目次
閉じる