Contact Form 7でメールアドレスの再入力チェック機能を実装する方法

プラグイン                

  公開日:2020年9月23日  最終更新日:2021年1月27日

WordPressのプラグインContact Form 7でメールアドレスの再入力チェック機能をつけるカスタマイズ方法です。

一般的なお問い合わせフォームでメールアドレスといえば、連絡手段として非常に重要な項目ですが、人が入力する限り入力ミスは避けられません。
もし間違ったメールアドレスを入力されてしまったら折角のリード(=興味関心を持つ見込み客)と連絡が取れなくなってしまいますので、間違いないメールアドレス入力いただきたいものです。
その為に、もう一度メールアドレス確認用エリアにメールアドレスを再度入力していただき、前のデータと齟齬がないか確認する機能です。

もうデフォルトで実装してくれてもいいんじゃないかと言うくらいの定番機能ですね。

2021年1月26日 加筆修正
下記「実装方法」に記載のコードの一部で、全角文字が使用されており、コピペでは動作しない、とのご指摘をいただきました。
確認したところ、9,10行目の先頭部分の空白が全角スペースとなっており、コードそのままコピペでは動作しないことが確認できました。
本日改修版コードに入れ替えましたので、2021年1月26日以前に参考にされた方には、ご迷惑をお掛けして申し訳ございませんでした。
ここにお詫びして訂正いたします。

実装方法

メールアドレスの再入力チェック機能の実装手順としては3ステップ。

  1. functions.phpにコード貼り付け
  2. Contact Form 7でフォームを作成
  3. 動作確認

1,2は作業順は前後しても構いません。
1の作業は1度行えば、別のフォームを作る際には不要です。

functions.phpにコード貼り付け

まずは現在利用中テーマのfunctions.phpに以下のコードを追記します。
FTPでアップしてもいいし、テーマエディターで編集しても構いません。

add_filter( 'wpcf7_validate_email', 'wpcf7_validate_email_filter_confrim', 11, 2 );
add_filter( 'wpcf7_validate_email*', 'wpcf7_validate_email_filter_confrim', 11, 2 );
function wpcf7_validate_email_filter_confrim( $result, $tag ) {
    $type = $tag['type'];
    $name = $tag['name'];
    if ( 'email' == $type || 'email*' == $type ) {
        if (preg_match('/(.*)_confirm$/', $name, $matches)){ //確認用メルアド入力フォーム名を ○○○_confirm としています。
            $target_name = $matches[1];
                $posted_value = trim( (string) $_POST[$name] ); //前後空白の削除
                $posted_target_value = trim( (string) $_POST[$target_name] ); //前後空白の削除
            if ($posted_value != $posted_target_value) {
                $result->invalidate( $tag,"確認用のメールアドレスが一致していません");
            }
        }
    }
    return $result;
}

注意
2021年1月26日以前のコードには全角文字が含まれ、上記コードのコピペでは動作しません。見た目にはほとんど変化ありませんが、9,10行目の先頭に全角文字が含まれていましたので、半角スペースに訂正しております。

Contact Form 7でお問い合わせフォームを作成

次に、Contact Form 7でお問い合わせフォームを作成し、メールアドレス入力用のタグを挿入します。

画面キャプチャ:Contact Form 7でのフォーム作成イメージ
サンプルのフォーム

例えば、[email your-email]こんな感じ。
続けて、確認用メールアドレス入力用のタグを挿入。
[email your-email_confirm]こんな感じ。
フォームを保存して、ショートコードを適当な固定ページにでも貼り付ければ完成です。

動作確認

実行結果はこんな感じになります。
メールアドレスと確認用メールアドレスの値が違う場合、確認用メールアドレスの方に、メッセージが表示されます。
(フォーム体裁はCSSにて整えています。)

画面キャプチャ:実行時のイメージ
動作確認は必ず行いましょう

このカスタマイズで重要なのは、「タグの名前」(先ほどの例で言うと「your-email」や「your-email_confirm」の部分)です。
コード解説でも書きますが、確認用メールアドレスの名前は必ずメールアドレスのタグ名に「_confirm」を付けた名前にすることです。

コードの中で何をやっているか興味のある人は、続きをどうぞ!

コード解説

今回のカスタマイズでは、

add_filter( 'wpcf7_validate_email', 'wpcf7_validate_email_filter_confrim', 11, 2 );
add_filter( 'wpcf7_validate_email*', 'wpcf7_validate_email_filter_confrim', 11, 2 );

add_filterで始まる最初のこの2行でWordPressのフック機能を利用し、contact form 7のバリデーションロジックに今回の独自ロジックを割り込ませています。

function wpcf7_validate_email_filter_confrim( $result, $tag ) {

functionで始まる3行目からが、今回追加する「確認用メールアドレスチェック」の独自ロジックになります。

今回フックしたwpcf7_validate_emailとwpcf7_validate_email*では、$resultと$tagという、2つの引数を受け取ることができます。

$resultはバリデーションの結果情報
$tagはcontact form 7でフォームを作成した際に挿入した各種要素の情報です。

今回ならフォーム作成時に[email your-email]と言うようなタグを挿入したはずです。

 $type = $tag['type'];
 $name = $tag['name'];

4,5行目では、$tagからtype情報とname情報を取り出しています。
さっきの[email your-email]と言うタグなら、typeはemail、nameはyour-emailとなります。

    if ( 'email' == $type || 'email*' == $type ) {

6行目は、typeがemailまたはemail*(入力必須の場合のタグ)の場合に処理を限定しています。

        if (preg_match('/(.*)_confirm$/', $name, $matches)){ //確認用メルアド入力フォーム名を ○○○_confirm としています。
            $target_name = $matches[1];

7,8行目は、いま処理しているタグの名前に「_confirm」と言う文字列が含まれるかを判断し、同時にタグの名前の「_confirm」以外の部分を取得しています。
この辺りからの実装がこの機能の肝です。

                $posted_value = trim( (string) $_POST[$name] ); //前後空白の削除
                $posted_target_value = trim( (string) $_POST[$target_name] ); //前後空白の削除

9,10行目。ここで先ほど取得した『「_confirm」以外の部分』の文字列を利用して、フォームに入力されたデータを取得しています。その際、前後の不要な空白文字を削除しておきます。

実装方法で挿入したサンプルタグで説明すると、この処理自体は[email your-email_confirm]のタグを処理する際に機能します。
7,8行目でタグ名(今回の場合「your-email_confirm」)に「_confirm」が含まれるか?
含まれる場合、それ以外の文字列は何か?(今回の場合「your-email」)
を処理し、この9,10行目で入力さえれたデータ($_POST)から「your-email」と「your-email_confirm」の値を取り出し。

            if ($posted_value != $posted_target_value) {

11行目でその値を比較し、もし両データに違いがあれば、12行目を実行して、$resultにエラー情報を登録します。
11行目の比較で両データが同じなら、何もしません。

    return $result;

16行目。最後に$resultを返して終了です。

後述

今回、改めてこの記事を書くために他のサイトの記事も確認しました。
よく見かけるのは以下のコード(サイトによって多少の違いはあります。)

add_filter( 'wpcf7_validate_email', 'wpcf7_validate_email_filter_confrim', 11, 2 );
add_filter( 'wpcf7_validate_email*', 'wpcf7_validate_email_filter_confrim', 11, 2 );
function wpcf7_validate_email_filter_confrim( $result, $tag ) {
    $type = $tag['type'];
    $name = $tag['name'];
    $_POST[$name] = trim( strtr( (string) $_POST[$name], "\n", " " ) ); //改行コードの削除(strtrによる置換はあまり意味がない)
    if ( 'email' == $type || 'email*' == $type ) {
        if (preg_match('/(.*)_confirm$/', $name, $matches)){ //確認用メルアド入力フォーム名を ○○○_confirm としています。
            $target_name = $matches[1];
            if ($_POST[$name] != $_POST[$target_name]) {
                if (method_exists($result, 'invalidate')) {
                    $result->invalidate( $tag,"確認用のメールアドレスが一致していません");
                } else {
                    $result['valid'] = false;
                    $result['reason'][$name] = '確認用のメールアドレスが一致していません';
                }
            }
        }
    }
    return $result;
}

ただ、このプログラムだと6行目で、実際にフォームで入力されたデータの加工を行なっていますが、不必要な加工が含まれます。

$_POST[$name] = trim( strtr( (string) $_POST[$name], "\n", " " ) ); //改行コードの削除(strtrによる置換はあまり意味がない)

処理内容としては、入力データに改行コード(\n)が含まれていた場合、strtr関数で半角スペースに置き換えてから、trim関数で前後の空白データを削除しているのですが、何がしたいのかよく分かりません。(trimはまだ分かるけど、strtrは全く意味不明。メールアドレスに空白データは使えませんので、そもそもcontact form 7のemail型を使っている時点でエラーとなります。

POSTデータにstrtrを当てて改行コードを半角スペースに置き換えている処理についてですが、本家のCustom validationの記事を見てもtrimしか使ってないし、それで十分だと思います。

本家のCustom validationの記事はこちら

更に言えば次のコードで入力データを比較する際、$_POST[$name]の値は空白文字を削除したり加工しているのに、$_POST[$target_name]の方は何もしていませんが、これも意味がありません。
やるなら$_POST[$target_name]の方にも同じ処理をするべきです。

if ($_POST[$name] != $_POST[$target_name]) {
//$_POST[$name]には加工済みデータが入っているのに
//$_POST[$target_name]は未加工のデータ

どこで誰がstrtrでの処理を入れたのか謎ですが、冗長な処理はバグの元になるので入れない方が良いです。

すべきでない処理がもう1箇所

スーパーグローバル変数$_POSTを直接書き換えてるのも、正直よろしくないです。オリジナルの入力値は加工しないで保存すべきです。

何故か???
もし、他のプラグインなどが同一の$_POST値を使いたいときどうなるでしょうか?
$_POST値が加工された前提を知らず、すでに加工されてしまったデータを処理することになり、期待と違う結果になったとしたら、その原因が分からなくなります。

11行目で、contact form 7プラグインのバージョンによる動作の違いを吸収するために、$result内に必要なメソッドが存在しているか確認しています。
メソッドが存在している場合(比較的新しいバージョン)は12行目を実行。
存在しない場合(おそらくバージョン4.1未満)は、14,15行目を実行します。

プラグインの仕様が変わって久しいので、古いプラグインなんか対応しなくていいよ!という方は、11行目と13〜16行目を削除してもOKです。

今回Contact Form 7でメールアドレスの再入力チェック機能を実装する方法として他のサイトを色々拝見しましたが、プログラマーがちゃんと書いたコードもあれば、コピペの記事もありました。中にはプラグインのコアファイルを直接編集してください。なんて荒技を掲載しているサイトもありましたが、くれぐれもコアファイルを編集するのだけはやめてください!!!

ちなみに、「contact form 7 メールアドレス 確認用」などで検索すると2020/9/19時点でトップに表示されるこちらのページのコードには間違いがあり、そのままでは利用できませんのでご注意を。(サイトオーナーさん直して〜〜〜!!)

ネット上の情報は古い情報も混ざっているので、少なくとも更新日付は確認しましょう。
また、コピペで作った記事などは動作検証などしていないので、間違った情報をそのまま発信している場合もありますので情報を探す方にもスキルが要求されてしまいますね。