# 画面設計書 65-メール編集画面

## 概要

本ドキュメントは、Legacy CMSの管理画面における「メール編集画面」の設計仕様を定義するものである。この画面はメールの内容編集と送信機能を提供する。

### 本画面の処理概要

**業務上の目的・背景**：組織からユーザーへのメール配信において、メール本文の作成・編集は重要なプロセスである。本画面は、下書き状態のメールの宛先、件名、本文（テキスト版・HTML版）を編集し、テスト送信や本送信を行うための機能を提供する。テキスト版とHTML版の両方をサポートすることで、受信者のメール設定に応じた適切な形式でメールを配信できる。また、添付ファイル機能により、ドキュメントや画像をメールに添付して送信することが可能である。

**画面へのアクセス方法**：メール管理画面（/admin/mail/manage/）のメール一覧から件名リンクまたは「Edit」リンクをクリックしてアクセスする。新規メール作成ダイアログで作成後、自動的にこの画面へリダイレクトされる。URLは `/admin/mail/edit/id/{mail_id}/`。

**主要な操作・処理内容**：
1. 宛先の変更（メーリングリスト、ロール、ユーザーから選択）
2. 件名の編集
3. テキスト本文の編集
4. HTML本文の編集（FCKeditorによるリッチテキスト編集）
5. 添付ファイルの追加・削除
6. メールの保存
7. テストメールの送信（自分宛に送信）
8. 本メールの送信
9. メールの削除

**画面遷移**：メール管理画面から遷移してくる。新規メール作成ダイアログからも遷移可能。保存後は同画面に留まり、削除後はメール管理画面へリダイレクトされる。「Mail...」ボタンでメール管理画面へ戻ることができる。

**権限による表示制御**：`uusers`権限と`uview`権限が必要。メール削除には`mmaildelete`権限が必要。メール送信には`mmailsend`権限が必要。送信済みメールは編集不可（Save、Delete、Send Test、Sendボタンが非表示）。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 59 | メール送信 | 主機能 | メールの編集・送信処理 |
| 63 | 入力検証 | 補助機能 | メールフォームのバリデーション |

## 画面種別

編集

## URL/ルーティング

- URL: `/admin/mail/edit/id/{mail_id}/`
- モジュール: admin
- コントローラー: MailController
- アクション: editAction

## 入出力項目

| 項目名 | 項目ID | データ型 | 必須 | 最大長 | 入力形式 | 備考 |
|--------|--------|----------|------|--------|----------|------|
| 宛先 | slave | integer | Yes | - | セレクト/非表示 | メールタイプにより表示形式が異なる |
| 件名 | subject | string | Yes | - | テキスト入力 | ValidationTextBox使用 |
| テキスト本文 | text | text | No | - | テキストエリア | SimpleTextarea使用 |
| HTML本文 | html | text | No | - | FCKeditor | HTMLリッチテキスト |

## 表示項目

| 項目名 | データソース | 表示形式 | 備考 |
|--------|--------------|----------|------|
| 著者名 | users.user_alias | テキスト | 詳細パネルに表示 |
| ステータス | mail.mail_status | テキスト | ucwords()で整形 |
| 送信日時 | mail.mail_sent | d/m/Y H:i | 送信済みの場合のみ表示 |
| 最終編集日時 | mail.mail_date | d/m/Y H:i | 下書き状態の場合のみ表示 |
| 添付ファイル一覧 | attachments | リスト | Attachmentsタブ |

## イベント仕様

### 1-保存ボタン押下

FCKeditorの内容を更新後、Ajaxダイアログ経由で `/admin/mail/save/id/{mail_id}/` にPOSTリクエストを送信する。バリデーション成功時はmailテーブルを更新する。送信済みメールの場合は保存不可。

### 2-削除ボタン押下

`mmaildelete`権限があり、かつ送信済みでない場合のみ表示。getDialog()で `/admin/mail/delete/id/{mail_id}/` を呼び出し、削除確認ダイアログを表示する。

### 3-Send Testボタン押下

`mmailsend`権限があり、かつ送信済みでない場合のみ表示。FCKeditorの内容を更新後、getDialog()で `/admin/mail/sendtest/id/{mail_id}/` を呼び出す。確認後、現在ログインしているユーザー宛にテストメールを送信する。

### 4-Sendボタン押下

`mmailsend`権限があり、かつ送信済みでない場合のみ表示。FCKeditorの内容を更新後、getDialog()で `/admin/mail/send/id/{mail_id}/` を呼び出す。確認後、宛先（メーリングリスト、ロール、ユーザー）に応じてメールを送信し、ステータスを「sent」に更新する。

### 5-Mail...ボタン押下

goTo()関数を使用して `/admin/mail/` にリダイレクトする。

### 6-Browseボタン押下（添付ファイル）

送信済みでない場合のみ表示。アセット管理画面をモーダルウィンドウで開き、添付するファイルを選択する。

### 7-Add Attachmentボタン押下

選択したアセットを添付ファイルとして追加する。

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | mail | UPDATE | メール情報を更新 |
| 削除ボタン押下 | mail | DELETE | メールを削除 |
| 削除ボタン押下 | attachments | DELETE | 関連添付ファイルを削除 |
| 送信ボタン押下 | mail | UPDATE | ステータスを'sent'に更新、送信日時を設定 |

### テーブル別更新項目詳細

#### mail

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | mail_slave | フォーム入力値 | 保存時 |
| UPDATE | mail_subject | フォーム入力値 | 保存時 |
| UPDATE | mail_text | フォーム入力値（StripTags適用） | 保存時 |
| UPDATE | mail_html | フォーム入力値（html_entity_decode適用） | 保存時 |
| UPDATE | mail_date | NOW() | 保存時 |
| UPDATE | mail_status | 'sent' | 送信時のみ |
| UPDATE | mail_sent | NOW() | 送信時のみ |
| DELETE | - | WHERE mail_id = {id} | 削除時 |

## メッセージ仕様

| メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|-------------|---------------|---------------|----------|
| MSG001 | 成功 | Mail Saved | 保存成功時 |
| MSG002 | 成功 | Mail Deleted | 削除成功時 |
| MSG003 | 成功 | Test Mail Sent | テスト送信成功時 |
| MSG004 | 成功 | Mail Sent | 本送信成功時 |
| MSG005 | 確認 | Are you sure you want to delete this mail? | 削除確認時 |
| MSG006 | 確認 | This will send a test mail to: {user_email} | テスト送信確認時 |
| MSG007 | 確認 | Are you sure you want to send this mail? | 本送信確認時 |
| MSG008 | エラー | Mail Not Specified! | メールID未指定時 |
| MSG009 | エラー | Mail Already Sent! | 送信済みメールを編集しようとした時 |
| MSG010 | エラー | To is required | 宛先未選択時 |
| MSG011 | エラー | Subject is required | 件名未入力時 |

## 例外処理

| 例外状態 | 対応処理 |
|----------|----------|
| メールIDが未指定または無効 | メール管理画面へリダイレクト |
| 該当メールが存在しない | メール管理画面へリダイレクト |
| 権限不足 | 権限エラー画面へフォワード |
| 送信済みメールの編集試行 | エラーメッセージを表示 |
| バリデーションエラー | エラーメッセージをダイアログに表示 |

## 備考

- メール送信タイプは3種類：G（グループ/メーリングリスト宛）、R（ロール宛）、U（ユーザー宛）
- メールタイプがUの場合、宛先は読み取り専用で表示される
- テキスト本文とHTML本文の両方を設定した場合、受信者のメール設定に応じて適切な形式が配信される
- 添付ファイルは送信済みの場合、追加・削除ができない
- HTML本文にはフルURLを使用する必要がある（相対・絶対パスは不可）
- テスト送信は現在ログインしているユーザーのメールアドレスに送信される

---

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

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

### 推奨読解順序

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

メールデータの構造と送信タイプを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Mail.php | `application/models/Mail.php` | mailテーブルのカラム構造、fetchMail()、updateMail() |

**読解のコツ**: mail_typeカラムの値（G/R/U）と、それに対応するmail_slaveの解釈（グループID/ロールID/ユーザーID）を理解する。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MailController.php | `application/modules/admin/controllers/MailController.php` | editAction()メソッド（220-238行目） |

**主要処理フロー**:
1. **222行目**: 権限チェック（uusersとuview）
2. **224行目**: URLパラメータからメールIDを取得
3. **226-227行目**: Mailモデルを使用してメールデータを取得
4. **229-231行目**: メールが存在しない場合は一覧画面へリダイレクト

#### Step 3: ビューテンプレートを理解する

編集画面のUIを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.phtml | `application/modules/admin/views/scripts/mail/edit.phtml` | 編集フォームUI、タブ構造 |
| 3-2 | details.phtml | `application/modules/admin/views/scripts/mail/details.phtml` | 詳細・機能ボタンパネル |

**主要処理フロー**:
- **47-142行目** (edit.phtml): Mailタブ（宛先、件名、本文）
- **53-88行目** (edit.phtml): 宛先フィールド（タイプ別に分岐）
- **125-133行目** (edit.phtml): FCKeditorの初期化
- **144-180行目** (edit.phtml): Attachmentsタブ
- **33-39行目** (details.phtml): 操作ボタン（Save、Delete、Send Test、Send）

#### Step 4: 保存処理を理解する

保存ボタン押下時の処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | MailController.php | `application/modules/admin/controllers/MailController.php` | saveAction()（55-169行目） |
| 4-2 | Mail.php | `application/models/Mail.php` | updateMail()（406-418行目） |

#### Step 5: 送信処理を理解する

メール送信の処理フローを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | MailController.php | `application/modules/admin/controllers/MailController.php` | sendAction()（700-1158行目） |

**主要処理フロー**:
- **774-885行目**: グループ宛送信（mail_type = 'G'）
- **887-995行目**: ロール宛送信（mail_type = 'R'）
- **997-1105行目**: ユーザー宛送信（mail_type = 'U'）
- テキスト/HTML両方がある場合は受信者の設定に応じて分けて送信

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

```
editAction() [MailController.php:220]
    │
    ├─ acl->isAllowed() [権限チェック]
    │
    └─ Mail->fetchMail() [Mail.php:270]
           │
           └─ registry->db->fetchall() [DB検索]
                  │
                  ▼
           View rendering [edit.phtml]
                  │
                  └─ Ajax: /admin/mail/details [details.phtml]

saveAction() [MailController.php:55]
    │
    ├─ Zend_Filter_Input [バリデーション]
    │
    └─ Mail->updateMail() [Mail.php:406]
           └─ registry->db->update() [mail更新]

sendAction() [MailController.php:700]
    │
    ├─ Mail->fetchMail() [メール情報取得]
    │
    ├─ Attachments->fetchAttachments() [添付ファイル取得]
    │
    ├─ Mail->updateMail() [保存]
    │
    └─ [送信タイプ別分岐]
           │
           ├─ [G: グループ宛]
           │      ├─ Mail->fetchSubscriptions() [購読者取得]
           │      └─ Zend_Mail->send() [メール送信]
           │
           ├─ [R: ロール宛]
           │      ├─ Mail->fetchUsers() [ユーザー取得]
           │      └─ Zend_Mail->send() [メール送信]
           │
           └─ [U: ユーザー宛]
                  ├─ Mail->fetchUsers() [ユーザー取得]
                  └─ Zend_Mail->send() [メール送信]
```

### データフロー図

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

フォーム入力 ─────────▶ MailController ─────────▶ Ajaxダイアログ
(slave, subject,         saveAction()               (成功/エラーメッセージ)
 text, html)                  │
                              │
                              ▼
                        Zend_Filter_Input
                        (バリデーション・フィルタ)
                              │
                              ▼
                        Mail->updateMail()
                              │
                              └──────────▶ mailテーブル
                                           (UPDATE)

[送信時]
                        MailController
                        sendAction()
                              │
                              ├──────────▶ mailテーブル
                              │            (状態確認)
                              │
                              ├──────────▶ attachmentsテーブル
                              │            (添付ファイル取得)
                              │
                              ├──────────▶ mail_subscriptions
                              │            (購読者取得/グループ宛時)
                              │
                              ├──────────▶ usersテーブル
                              │            (送信先ユーザー取得)
                              │
                              └──────────▶ SMTPサーバー
                                           (Zend_Mail経由で送信)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MailController.php | `application/modules/admin/controllers/MailController.php` | ソース | メール管理のコントローラー |
| Mail.php | `application/models/Mail.php` | ソース | メールデータのモデル |
| Attachments.php | `application/models/Attachments.php` | ソース | 添付ファイルのモデル |
| edit.phtml | `application/modules/admin/views/scripts/mail/edit.phtml` | テンプレート | 編集画面のビュー |
| details.phtml | `application/modules/admin/views/scripts/mail/details.phtml` | テンプレート | 詳細パネルのビュー |
| attachments.js | `public/_scripts/admin/attachments.js` | JavaScript | 添付ファイル管理スクリプト |
| common.js | `public/_scripts/admin/common.js` | JavaScript | 共通ユーティリティ関数 |
| fckeditor.php | `public/_scripts/fckeditor/fckeditor.php` | ライブラリ | FCKeditorのPHPラッパー |
| template.css | `public/_styles/admin/template.css` | スタイル | 管理画面共通スタイル |
