# 機能設計書 55-添付ファイル追加

## 概要

本ドキュメントは、LEGACY CMSにおける添付ファイル追加機能の設計を定義する。この機能は、コンテンツに添付ファイルを追加するための機能である。

### 本機能の処理概要

**業務上の目的・背景**：コンテンツ管理において、記事やページに関連するファイル（PDF、画像、文書など）を添付することは重要な要件である。この機能により、管理者は既存のアセット（アップロード済みファイル）をコンテンツに紐づけることができ、ユーザーにダウンロード可能なファイルや補足資料を提供できる。

**機能の利用シーン**：管理画面で記事やページなどのコンテンツを編集する際、「Attachments」タブ内でアセット選択ダイアログからファイルを選び、「Add」ボタンをクリックして添付する。重複チェックにより、同じアセットが二重に添付されることを防止する。

**主要な処理内容**：
1. POSTリクエストからtype、slave、assetパラメータを取得
2. 重複チェック（同一コンテンツに同一アセットが既に添付されていないか）
3. バリデーション（必須パラメータの検証）
4. attachmentsテーブルへのレコード挿入
5. 結果メッセージの表示

**関連システム・外部連携**：アセット選択機能（dijit.Dialog）との連携。添付するファイルはアセット管理で事前にアップロードされている必要がある。

**権限による制御**：添付ファイルの追加は、該当コンテンツの編集権限を持つユーザーが利用可能。コントローラはCMS_Controller_Action_Adminを継承しており、管理者認証が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 36 | 記事編集画面 | 主画面 | 記事に添付ファイルを追加 |
| 49 | イベント編集画面 | 主画面 | イベントに添付ファイルを追加 |
| 61 | ページ編集画面 | 主画面 | ページに添付ファイルを追加 |
| 65 | メール編集画面 | 主画面 | メールに添付ファイルを追加 |

## 機能種別

CRUD操作（Create）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| type | string | Yes | コンテンツタイプ（A=記事, P=ページ, M=メール等） | NotEmpty |
| slave | integer | Yes | コンテンツID（スレーブID） | NotEmpty |
| asset | string | Yes | アセットキー（assets.asset_key） | NotEmpty |

### 入力データソース

- POSTリクエストで送信されるフォームデータ
- Ajax経由でリクエストされる

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 結果メッセージ | HTML | 追加完了/重複/エラーメッセージとCloseボタンを含むHTML |

### 出力先

- Ajaxダイアログ（dijit.Dialog）内にHTML形式で出力

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ newActionメソッドがコールされる
2. レイアウト・ビュー無効化
   └─ Ajax応答のためレイアウトとビューレンダリングを無効化
3. POSTチェック
   └─ POSTリクエストかどうかを確認
4. パラメータ取得
   └─ type、slave、assetをPOSTから取得
5. 重複チェック
   └─ 同一type/slave/assetの組み合わせが既存か確認
6. バリデーション
   └─ Zend_Filter_Inputで入力検証
7. データベース挿入実行
   └─ attachmentsテーブルに新規レコード挿入
8. 結果出力
   └─ 成功/重複/エラーメッセージをHTML出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[newAction呼び出し]
    B --> C[レイアウト・ビュー無効化]
    C --> D{POSTリクエスト?}
    D -->|No| E["No data received" 出力]
    D -->|Yes| F[パラメータ取得]
    F --> G[DB: 重複チェッククエリ]
    G --> H{重複あり?}
    H -->|Yes| I["Duplicate Attachment" 出力]
    H -->|No| J[Zend_Filter_Inputでバリデーション]
    J --> K{バリデーション成功?}
    K -->|No| L[エラーメッセージ出力]
    K -->|Yes| M[DB: attachmentsにINSERT]
    M --> N["Attachment Added" 出力]
    E --> O[終了]
    I --> O
    L --> O
    N --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-55-01 | 重複チェック | 同一コンテンツに同一アセットは1回のみ添付可能 | 常時 |
| BR-55-02 | 必須パラメータ | type、slave、assetは全て必須 | 常時 |
| BR-55-03 | POSTメソッド | 追加処理はPOSTメソッドでのみ受け付ける | 常時 |

### 計算ロジック

計算ロジックは存在しない。

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 重複チェック | attachments | SELECT | 同一添付の存在確認 |
| 添付ファイル追加 | attachments | INSERT | 新規添付レコード作成 |

### テーブル別操作詳細

#### attachments（SELECT - 重複チェック）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | WHERE attach_type = {type} AND attach_slave = {slave} AND attach_asset = {asset} | 重複確認 |

#### attachments（INSERT）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | attach_type | {type} | コンテンツタイプ |
| INSERT | attach_asset | {asset} | アセットキー |
| INSERT | attach_slave | {slave} | コンテンツID |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 重複エラー | 同一添付が既存 | "Duplicate Attachment" メッセージ表示 |
| - | バリデーションエラー | 必須パラメータ未入力 | 各フィールドのエラーメッセージ表示 |
| - | リクエストエラー | POSTメソッド以外 | "No data received" メッセージ表示 |

### リトライ仕様

リトライ処理は実装されていない。

## トランザクション仕様

単一のINSERT文による追加のため、明示的なトランザクション制御は行われていない。

## パフォーマンス要件

- Ajax経由での即時応答が求められる
- 重複チェックのため、attach_type, attach_slave, attach_assetの複合インデックスが推奨

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

- CMS_Controller_Action_Adminを継承しており、管理者認証が必須
- Zend_Filter_Inputによる入力フィルタリング・バリデーション実施
- POSTリクエストのみ受け付けることでCSRF対策の基盤を提供

## 備考

- フィルターにtagフィールドが定義されているが、実際にはassetフィールドを使用（コード流用の痕跡）
- 添付後は添付ファイル一覧がContentPaneの再読み込みで更新される

---

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

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

### 推奨読解順序

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

添付ファイルのデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Attachments.php | `application/models/Attachments.php` | attachmentsテーブル構造の理解 |

**読解のコツ**: attach_typeはコンテンツタイプを表す文字コード、attach_slaveはコンテンツIDへの参照、attach_assetはassetsテーブルのasset_keyへの参照。

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

コントローラのアクションを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AttachmentsController.php | `application/modules/admin/controllers/AttachmentsController.php` | newActionメソッドの処理フロー |

**主要処理フロー**:
1. **83-193行目**: newAction - 添付ファイル追加処理全体
2. **85-86行目**: レイアウトとビューの無効化
3. **88-111行目**: POSTチェックと重複確認クエリ
4. **113-141行目**: バリデーター定義
5. **146-163行目**: バリデーション成功時のINSERTと成功メッセージ
6. **165-176行目**: バリデーション失敗時のエラーメッセージ
7. **180-187行目**: 重複時のエラーメッセージ

#### Step 3: バリデーションを理解する

入力検証の仕組みを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AttachmentsController.php | `application/modules/admin/controllers/AttachmentsController.php` | Zend_Filter_Inputの使用方法 |

**主要処理フロー**:
- **119-121行目**: フィルター定義（StringTrim, StripTags）
- **123-139行目**: バリデーター定義（NotEmpty）
- **141行目**: Zend_Filter_Inputのインスタンス化
- **146行目**: isValid()でバリデーション実行

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

```
Admin_AttachmentsController::newAction()
    │
    ├─ $this->_helper->layout()->disableLayout()
    │
    ├─ $this->_helper->viewRenderer->setNoRender(true)
    │
    ├─ $this->_request->isPost()
    │
    ├─ $this->_getParam('type')
    ├─ $this->_getParam('slave')
    ├─ $this->_getParam('asset')
    │
    ├─ $registry->db->select() [重複チェック]
    │      ├─ ->from('attachments')
    │      ├─ ->where('attach_type = ?', $type)
    │      ├─ ->where('attach_slave = ?', $slave)
    │      └─ ->where('attach_asset = ?', $asset)
    │
    ├─ Zend_Filter_Input($filters, $validators, $_POST)
    │
    └─ $registry->db->insert('attachments', $data)
```

### データフロー図

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

POSTデータ ───▶ AttachmentsController ───▶ HTML応答
(type, slave,     ::newAction()           (結果メッセージ)
 asset)                │
                       ▼
                  重複チェック
                  (SELECT)
                       │
                       ▼
                  バリデーション
                  (Zend_Filter_Input)
                       │
                       ▼
                  attachmentsテーブル
                  (INSERT)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AttachmentsController.php | `application/modules/admin/controllers/AttachmentsController.php` | コントローラ | 添付ファイル追加アクションを提供 |
| Attachments.php | `application/models/Attachments.php` | モデル | 添付ファイルデータ構造定義 |
