先日以下のような相談があり、実装テストを行っていました。
- ユーザーがカスタム投稿からお問い合わせフォームに遷移し、入力後送信した場合にそれぞれ異なるメールアドレスに管理者向けメールを送信したい
- サンクスページにはそれぞれ異なる電話番号(連絡先)を表示させたい
なおContact Form 7 を使用するものとします
以下に書くことは僕が実際にテストし実装したものです。もしこれが違うよとか、こういった方法があると言った物があればTwitterにメッセージいただくと嬉しいです。
では本編
下準備
まずテスト実装するにあたり、環境を整えます
- カスタム投稿「class」作成(名前は何でもいいです)
- Smart Custom Field(以下SCF)でメールアドレスと電話番号の入力欄を作成し、⒈に紐付ける
- 記事を数個作成する
- 「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で書き換えます
以下参考にさせていただきました
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));
参考にさせていただきました
最後に
それぞれ違うメールアドレスに送信したいという情報がなかなかなくて、最初はパイプ機能を動的にしようと試したり、色々と検索・検証を重ねた結果今のような形になりました
何かの参考になれば嬉しいです