すたらブログ

文系Webプログラマの備忘録

SYNCKGRAPHICA Mailform 6.8: ユーザに複数の送信先からひとつを選ばせたい

目次


要望

ユーザに複数の送信先からひとつを選んでもらい、それに応じて送信先のアドレスを変更したい。


方法1: send.cgi複数用意する

送信先の分だけsend.cgiを用意して、セレクトボックスの変更に応じて<form>のaction属性を動的に書き換えます。

長所

Perlが分からなくても簡単にできます。
また、「Mailform 6.8」に限らず汎用的に使える方法だと思います。

短所

設定ファイルが複数になるので管理が煩雑になります。
また、増えたsend.cgiパーミッション変更を忘れがちになります。

手順

既存のsend.cgiをコピーして送信先の分だけ新たに作成します。

  • 営業部: send-eigyou.cgi
  • 人事部: send-jinji.cgi
  • 総務部: send-soumu.cgi
  • 経理部: send-keiri.cgi

それぞれの06.設置者のアドレスの欄を変更します。

#06.設置者のアドレス(カンマ区切り)
$conf{'mailto'} = 'eigyou@example.com';

メールフォームにセレクトボックスを追加します。
value属性にそれぞれのsend.cgiと対応する値を記述します。

<select id="address" name="お問い合わせ先(必須)">
  <option value="eigyou">営業部</option>
  <option value="jinji">人事部</option>
  <option value="soumu">総務部</option>
  <option value="keiri">経理部</option>
</select>

action属性を変更する処理を追加します。

// (jQueryを使用)
$(function () {
// お問い合わせ先に応じてaction属性を動的に変更する
  $('#address').change(function (ev) {
    $('#mailform').attr('action', 'mailform/send-' + $(ev.target).val() + '.cgi');
  });
});

方法2: 単一のsend.cgiの中で処理する

send.cgiの中で、送信先に応じて$conf{'mailto'}の値を変更する処理をPerlで記述します。

長所

設定ファイルがひとつで済むので管理が楽です。

短所

フォームの送信はGET送信でなければなりません。
また、Perlを理解する必要があります。
設定項目が並ぶ箇所にPerlのコードを追加するので、設定項目が読みづらくなります。

手順

<form>のmethod属性をgetに設定します。

<form id="mailform" method="get" action="mailform/send.cgi" onsubmit="return sendmail(this);">

メールフォームにセレクトボックスを追加します。

<select id="address" name="お問い合わせ先(必須)">
  <option>営業部</option>
  <option>人事部</option>
  <option>総務部</option>
  <option>経理部</option>
</select>

send.cgiに送信先の名前とメールアドレスのペアをハッシュに格納します。
また、セレクトボックスのname属性を変数に格納します。

my %hash_mailto = (
  '営業部' => 'eigyo@example.com',
  '人事部' => 'jinji@example.com',
  '総務部' => 'soumu@example.com',
  '経理部' => 'keiri@example.com',
);
my $name_mailto = 'お問い合わせ先';

送信先に応じたメールアドレスを$conf{'mailto'}に格納する処理を記述します。

# GET送信された内容を取得する
my $buffer = $ENV{'QUERY_STRING'};

# 項目ごとに分けて配列に格納する
my @pairs = split(/&/, $buffer);

foreach my $pair (@pairs) {
  # 各項目の内容を名前と値に分割する
  my ($name, $value) = split(/=/, $pair);
  $name =~ tr/+/ /;
  $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  $value =~ tr/+/ /;
  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

  # 項目が送信先の場合
  if ($name eq $name_mailto) {
    while (my ($h_key, $h_val) = each(%hash_mailto)) {
      if ($value eq $h_key) {
        # 選ばれた送信先のメールアドレスを「$conf{'mailto'}」の値とする
        $conf{'mailto'} = $h_val;
      }
    }
  }
}

GET送信にする理由

PerlでPOST送信の内容を取得するには下記のようにするらしいです。

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

しかし、これは一度実行すると中身が消えてしまうようです。
seek()でファイルポインタを先頭に戻しても無駄でした。

「Mailform 6.8」のsend.cgiの中ですでにread(STDIN, ...が使われているため、POST送信の内容を他で利用することができません。
GET送信ならば内容を再利用できるようなので、やむなくGET送信に限定することにしました。


私が選んだ方法

「方法2: 単一のsend.cgiの中で処理する」を選びました。
GET送信とはいえ、今回の場合は内容を盗み見される危険性はPOST送信と変わらないと思います。
とはいえ、Perlは全くの初心者なのでご意見をお待ちしています m(_ _)m