WordPressにメールフォームを実装する優秀なプラグインは沢山ありますが、
ほとんどのプラグインは非開発者向けに導入しやすさを重視して作られているため、
例えば入力項目を動的にするなど、少し複雑なことをしようと思うと、
詰んでしまいます。
WordPressにはメール送信処理やデータの保存などを簡単に実装できる関数が用意されているので、
メールフォームを自力で実装するのもそれほど難しくなく、かえってその方が好都合な場合があります。
メールフォームの実装方法
※本記事の途中の暫定版ソースをコピペして使用しないでください。
単一のフォームであれば、固定ページで実装してしまうのが簡単です。
まずは固定ページを作成し、ページテンプレートに(page-{slug}.php)にフォームのHTMLを記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<form action="<?php the_permalink(); ?>" method="post"> <dl> <dt>お名前</dt> <dd><input type="text" name="username" /></dd> <dt>メールアドレス</dt> <dd><input type="email" name="email" /></dd> <dt>お問合せ内容</dt> <dd><textarea name="content"></textarea></dd> </dl> <button type="submit">送信する</button> </form> |
そして、functions.php にメール送信処理を記述します。
ここでは、template_redirect アクションにフックしていますが、
処理によっては init アクションなどでも良いでしょう。
is_page() で判定し、対象のページ以外では動作しないようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
add_action( 'template_redirect', 'form_init' ); function form_init() { if ( ! is_page( 'inquiry' ) ) { return; } if ( isset( $_POST['username'] ) ) { $username = $_POST['username']; $email = $_POST['email']; $content = $_POST['content']; $to = "admin@example.com"; $subject = "お問合せがありました"; $body = "お名前 : \n{$username}\n" . "メールアドレス : \n{$email}\n" . "お問合せ内容 : \n{$content}\n"; $fromname = "My Test Site"; $from = "sendonly@example.com"; $headers = "From: {$fromname} <{$from}>\r\n"; wp_mail( $to, $subject, $body , $headers) ; } } |
wp_mail() 関数が、メール送信処理をいい感じにやってくれるので、
基本的には、フォームから送信したデータをこの関数に渡すだけで動きます。
より実用的なメールフォームへ
メールフォームとして実践で使えるようにするためには、最低限、
・エラーチェックとエラー表示処理
・CSRF対策
・完了画面表示+二重送信対策
が必要だと思います。
CSRF対策
とりあえずこのままでは不正送信し放題なので、nonceチェックを入れましょう。
テンプレート側でnonceデータを生成し、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<form action="<?php the_permalink(); ?>" method="post"> <?php wp_nonce_field( 'my-form', 'myform_nonce' ) ?> <dl> <dt>お名前</dt> <dd><input type="text" name="username" /></dd> <dt>メールアドレス</dt> <dd><input type="email" name="email" /></dd> <dt>お問合せ内容</dt> <dd><textarea name="content"></textarea></dd> </dl> <button type="submit">送信する</button> </form> |
送信処理の前にチェックを行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
add_action( 'template_redirect', 'form_init' ); function form_init() { if ( ! is_page( 'inquiry' ) ) { return; } if ( isset( $_POST['username'] ) ) { $username = $_POST['username']; $email = $_POST['email']; $content = $_POST['content']; $myform_nonce = $_POST['myform_nonce']; if ( ! wp_verify_nonce( $myform_nonce, 'my-form') ) { wp_die( '不正な遷移です' ); } $to = "admin@example.com"; $subject = "お問合せがありました"; $body = "お名前 : \n{$username}\n" . "メールアドレス : \n{$email}\n" . "お問合せ内容 : \n{$content}\n"; $fromname = "My Test Site"; $from = "sendonly@example.com"; $headers = "From: {$fromname} <{$from}>" . "\r\n"; wp_mail( $to, $subject, $body , $headers); } } |
完了画面表示+二重送信対策
フォームページの子ページとして、送信完了ページを子ページで作成しておきます。
そして、送信完了時にリダイレクト処理を入れます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
add_action( 'template_redirect', 'form_init' ); function form_init() { if ( ! is_page( 'inquiry' ) ) { return; } if ( isset( $_POST['username'] ) ) { $username = $_POST['username']; $email = $_POST['email']; $content = $_POST['content']; $myform_nonce = $_POST['myform_nonce']; if ( ! wp_verify_nonce( $myform_nonce, 'my-form') ) { wp_die( '不正な遷移です' ); } $to = "admin@example.com"; $subject = "お問合せがありました"; $body = "お名前 : \n{$username}\n" . "メールアドレス : \n{$email}\n" . "お問合せ内容 : \n{$content}\n"; $fromname = "My Test Site"; $from = "sendonly@example.com"; $headers = "From: {$fromname} <{$from}>" . "\r\n"; $res = wp_mail( $to, $subject, $body , $headers ); if ( $res ) { wp_safe_redirect( get_page_link( get_page_by_path( 'inquiry/thanks' )->ID ) ); } } } |
エラーチェックとエラー表示処理
ここはPHP的に地道に実装していきましょう。
やり方は色々ありますが、例えば以下のような実装です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php global $value; global $error; ?> <form action="<?php the_permalink(); ?>" method="post"> <?php wp_nonce_field( 'my-form', 'myform_nonce' ) ?> <dl> <dt>お名前</dt> <dd> <?php if ( ! empty( $error['username'] ) ): ?><p><?php echo $error['username']; ?></p><?php endif; ?> <input type="text" name="username" value="<?php echo $value['username']; ?>" /> </dd> <dt>メールアドレス</dt> <dd> <?php if ( ! empty( $error['email'] ) ): ?><p><?php echo $error['email']; ?></p><?php endif; ?> <input type="email" name="email" value="<?php echo $value['email']; ?>" /> </dd> <dt>お問合せ内容</dt> <dd> <?php if ( ! empty( $error['content'] ) ): ?><p><?php echo $error['content']; ?></p><?php endif; ?> <textarea name="content"><?php echo $value['content']; ?></textarea> </dd> </dl> <button type="submit">送信する</button> </form> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
add_action( 'template_redirect', 'form_init' ); function form_init() { if ( ! is_page( 'inquiry' ) ) { return; } global $value, $error; $value = array( 'username' => '', 'email' => '', 'content' => '' ); $error = array(); if ( isset( $_POST['myform_nonce'] ) ) { if ( ! wp_verify_nonce( $_POST['myform_nonce'], 'my-form') ) { wp_die( '不正な遷移です' ); } foreach ( $value as $key => $val ) { if ( isset( $_POST[$key] ) ) { $value[$key] = $_POST[$key]; } if ( $value[$key] === "" ) { $error[$key] = '必須項目です'; } else if ( $key == "email" && ! is_email( $value[$key] ) ) { $error[$key] = 'メールアドレスの形式が間違っています'; } } if ( empty( $error ) ) { $to = "admin@example.com"; $subject = "お問合せがありました"; $body = "お名前 : \n{$value['username']}\n" . "メールアドレス : \n{$value['email']}\n" . "お問合せ内容 : \n{$value['content']}\n"; $fromname = "My Test Site"; $from = "sendonly@example.com"; $headers = "From: {$fromname} <{$from}>" . "\r\n"; $res = wp_mail( $to, $subject, $body , $headers ); if ( $res ) { wp_safe_redirect( get_page_link( get_page_by_path( 'inquiry/thanks' )->ID ) ); } } } } |
フォームを自前で実装する際に悩ましいのはデータの妥当性チェックです。
多くの場合、正規表現やPHPの filter_var() を使用して検証することになりますが、メールアドレスの妥当性チェックに関しては、WordPressの is_email() 関数を使用することもできます。