# 通知設計書 7-テストメール送信

## 概要

本ドキュメントは、メール配信前のテスト送信機能について、ログインユーザーにテキストまたはHTML形式のメールを送信する設計仕様を記載する。

### 本通知の処理概要

本通知は、管理者がメール配信機能を使用してメーリングリストや特定ユーザーにメールを送信する前に、内容を確認するためのテスト送信機能である。

**業務上の目的・背景**：メール配信は一度送信すると取り消しができないため、本番送信前にメールの内容・形式・添付ファイルなどを実際のメールとして確認できる機能が必要である。テストメール機能により、誤送信や内容ミスを防止し、メール配信の品質を確保する。操作者自身のメールアドレスに送信されるため、第三者への影響なくテストが可能。

**通知の送信タイミング**：管理画面のメール編集画面（/admin/mail/sendtest）でテスト送信確認ダイアログを経てconfirm=1でPOSTリクエストした際に送信される。

**通知の受信者**：テスト送信を実行した管理者（ログインユーザー）本人。現在ログイン中のユーザーのメールアドレス（view->user->user_email）宛に送信される。

**通知内容の概要**：作成中のメール本文（テキスト版またはHTML版、もしくは両方）と添付ファイルが送信される。メール内容はフォームから入力された最新の内容が使用される。

**期待されるアクション**：受信者（操作者）はテストメールの内容を確認し、問題なければ本番送信を実行、問題があれば修正を行う。

## 通知種別

メール

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 中 |
| リトライ | 無 |

### 送信先決定ロジック

テスト送信を実行したログインユーザーのメールアドレスに送信する。送信先は`$this->view->user->user_email`から取得され、操作者本人にのみ送信される。

## 通知テンプレート

### メール通知の場合

| 項目 | 内容 |
|-----|------|
| 送信元アドレス | {registry.site.site.email} |
| 送信元名称 | {registry.site.site.name} |
| 件名 | {mail_subject}（フォーム入力値） |
| 形式 | テキスト/HTML（メール設定に応じて） |

### 本文テンプレート

本文はフォームから入力された内容がそのまま使用される。テンプレート変数の置換は行われない。

```
{mail_text または mail_html の内容}
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| {asset_name}.{asset_extension} | 各種 | メールに添付ファイルが設定されている場合 | Attachmentsモデルで取得した添付ファイル |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| mail_subject | メール件名 | フォーム入力（POST） | Yes |
| mail_text | テキスト本文 | フォーム入力（POST） | No |
| mail_html | HTML本文 | フォーム入力（POST）+ html_entity_decode | No |
| user_email | 送信先メールアドレス | view->user->user_email | Yes |
| user_alias | 送信先表示名 | view->user->user_alias | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | テスト送信ボタン押下 | confirm=1かつ管理者権限ありかつメール未送信 | 管理画面の/admin/mail/sendtest/id/{id}/confirm/1/にPOST |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 権限不足 | 操作者にmmailまたはmmailsend権限がない場合 |
| メールID未指定 | URLパラメータにidが含まれていない場合 |
| 確認未完了 | confirm=1でない（初回表示時）場合 |
| 送信済みメール | mail_status='sent'の場合 |
| バリデーションエラー | 宛先または件名が未入力の場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[テスト送信リクエスト] --> B{権限チェック}
    B -->|権限なし| C[権限エラー画面]
    B -->|権限あり| D{confirm=1?}
    D -->|No| E[確認ダイアログ表示]
    D -->|Yes| F{バリデーションチェック}
    F -->|エラー| G[エラーメッセージ表示]
    F -->|成功| H[メール情報取得]
    H --> I[添付ファイル情報取得]
    I --> J{mail_status = sent?}
    J -->|Yes| K[送信済みエラー表示]
    J -->|No| L[メール情報更新]
    L --> M{text/html/両方?}
    M -->|textあり| N[テキストメール送信]
    M -->|htmlあり| O[HTMLメール送信]
    M -->|両方あり| P[両形式で送信]
    M -->|両方なし| Q[空本文で送信]
    N --> R[完了メッセージ表示]
    O --> R
    P --> R
    Q --> R
    C --> S[終了]
    E --> S
    G --> S
    K --> S
    R --> S
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| mail | メール情報取得 | Mailモデル経由 |
| assets | 添付ファイル情報取得 | Attachmentsモデル経由 |

### テーブル別参照項目詳細

#### mail

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| mail_id | メール識別 | WHERE mail_id = ? |
| mail_subject | メール件名 | Mail::fetchMail() |
| mail_text | テキスト本文 | Mail::fetchMail() |
| mail_html | HTML本文 | Mail::fetchMail() |
| mail_status | 送信ステータス | Mail::fetchMail() |

#### assets（添付ファイル）

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| asset_file | ファイルパス | Attachments::fetchAttachments(type='M') |
| asset_name | ファイル名 | Attachments::fetchAttachments(type='M') |
| asset_extension | 拡張子 | Attachments::fetchAttachments(type='M') |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| mail | UPDATE | メール内容の更新（送信前に最新内容を保存） |

#### mailテーブル更新

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| UPDATE | mail_slave | フォーム入力値 | 送信先ID |
| UPDATE | mail_subject | フォーム入力値 | 件名 |
| UPDATE | mail_text | フォーム入力値 | テキスト本文 |
| UPDATE | mail_html | html_entity_decode(フォーム入力値) | HTML本文 |
| UPDATE | mail_date | NOW() | 更新日時 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 権限エラー | mmailまたはmmailsend権限がない | 権限エラー画面（privileges）にフォワード |
| 宛先未入力 | slaveパラメータが空 | エラーメッセージ「To is required」を表示 |
| 件名未入力 | subjectパラメータが空 | エラーメッセージ「Subject is required」を表示 |
| 送信済み | mail_status='sent' | エラーメッセージ「Mail Already Sent!」を表示 |
| メール送信失敗 | SMTP接続エラー等 | Zend_Mailが例外をスロー |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

配信時間帯の制限は設けられていない。24時間いつでも送信可能。

## セキュリティ考慮事項

- テスト送信は操作者本人にのみ送信されるため、第三者への誤送信リスクは低い
- 管理者権限（mmail + mmailsend）による操作制限あり
- 確認ダイアログによる誤操作防止機能あり
- 添付ファイルは$syspathからの相対パスで取得されるため、パストラバーサルのリスクに注意
- HTML本文にはhtml_entity_decodeが適用されるため、XSS攻撃のリスクを含む可能性

## 備考

- 本機能はZend Framework 1.x系のZend_Mailコンポーネントを使用している
- テキスト版とHTML版の両方が設定されている場合、両方のメールが別々に送信される
- 添付ファイルはcreateAttachment()で動的に添付される
- 添付ファイルのパスは$registry->assets->assets->syspathから取得される
- テスト送信しても mail_status は変更されない（draftのまま）
- 送信設定はレジストリ（`$registry->mail`）で管理されるトランスポート設定に依存する

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、メール配信に必要なデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mail テーブル | データベース | mail_id, mail_subject, mail_text, mail_html, mail_status の構造 |
| 1-2 | assets テーブル | データベース | asset_file, asset_name, asset_extension の構造 |

**読解のコツ**: メールと添付ファイルは別テーブルで管理され、type='M'で関連付けられる。

#### Step 2: エントリーポイントを理解する

処理の起点となるコントローラーとアクションを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MailController.php | `application/modules/admin/controllers/MailController.php` | sendtestAction()メソッドがエントリーポイント |

**主要処理フロー**:
1. **行512**: `sendtestAction()`メソッド開始
2. **行514**: 権限チェック（mmail AND mmailsend）
3. **行516-517**: レイアウト・ビュー無効化
4. **行519-520**: URLパラメータ取得（confirm, id）
5. **行522**: confirm=1かつID存在チェック
6. **行524-562**: バリデーション設定とフィルタ
7. **行564**: バリデーション実行
8. **行566-571**: メール情報と添付ファイル情報取得
9. **行573**: アセットパス取得
10. **行575**: mail_status != 'sent'チェック
11. **行577-582**: メール情報更新
12. **行584**: 最新メール情報再取得
13. **行586-644**: 条件分岐でメール送信（text/html/両方/なし）
14. **行646-651**: 完了メッセージHTML出力

#### Step 3: Mailモデルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Mail.php | `application/models/Mail.php` | fetchMail(), updateMail()メソッド |

**主要処理フロー**:
- **行270-284**: fetchMail() - メール情報取得
- **行406-418**: updateMail() - メール情報更新

### プログラム呼び出し階層図

```
Admin_MailController::sendtestAction()
    │
    ├─ ACL権限チェック (mmail AND mmailsend)
    │
    ├─ URLパラメータ取得 (confirm, id)
    │
    ├─ Zend_Filter_Input (バリデーション)
    │
    ├─ Mail::fetchMail() (メール情報取得)
    │
    ├─ Attachments::fetchAttachments() (添付ファイル取得)
    │
    ├─ Mail::updateMail() (メール情報更新)
    │
    └─ Zend_Mail (テストメール送信)
           ├─ setBodyText() または setBodyHtml()
           ├─ setFrom()
           ├─ addTo() (ログインユーザーのメールアドレス)
           ├─ setSubject()
           ├─ createAttachment() (ループ)
           └─ send()
```

### データフロー図

```
[入力]                    [処理]                    [出力]

フォームデータ ─────▶ 権限チェック ──────────▶ エラー/続行判定
(slave, subject,            │
text, html)                 ▼
                     confirm判定
                           │
              ┌────────────┴────────────┐
              ▼                          ▼
         confirm!=1                 confirm=1
         確認ダイアログ              バリデーション
                                        │
                                        ▼
                                  メール情報取得
                                  添付ファイル取得
                                        │
                                        ▼
                                  メール情報更新 ───▶ mailテーブル
                                        │
                                        ▼
                                  メール送信判定
                                  (text/html/両方/なし)
                                        │
                                        ▼
                                  メール送信 ────────▶ ログインユーザー
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MailController.php | `application/modules/admin/controllers/MailController.php` | ソース | テストメール送信処理のコントローラー |
| Mail.php | `application/models/Mail.php` | ソース | メール情報の取得・更新モデル |
| Attachments.php | `application/models/Attachments.php` | ソース | 添付ファイル情報の取得モデル |
| CMS_Controller_Action_Admin | `library/CMS/Controller/Action/Admin.php` | ソース | 管理画面コントローラーの基底クラス |
| edit.phtml | `application/modules/admin/views/scripts/mail/edit.phtml` | テンプレート | メール編集画面のビュー |
