1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Wordpress Contact Form 7 で問い合わせ種別に応じて複数の宛先に管理者向けメールを送る方法

Last updated at Posted at 2024-09-03

はじめに

問い合わせ種別に応じて、各担当のメールアドレス宛にメールを送りたいこと、あると思います。
Contact Form 7は以下のようにプルダウンのvalueにメールアドレスを設定すれば、やりたいことが出来るには出来るのですが…

[select* type id:type class:form-select include_blank "イベントに関する問い合わせ|test+event@example.co.jp" "求人に関する問い合わせ|test+recruit@example.co.jp" "ホームページに関する問い合わせ|test+web@example.co.jp" "その他|test+etc@example.co.jp"]

valueにメールアドレスの一覧を羅列するのって結構抵抗ありませんか? 私はあります。

担当のメールアドレスが変わったら、メンテナンスが大変ですし、
担当のメールアドレスが複数あったら、実装も大変になります。

なので、Wordpress管理画面にオプション画面を設置し、
問い合わせ種別に応じて、それぞれ複数のメールアドレス宛にメールが送れるようにします。

スクリーンショット 2024-09-03 163115.png

オプション画面を初めて作ったので、もっと良い方法や、これを実現できる既製プラグインがあれば、ご紹介をお願いします。

実装

お問い合わせフォームテンプレート

お問い合わせ > コンタクトフォーム > フォーム

<p>問い合わせ種別</p>
[select* type id:type class:form-select include_blank "イベントに関する問い合わせ|event" "求人に関する問い合わせ|recruit" "ホームページに関する問い合わせ|web" "その他|etc"]

<p>メールアドレス</p>
[email* your-email autocomplete:your-email id:your-email class:form-text class:form-email]

[submit "送信する"]

お問い合わせ > コンタクトフォーム > メール > メール1(管理者向けメール)

[_raw_{field_name}] と記述することで、プルダウンのvalueの値を出力可能です

送信先: [_site_admin_email]
送信元: [_site_title] <wordpress@example.co.jp>
題名: [_site_title] "[your-subject]"
追加ヘッダー: Reply-To: [your-email]
メッセージ本文:
お問い合わせの種類目的: [_raw_type]
メールアドレス: [your-email]

お問い合わせ > コンタクトフォーム > メール > メール2(ユーザ向けメール)

送信先: [your-email]
送信元: [_site_title] <wordpress@example.co.jp>
題名: [_site_title] "[your-subject]"
追加ヘッダー: Reply-To: [_site_admin_email]
メッセージ本文:
お問い合わせの種類目的: [_raw_type]
メールアドレス: [your-email]

ロジック

共通関数ファイル functions.php

wp-content/themes/{theme_name}/functions.php
/*
 * 管理画面に送信先管理のオプション画面を追加する
 */
add_action('admin_menu', 'cf7_custom_inquiry_option_menu');

function cf7_custom_inquiry_option_menu()
{
    add_menu_page(
        'お問い合わせ送信先管理', // ページタイトル
        'お問い合わせ送信先管理', // メニュータイトル
        'manage_options', // 権限
        'cf7-custom-inquiry-option', // ページスラッグ
        'cf7_custom_inquiry_option_page' // コールバック関数 includes/cf7_custom_inquiry_option.php に定義
    );
	add_action('admin_init', 'cf7_custom_inquiry_register_settings'); // includes/cf7_custom_inquiry_option.php に定義
}

// メール送信ロジックやオプション画面は以下のファイルに記載
require ( dirname(__FILE__) . '/includes/cf7_custom_inquiry_option.php');

オプション画面 includes/cf7_custom_inquiry_option.php

wp-content/themes/{theme_name}/includes/cf7_custom_inquiry_option.php
<?php
/**
 * [管理画面] お問い合わせ送信先管理
 * お問い合わせ種別
 */
function cf7_custom_inquiry_get_inquiry_types() {
    $inquiryCodes = [
        'default' => "(デフォルト)その他",
        'event' => "イベントに関する問い合わせ",
        'recruit' => "求人に関する問い合わせ",
        'web' => "ホームページに関する問い合わせ"
    ];
    return $inquiryCodes;
}

/**
 * [管理画面] お問い合わせ送信先管理
 * オプションページを表示する
 */
function cf7_custom_inquiry_option_page() {
    $inquiryCodes = cf7_custom_inquiry_get_inquiry_types();

    // DBから送信先別メールアドレス一覧を取得
    $storedEmails = get_option('cf7_custom_inquiry_emails');

    // DB上にデータが存在しない時にエラーが出るのを抑制
    if (! $storedEmails || ! is_array($storedEmails)) {
        $storedEmails = [];
    }

    /* ★オプションページ描画 ここから★ */
?>
    <div class="wrap">
        <h2>お問い合わせ送信先管理</h2>

        <?php settings_errors('cf7_custom_inquiry_emails'); ?>

        <form method="post" action="options.php">
            <?php settings_fields('cf7_custom_inquiry_settings_group'); ?>
            <h3>送信先メールアドレスを改行区切りで一つずつ入力してください</h3>
            <p>デバッグ用</p>
            <pre><?= var_dump($storedEmails); ?></pre>
            <pre><?= var_dump(get_mail_address_lists_of_inquiry()); ?></pre>
            <table class="form-table">
                <?php foreach ($inquiryCodes as $code => $label): ?>
                    <tr valign="top">
                        <th scope="row"><?= $label; ?></th>
                        <td>
                            <textarea name="cf7_custom_inquiry_emails[<?= $code; ?>]" rows="3" cols="50" required><?= esc_textarea(isset($storedEmails[$code]) ? $storedEmails[$code] : ''); ?></textarea>
                        </td>
                    </tr>
                <?php endforeach; ?>
            </table>
            <?php submit_button(); ?>
        </form>
    </div>
<?php
    /* ★オプションページ描画 ここまで★ */
}

/**
 * [管理画面] お問い合わせ送信先管理
 * 設定グループをWordPressに登録
 */
function cf7_custom_inquiry_register_settings() {
    register_setting('cf7_custom_inquiry_settings_group', 'cf7_custom_inquiry_emails', 'cf7_custom_inquiry_validate');
}

/**
 * [管理画面] お問い合わせ送信先管理
 * カスタムバリデーションルール追加
 */
function cf7_custom_inquiry_validate($input) {
    $inquiryCodes = cf7_custom_inquiry_get_inquiry_types();
    $errors = [];
    $validInput = $input; // 元の入力内容を保持

    foreach ($inquiryCodes as $code => $label) {
        $emails = explode("\n", trim($input[$code])); // 改行区切りでメールアドレスを展開
        $emails = array_map('trim', $emails);

        // 必須入力チェック
        if (empty($emails)) {
            add_settings_error(
                'cf7_custom_inquiry_emails',
                'cf7_custom_inquiry_emails_error_' . $code,
                sprintf('%s は必須入力です。', $label),
                'error'
            );
            $errors[] = $code;

            continue;
        }

        // メールアドレス妥当性、重複チェック
        $uniqueEmails = [];
        foreach ($emails as $email) {
            if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                add_settings_error(
                    'cf7_custom_inquiry_emails',
                    'cf7_custom_inquiry_emails_format_error_' . $code,
                    sprintf('%s に無効なメールアドレスが含まれています: %s', $label, $email),
                    'error'
                );
                $errors[] = $code;
            }
            elseif (in_array($email, $uniqueEmails)) {
                add_settings_error(
                    'cf7_custom_inquiry_emails',
                    'cf7_custom_inquiry_emails_duplicate_error_' . $code,
                    sprintf('%s に重複するメールアドレスが含まれています: %s', $label, $email),
                    'error'
                );
                $errors[] = $code;
            }
            else {
                $uniqueEmails[] = $email; // 登録済メールアドレスとして格納
            }
        }

        // 入力に問題がない場合、送信先別メールアドレスリストに登録
        if (! empty($uniqueEmails)) {
            $validInput[$code] = implode("\n", $uniqueEmails);
        }
    }

    // エラーがあれば入力値をそのまま返すが、保存はしないようにする(pre_update filterで制御)
    if (! empty($errors)) {
        return $input;
    }

    // エラーがない場合に成功メッセージを追加
    add_settings_error(
        'cf7_custom_inquiry_emails',
        'cf7_custom_inquiry_emails_success',
        'お問い合わせ送信先を保存しました。',
        'success'
    );

    // エラーがなければバリデーション通過した内容を返す
    return $validInput;
}

/**
 * 保存前のオプションの値をフィルタリングして、エラーがあれば保存を中止する。
 */
function cf7_custom_inquiry_pre_update($new_value, $old_value) {
    // ここでバリデーションエラーがあった場合に旧値をそのまま返し、新しい値を保存しない
    $errors = get_settings_errors('cf7_custom_inquiry_emails');
    if (!empty($errors)) {
        // エラーがある場合は古い値を返す
        return $old_value;
    }
    // エラーがない場合は新しい値を返す
    return $new_value;
}

add_filter('pre_update_option_cf7_custom_inquiry_emails', 'cf7_custom_inquiry_pre_update', 10, 2);

/**
 * [管理画面/フロント]
 * お問い合わせ種別ごとのメール飛ばし先リストを取得する
 */
function get_mail_address_lists_of_inquiry()
{
    $defaultMailAddresses = [
        'default' => ['test@example.co.jp', 'test+etc@example.co.jp'], // その他・デフォルト
        'event' => ['test@example.co.jp', 'test+event@example.co.jp'], // イベント
        'recruit' => ['test@example.co.jp', 'test+recruit@example.co.jp'], // 求人
        'web' => ['test@example.co.jp', 'test+web@example.co.jp'], // ホームページ
    ];

    // 取得したメールアドレスの配列
    $storedEmails = get_option('cf7_custom_inquiry_emails');

    // DB上にデータが存在しない場合、デフォルトのメールアドレスリストを使用
    if (!$storedEmails || !is_array($storedEmails)) {
        $storedEmails = $defaultMailAddresses;
        return $storedEmails;
    }

    // 新しいメールアドレス配列を作成
    $mailAddresses = [];

    // インデックスを設定
    $index = 0;

    // 配列のキーと値をループ処理
    foreach ($storedEmails as $code => $emails) {
        // 改行で分割してメールアドレスの配列を取得
        $emailList = array_map('trim', explode("\n", $emails));
        // インデックスに基づいてメールアドレスにサフィックスを追加
        foreach ($emailList as $email) {
            // メールアドレスにサフィックスを追加
            $mailAddresses[$code][] = $email;
            $index++;
        }
    }

    return $mailAddresses;
}

/**
 * [フロント] お問い合わせフォーム/採用応募フォーム
 * お問い合わせ種別によってメールの飛ばし先を変更する
 * 確認画面後、送信するボタンを押下時に発火する
 * 管理者向けメール(メール1)、ユーザ向けメール(メール2)の2回、発火する
 */
function custom_wpcf7_mail_components($components, $form, $args)
{
    $targetKey = 'type';

    // デフォルトの送り先
    $toAddressOrg = $components['recipient'];

    // 管理者メールアドレスを取得
    $adminEmail = get_option('admin_email');

    $sendType = ($toAddressOrg === $adminEmail) ? "mail_1" : "mail_2";
    // ユーザー向けメール(mail_2)の送信なら以降の処理を中断
    // WARNING: このロジックだと、管理者ユーザーが自分に対してメールを送ると、処理が継続する
    if($isSendToUser = $sendType === "mail_2") {
        $components['recipient'] = $toAddressOrg; // mail_1の処理で送り先が書き換わるので元の送り先に戻す
        return $components;
    }

    // 管理者向けメール(mail_1)のみ、送り先を変更する
    if ($submission = WPCF7_Submission::get_instance()) {
        $postedData = $submission->get_posted_data();

        // NOTE: プルダウンの値(typeやprefectureなど)は配列型で値が来る模様
        $isValueExists = false;
        $value = "";

        if(isset($postedData[$targetKey])){
            $isPulldownField = (is_array($postedData[$targetKey]) && count($postedData[$targetKey]) > 0);
            $isHiddenField = (is_string($postedData[$targetKey]) && strlen($postedData[$targetKey]) > 0);

            if($isPulldownField) $value = $postedData[$targetKey][0];
            if($isHiddenField) $value = $postedData[$targetKey];
        }

        // お問い合わせ種別ごとのメールアドレス配列を定義
        $toAddresses = get_mail_address_lists_of_inquiry();
        // 管理者のメールアドレスを設定
        $components['recipient'] = implode(', ', $toAddresses["default"]);

        if(array_key_exists($value, $toAddresses)){
            $components['recipient'] = implode(', ', $toAddresses[$value]);
        }
    }
    return $components;
}

add_filter('wpcf7_mail_components', 'custom_wpcf7_mail_components', 10, 3);

動作確認

オプション画面でメールアドレスを設定後、問い合わせフォームを送信すると、問い合わせ種別に応じて、管理者メールのみ、対応するメールアドレス一覧にメールを送ります。
オプション画面でメールアドレスを未設定の場合でも、デフォルトの送信先メールアドレス一覧をセットします。

無題.png

注意点として、メールアドレスの送信先が管理者メールアドレスと同じ場合、管理者メールもユーザー向けメールも送信先がオプション画面で設定したメールアドレス一覧になります。メール1とメール2のイイ感じの識別方法がわからなかったため。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?