見出し画像

【PHP+Ajax】メールスクリプト epistoli

WordPressのメールフォームプラグイン全般を捨てたい。
でも既存のPHPメールフォームでは微妙に条件を満たせない。
よって作ってしまえ!という精神による、自分が使用するためだけに作った産物です。


1. 仕様一覧

- PHP7.0以上
- UTF-8のみ
- DB、jQuery不要
- 既存ページへの組み込み・使い回し前提
- デザイン自由
- 画面変遷なし
- 送信元URL、ページタイトルの取得
- CSVへの自動保存(月別自動生成)
- ログファイル対応(デフォルト150件まで)
- ワンタイムトークンによる二重送信・CSRF対策
- ブラックリスト、NGワード対応
- 連続送信(デフォルト10回)後、一定時間ブロック
- お礼画像対応
- WordPressへの組み込み可

このメールスクリプトは感想フォームとして利用することを前提に作成しましたが、通常のメールフォームとしても利用することができます。
ただし、このメールスクリプトには確認画面、及び確認メール等の機能は実装していないため、本格的なお問い合わせフォームとしての利用には向いておりません。
また、管理画面などという冗長的なものも用意しておりませんので、それらを必要とされる方は別のメールスクリプトをご利用されることをお勧めします。

動作確認環境はPHP8.0.25、WordPress6.2です。


2. ダウンロード

2-1. 設置に際しての注意事項

  • 設置、カスタマイズ、改造は自己責任でお願いします。

  • epistoli/epistoli.php に書かれた著作権・配布元表示は消さないでください。

  • 万が一、不具合が起きたとしても作者は一切の責任を負いかねますので、予めご了承ください。

  • 素人が趣味で開発したものです。二次配布や販売についてはご遠慮ください。

2-2. ダウンロードファイル

ダウンロードはこちらからお願いします。


3.基本設定

3-1. ファイル構成

ファイル構成は以下のとおりです。

epistoli
   ├─ conf(ブラックリスト・NGワード設定用)
   │    ├─ blacklist.ini
   │    ├─ NGword.ini
   │    └─ .htaccess
   ├─ data(ログファイル・CSV格納用) / .htaccess
   ├─ epistoli.php(本体)
   ├─ mailfrom.php(フォーム用テンプレート)
   ├─ epistoli.js
   ├─ style.css
   └─ .htaccess

ログファイル、CSVは自動生成されます。
サーバーの設定によっては上手く生成、書き込みがされない場合がありますので、その際はパーミッションの設定を設置サーバーに合わせて変更してみてください。
ログファイルのデフォルトパーミッションの設定は 666 です。

3-2. 初期設定

epistoli.php を開くと、16~32行目 に初期設定項目があります。
ここでは送信先メールアドレス、送信元メールアドレス、送信者名、メールタイトルをそれぞれ指定することができます。
また、ログファイルの保存件数もここで指定できるようになっていますが、あまりに大きすぎる件数は指定しないようにしてください。

/* -------------------- 初期設定 -------------------- */
// 送信先メールアドレス
$mail_to = 'mail_to@example.com';

// 送信元メールアドレス
$from_email = 'mail_from@example.com';

// 送信者名
$from_name = '送信者名';

// メールタイトル
$subject = '感想フォーム';

// ログの保存件数
$log = 150;

送信先アドレスと送信元アドレスは同じものを指定して大丈夫です。
ですが、送信元と受信アドレスを分けたい場合にはそれぞれ別のメールアドレスを指定する必要があります。

3-3. 設置

本体フォルダを設置するのはどこであっても大丈夫です。
フォームを設置するページに必要なのな3つだけです。

mailform.php は以下のようにして呼び出します。

<?php include_once($_SERVER['DOCUMENT_ROOT'] . '/epistoli/mailform.php'); ?>

また、中身だけコピーしてHTMLに直接、組み込むことも可能です。

style.cssepistoli.js も必ず読み込むようにしてください。
epistoli.js の設置パスは 絶対URL か 絶対パス で指定します。

<link href="./epistoli/style.css" type="text/css" media="all" rel="stylesheet">
<script src="/epistoli/epistoli.js"></script>

jQueryを必要としていないため、基本的にはこれだけで設置は完了です。
設置後、正しくメールが送信されるか、またログファイル、及びCSVが生成・書き込みが行われているか確認してみてください。

設置段階で送信エラー等が出る場合は、ログファイルのパーミッション等で問題が出ている可能性があります。
本体ファイル epistoli.php92行目 に以下のコードがあります。

chmod($log_file_path, 0666);

パーミッションはここで指定しています。
また、ログファイルが生成されない場合は手動で data/maillog.log を設置し、環境に合わせてパーミッションを設定することも可能です。

ログファイル以外でのパーミッションの設定は特に必要ありません。
ですがログファイル以外でも書き込みや読み込みができない場合は、dataフォルダ、confフォルダの権限を一度見直して見てください。

3-4.WordPressへの追加

特殊な設定は必要ありません。
HTMLに設置するのと同じように行ってください。


4.テンプレートファイル

4-1. mailform.php

フォーム画面

mailform.php はフォーム用のテンプレートファイルです。
このファイルには初期段階では使用できるすべてのフォームが記述されています。
使用できるフォームは以下のとおりです。

  • <input type="text">(名前用)

  • <input type="checkbox">(定型文等)

  • <input type="radio">(返信選択用)

  • <select>(お問い合わせ項目、定型文等)

  • <textarea>(メッセージ用)

  • <input type="submit">(送信ボタン)

それぞれにはname属性がすべて指定されていますが、<input type="checkbox">、<input type="radio">、<select>については自由に項目内容を設定することができます。
また、不要であれば mailform.php から削除するだけで大丈夫です。
極端な話、一言フォームとして利用することも可能です。
メール本文用のテンプレートでは条件分岐を指定してあるため、特に削除する必要はありませんが、例えばSelect要素の「選択項目」を「お問い合わせ内容」に変更したいときなどはメールテンプレートを書き換える必要があります。

4-2. メールテンプレート

メール本文は以下のようなテンプレートになっています。
epistoli.php の 33~58行目 に該当します。

$body  = "メッセージが届いています。\n\n";
$body .= "----------------------------------------\n\n";
$body .= "名前: {$name}\n";

// $template_bodyが空でない場合のみ、定型文の内容を追加する
$body .= !empty($template_body) ? "定型文:\n{$template_body}\n" : '';

// Select要素の値をメッセージに追加する
$body .= !empty($select) ? "選択項目: {$select}\n\n" : '';

$body .= "メッセージ:\n\n{$message}\n";

if (isset($_POST['reply'])) {
  $reply = ($_POST['reply'] === 'yes') ? "要返信\n" : "返信不要\n";
  $body .= "\n----------------------------------------\n\n{$reply}";
}
$body .= "\n----------------------------------------\n";
$body .= "送信元ページ: {$title}\n";
$body .= "送信元URL: {$url}\n";
$body .= "----------------------------------------\n";
$body .= "IP: {$ip}\n";
$body .= "{$user_agent}\n";

実際のメールは以下のような形で届きます。

メッセージが届いています。

----------------------------------------

名前: {$name}
定型文: // 選択されたときのみ表示
checkbox1
checkbox2
checkbox3

選択項目: select // 選択されたときのみ表示

メッセージ:

メッセージ本文

----------------------------------------

返信不要 // 選択されたときのみ表示

----------------------------------------
送信元ページ: Document
送信元URL: http://www.example.com
----------------------------------------
IP: xxx.xxx.xxx.xx
UserAgent

メールテンプレートは関数化されているため、フォームを追加する際には注意が必要です。
例えば<input type="text">を別途追加する程度であれば、コードを読める程度の知識があれば自力で対応可能だと思われます。
ですが変数の設定、メールテンプレート関数への引数を含めた追加、CSVへの追加等を忘れるとフォーム内容は送信されないでお気をつけください。

4-3. CSS

このスクリプトにはアラート用のCSSと、お礼画像用のCSSのみが style.css に含まれています。
そのため、フォーム自体は自由にデザインすることが可能です。
ただし、予め指定されているid等はフォームの送信に必要となります。#epistoli#alert#token はCSS、mailform.php 共に削除・変更しないようにお願いします。


5. 送信完了画面(お礼画像表示)

送信完了画面

このメールスクリプトはデフォルトで送信完了メッセージの代わりにお礼画像とメッセージを表示するようになっています。
お礼画像は本体フォルダに thanks.jpg として用意してください。
画像パス等の指定を行う必要は特にありません。
また、お礼画像と共に表示されるメッセージを変更する場合は、epistoli.js74行目 にある以下の部分を任意の文に置き換えてください。

thanksMessage.textContent = 'メッセージありがとうございます。';

また、お礼画像の代わりに単なる送信完了メッセージを表示することもできます。
epistoli.js 59行目66行目 にコメントアウトされたコードがありますので、コメントアウトをはずしてください。

59行目:  // formMessages.classList.add('alert-success');
66行目:  // formMessages.innerHTML = response.message;

また、それに伴い、お礼画像が不要な方は epistoli.js 68行目~103行目 にある以下の部分をまるっと削除します。

// div#thanksを追加する
const thanksDiv = document.createElement('div');
thanksDiv.setAttribute('id', 'thanks');
const thanksImage = document.createElement('img');
thanksImage.src = root + 'thanks.jpg';
const thanksMessage = document.createElement('p');
thanksMessage.textContent = 'メッセージありがとうございます。';
thanksDiv.appendChild(thanksImage);
thanksDiv.appendChild(thanksMessage);
epistoliForm.appendChild(thanksDiv);

// 古いタイマーをクリア
let timer = null;
if (timer !== null) {
  clearTimeout(timer);
}

// #thanksを表示する
setTimeout(() => {
  thanksDiv.classList.add('show');
}, 10);

// 5秒後に#thanksを非表示にする
// #thanksを表示する
const thanks = document.querySelector('#thanks');
thanks.classList.add('show');

// 5秒後に#thanksを非表示にする
setTimeout(() => {
  thanks.classList.remove('show');
  thanks.classList.add('hidden');
  setTimeout(() => {
    thanks.parentNode.removeChild(thanks);
    thanks.classList.remove('hidden');
  }, 500);
}, 5000);


6. ブラックリスト・NGワード

ブラックリスト、NGワードへの登録は手動で行います。
ブラックリストは送信されたメール、あるいはログファイルを確認の上、該当するIPを追加してください。
IPはblacklist.iniに一件につき一行ずつ追加していきます。

ip_blacklist[] = xxx.x.x.x.
ip_blacklist[] = xxx.x.x.xxx
ip_blacklist[] = xxx.x.x.xxx

NGワードも同じです。
NGword.iniを開き、ブラックリストと同様に一行ずつ追加していきます。

ng_words[] = "NGワード1"
ng_words[] = "NGワード2"
ng_words[] = "NGワード3"

正常に動作すると、エラーメッセージが返る仕様です。
このとき、メールは送信されず、ログファイルにだけ記録が残る仕様になっています。

NGワードエラー画面

この記事が気に入ったらサポートをしてみませんか?