本記事は WordPress Advent Calendar 2021 12日目の記事です。
今回は、少し大がかりな Contact Form 7 の実装例をご紹介します。
同カレンダーの5日目には軽めの実装例をまとめた記事を投稿していますので、そちらもどうぞよろしくお願いします。
ACFで入力したメールアドレスを、パイプの値に反映する
公式では、フォームの選択内容によってメールの送信先を変える実装方法が紹介されています。
このメールの送信先、つまりパイプの値に、Advanced Custom Field(ACF)で入力した内容が反映されるようにする実装です。「コードは触りたくないけど色々設定を変更したい」というお客様向けですね。
※管理画面からフォームを編集すれば済む話ですし、それが最も望ましいことは言うまでもありません。
wpcf_form_tag というフィルターフックを使って、特定のフォームタグの内容を変更し、値を返して実装します。
ベースとなるコードは以下の参考記事に記載されています。
参考記事ではカスタム投稿タイプをもとに内容を変更していましたが、これをカスタムフィールドベースにして、パイプにも対応させます。
最終コードは以下の通りです。
function filter_wpcf7_form_tag( $scanned_tag, $replace ) {
	if(!empty($scanned_tag)){
		//内容を変更するフォームタグを判定
		if($scanned_tag['name'] == 'your-store'){
			// パイプの左側(表示するテキスト)を配列に格納
			// 今回は支店名を表示テキストとする
			$branchStore_labels = array(
				'A支店',
				'B支店',
				'C支店'
			);
			// ACFで登録した情報を格納する
			// 前提として、支店ごとに複数のメールアドレスをACFリピーターで登録しているものとする
			// A支店
			$a_mails = get_field('store-a');
			if($a_mails) {
				$no = 0;
				$last = count($a_mails) - 1;
				// リピーターで登録された複数のアドレスを、カンマで区切って配列に入れる
				foreach($a_mails as $a_mail) {
					switch ($no++) {
						case $last:
							$a_value = $a_value.$a_mail['store-a_mail'];
							break;
						default:
							$a_value = $a_value.$a_mail['store-a_mail'].',';
							break;
					}
				}
			}
			// 支店ごとに処理を繰り返す
			// B支店
			$b_mails = get_field('store-b');
			if($b_mails) {
				$no = 0;
				$last = count($b_mails) - 1;
				// リピーターで登録された複数のアドレスを、カンマで区切って配列に入れる
				foreach($b_mails as $b_mail) {
					switch ($no++) {
						case $last:
							$b_value = $b_value.$b_mail['store-b_mail'];
							break;
						default:
							$b_value = $b_value.$b_mail['store-b_mail'].',';
							break;
					}
				}
			}
			// 支店ごとに処理を繰り返す
			// C支店
			$c_mails = get_field('store-c');
			if($c_mails) {
				$no = 0;
				$last = count($c_mails) - 1;
				// リピーターで登録された複数のアドレスを、カンマで区切って配列に入れる
				foreach($c_mails as $c_mail) {
					switch ($no++) {
						case $last:
							$c_value = $c_value.$c_mail['store-c_mail'];
							break;
						default:
							$c_value = $c_value.$c_mail['store-c_mail'].',';
							break;
					}
				}
			}
			// 各表示テキストに、対応するメールアドレスをパイプで設定し、値を格納する
			foreach ($branchStore_labels as $branchStore_label) {
				// 「A支店」という表記に対してA支店のメールアドレスを格納し、
				// "A支店|hoge@a-store.com,fuga@a-store.com,piyo@a-store.com" という値を作る
				if($branchStore_label == 'A支店') {
					$scanned_tag['raw_values'][] = $branchStore_label.'|'.$a_value;
				}
				// 同様の処理をB支店とC支店でも行う
				if($branchStore_label == 'B支店') {
					$scanned_tag['raw_values'][] = $branchStore_label.'|'.$b_value;
				}
				if($branchStore_label == 'C支店') {
					$scanned_tag['raw_values'][] = $branchStore_label.'|'.$c_value;
				}
			}
			// パイプを使う準備
			$pipes = new WPCF7_Pipes($scanned_tag['raw_values']);
			// $scanned_tag の情報を書き換える
			$scanned_tag['values'] = $pipes->collect_befores();
			$scanned_tag['labels'] = $pipes->collect_befores();
			$scanned_tag['pipes'] = $pipes;
		}
	}
	// 値を返す
	return $scanned_tag;
};
add_filter( 'wpcf7_form_tag', 'filter_wpcf7_form_tag', 11, 2 );
何かうまくいかない場合は、var_dump($scanned_tag); で中身を確認してみましょう。
また、一度手作業で実装したときの $scanned_tag の中身を見ておくと、どの値を書き換えれば良いか分かると思います。
終わりに
実は前回のプライバシーポリシーの文章を出力する専用のフォームタグ作成 で紹介した、「独自のフォームタグを追加する」方法でも似たような実装をすることができます。
私自身、2回ほど下記の記事を参考に実装したことがあります。
ただ、こちらの方法を取る場合はバリデーションの定義も自分で行う必要があります。
普段使うフォームの形式やそのバリデーションの範囲で実装するのであれば、今回の wpcf_form_tag を使った手法のほうが魔改造凝ったことを比較的楽に実現できてオススメです。