前回作成したフォームに、送信データをDBに保存する機能を追加します。
送信データをDBに保存する方法は、以下の3種類が考えられます。
1. 投稿として保存する
2. コメントとして保存する
3. 独自のテーブルに保存する
送信データは個人情報を含むため、データ保護の観点からも考える必要があります。
上記のうち、コメントには投稿タイプのような大分類がなく、権限が制御しにくいので、却下。
WordPressに独自テーブルを追加するのはいわば最終手段なので、ここでは(1) 投稿として保存する方法で実装します。
カスタム投稿タイプでデータを保存する
データはサイト上で公開されてはいけないので、専用の投稿タイプを指定して保存します。
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 45 46 47 48 49 50 51 52 53 |
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 ) ) { $body = "お名前 : \n{$value['username']}\n" . "メールアドレス : \n{$value['email']}\n" . "お問合せ内容 : \n{$value['content']}\n"; $formdata = array(); $formdata['post_type'] = 'formdata'; $formdata['post_status'] = 'private'; $formdata['post_name'] = 'formdata' . date('YmdHis'); $formdata['post_title'] = $value['username'] . " (" . $value['email'] . ")"; $formdata['post_content'] = $body; wp_insert_post($formdata); $to = "admin@example.com"; $subject = "お問合せがありました"; $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 ) ); } } } } |
ここでは、formdata という投稿タイプを指定します。
明示的に投稿タイプを登録しない限りサイト上で公開されることはありませんが、post_status は private (非公開) が望ましいでしょう。
上記の例では、post_title (タイトル) に名前とメールアドレスを保存し、post_content (本文) にメールと同内容保存しています。
このままでもデータをDBに保存することはできますが、管理画面上で閲覧したり、エクスポート処理などを作成する際に不便なので、明示的に投稿タイプを追加しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
add_action( 'init', 'register_post_type_formdata' ); function register_post_type_formdata() { $labels = array( 'name' => 'お問合せデータ', 'singular_name' => 'お問合せデータ', 'menu_name' => 'お問合せ', ); $args = array( 'labels' => $labels, 'public' => false, 'show_ui' => true, ); register_post_type( 'formdata', $args ); } |
問合せデータがサイトに公開されることがないよう、public パラメータは必ず false にしておきます。
そして、管理画面からは見れるように、show_ui パラメータを true にします。
capability_type を指定して、閲覧権限を制限するのも良いでしょう。
より実用的なフォームデータ保存
さらに、フォームの入力情報を投稿画面のメタボックスに表示し、そのURLをメールに記載できるようにしてみましょう。
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
function register_post_type_formdata() { $labels = array( 'name' => 'お問合せデータ', 'singular_name' => 'お問合せデータ', 'menu_name' => 'お問合せ', ); $args = array( 'labels' => $labels, 'public' => false, 'show_ui' => true, 'supports' => array( 'title' ), 'register_meta_box_cb' => 'add_formdata_meta_box' ); register_post_type( 'formdata', $args ); } function add_formdata_meta_box() { add_meta_box( 'ad5-loyalty-content', '入力内容', 'display_formdata_meta_box', null, 'normal', 'high' ); } function display_formdata_meta_box() { global $post; echo '<table class="form-table">'; echo '<tbody>'; echo '<tr><th>お名前</th><td>' . get_post_meta( $post->ID, '_username', true ) . '</td></tr>'; echo '<tr><th>メールアドレス</th><td>' . get_post_meta( $post->ID, '_email', true ) . '</td></tr>'; echo '<tr><th>内容</th><td>' . nl2br( get_post_meta( $post->ID, '_content', true ) ) . '</td></tr>'; echo '</tbody>'; echo '</table>'; } 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 ) ) { $formdata = array(); $formdata['post_type'] = 'formdata'; $formdata['post_status'] = 'private'; $formdata['post_name'] = 'formdata' . date('YmdHis'); $formdata['post_title'] = $value['username'] . " (" . $value['email'] . ")"; $inserted = wp_insert_post($formdata); if ( $inserted && ! is_wp_error( $inserted ) ) { update_post_meta( $inserted, '_username', $value['username'] ); update_post_meta( $inserted, '_email', $value['email'] ); update_post_meta( $inserted, '_content', $value['content'] ); $link = "http://wordpress.ad5.jp/wp-admin/post.php?post={$inserted}&action=edit"; } else { $link = 'DBへの保存に失敗しました'; } $to = "admin@example.com"; $subject = "お問合せがありました"; $body = "お名前 : \n{$value['username']}\n" . "メールアドレス : \n{$value['email']}\n" . "お問合せ内容 : \n{$value['content']}\n\n"; . $link; $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 ) ); } } } } |
フォームに入力したデータは update_post_meta() でカスタムフィールドに保存しています。
なお、post_content は指定しなくても投稿可能ですが、null を入れてしまうと、wp_insert_post() でデータベースエラーが発生するので注意が必要です。
wp_insert_post() が成功すれば戻り値に保存した投稿のIDが入るので、これを利用して管理画面のURLを生成し、メールの本文に追加しています。
管理画面では、カスタムフィールドのデータを(編集できない)表示項目として出力するため、add_meta_box() でメタボックスを追加しています。
add_meta_box() を実行する関数は、add_meta_boxes アクションにフックすることもできますが、ここでは register_post_type() の register_meta_box_cb パラメータにコールバックとして指定しています。
また、本文欄は使用しないので、 register_post_type() の support パラメータ には title のみを指定しました。
他にも、対応状況を選択できるカスタムフィールドを作ったり、それを一覧画面に表示できるようにするのも良いですね。