# 機能設計書 31-アセット選択

## 概要

本ドキュメントは、LEGACY CMSにおけるアセット選択機能の設計を記載したものである。コンテンツ編集時にアップロード済みのアセット（画像・ファイル）をポップアップダイアログから選択し、エディタに挿入する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：コンテンツ（記事、ページ、イベント等）の編集において、テキストだけでなく画像やファイルリンクを挿入する必要がある。アセット選択機能は、アップロード済みのファイルを視覚的に一覧表示し、管理者が直感的に目的のファイルを選択できるようにすることで、コンテンツ作成の効率を向上させる。

**機能の利用シーン**：記事編集画面やページ編集画面でリッチテキストエディタを使用中に、画像を挿入したい場合や、ファイルへのダウンロードリンクを挿入したい場合に、ツールバーのボタンをクリックしてアセット選択ポップアップを開く。フォルダを階層的にナビゲートし、目的のファイルを選択して挿入する。

**主要な処理内容**：
1. アセット一覧の取得とフォルダ階層表示
2. アセットタイプ（画像・動画・音声・その他）によるフィルタリング
3. 画像挿入時のリサイズオプション設定とプレビュー表示
4. リンク挿入時のダウンロード/ブラウザ表示オプション選択
5. 選択したアセットのエディタへの挿入処理

**関連システム・外部連携**：Dojo Toolkitを使用したAjaxダイアログでポップアップを表示。リッチテキストエディタ（Editor）との連携により、選択したアセットをHTMLとして挿入する。

**権限による制御**：`fassets`権限を持つユーザーのみアセット選択機能を利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 83 | 画像挿入画面 | 主画面 | エディタへの画像挿入ダイアログ |
| 84 | リンク挿入画面 | 主画面 | エディタへのリンク挿入ダイアログ |
| 89 | スライド編集画面 | 参照画面 | スライド画像の選択 |
| 90 | スライド新規作成画面 | 参照画面 | スライド画像の選択 |

## 機能種別

UI操作 / アセット参照 / データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| type | string | No | アセットタイプフィルタ（image, video, audio, other） | 許可された値のみ |
| folder | string | No | 現在のフォルダID（デフォルト: '0' = ルート） | 数値または'0' |
| method | string | Yes | 選択モード（editor, link, select） | 許可された値のみ |
| field | string | No | 選択結果を格納するフォームフィールド名 | - |
| key | string | No | アセットキー（画像挿入時） | MD5形式 |
| width | integer | No | 画像リサイズ幅（画像挿入時） | 正の整数 |
| height | integer | No | 画像リサイズ高さ（画像挿入時） | 正の整数 |

### 入力データソース

- URLパラメータ（フォルダ、タイプ、メソッド、フィールド）
- フォーム入力（画像サイズ、リサイズタイプ）
- データベース（アセット情報、フォルダ情報）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| folderArray | array | サブフォルダ一覧 |
| assetArray | array | アセット一覧 |
| parentArray | array | 親フォルダ情報 |
| size | array | 画像サイズ（width, height） |

### 出力先

- HTMLビュー（アセット一覧表示）
- JavaScriptコールバック（選択結果のエディタ挿入）

## 処理フロー

### 処理シーケンス

```
1. アセット選択ダイアログの表示
   └─ エディタのツールバーボタンクリックでgetDialog()呼び出し
2. 権限チェック
   └─ fassets権限の確認
3. フォルダ・アセット一覧の取得
   └─ 指定フォルダ内のサブフォルダとアセットをDB検索
4. アセットタイプによるフィルタリング
   └─ typeパラメータが指定されている場合、該当タイプのみ表示
5. アセット選択
   └─ method=editor: 画像挿入ダイアログへ遷移
   └─ method=link: リンク挿入ダイアログへ遷移
   └─ method=select: chooseFile()でフィールドに値セット
6. 画像挿入処理（画像の場合）
   └─ サイズ・リサイズタイプを指定してプレビュー
   └─ imageInsert()でエディタにIMGタグ挿入
7. リンク挿入処理（ファイルの場合）
   └─ ダウンロード or ブラウザ表示を選択
   └─ linkInsert()でエディタにAタグ挿入
```

### フローチャート

```mermaid
flowchart TD
    A[エディタからアセット選択起動] --> B{権限チェック}
    B -->|権限なし| C[エラー画面へ転送]
    B -->|権限あり| D[フォルダ・アセット一覧取得]
    D --> E{タイプフィルタあり?}
    E -->|Yes| F[該当タイプのみ表示]
    E -->|No| G[全アセット表示]
    F --> H[アセット一覧表示]
    G --> H
    H --> I{ユーザー操作}
    I -->|フォルダ選択| D
    I -->|アセット選択| J{選択モード判定}
    J -->|editor + 画像| K[画像挿入ダイアログ]
    J -->|editor + その他| L[insertFile実行]
    J -->|link| M[リンク挿入ダイアログ]
    J -->|select| N[chooseFile実行]
    K --> O[サイズ設定・プレビュー]
    O --> P[imageInsert実行]
    M --> Q[リンクタイプ選択]
    Q --> R[linkInsert実行]
    P --> S[ダイアログ終了]
    L --> S
    R --> S
    N --> S
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-31-01 | アセットタイプ判定 | MIMEタイプに基づきimage/video/audio/otherに分類 | アセット選択・表示時 |
| BR-31-02 | 画像リサイズモード | Fit to Box/Adaptive Crop/Crop from Centerの3種類 | 画像挿入時 |
| BR-31-03 | リンクタイプ | ダウンロード/ブラウザ表示の2種類 | リンク挿入時 |

### 計算ロジック

**アセットタイプ判定（assetType関数）**:
- image: image/jpeg, image/gif, image/png, image/bmp
- video: video/x-flv
- audio: audio/mpeg
- flash: application/x-shockwave-flash
- other: 上記以外

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| フォルダ一覧取得 | assets_folders | SELECT | 指定親フォルダのサブフォルダ取得 |
| アセット一覧取得 | assets | SELECT | 指定フォルダ内のアセット取得 |
| アセット詳細取得 | assets | SELECT | キーでアセット情報取得（画像挿入時） |

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

#### assets_folders

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | folder_id, folder_name, folder_parent | folder_parent = :folder | フォルダ名昇順 |

#### assets

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 全項目 | asset_folder = :folder | アセット名昇順 |
| SELECT | 全項目 | asset_key = :key | 画像挿入時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 権限エラー | fassets権限なし | privileges画面へ転送 |
| - | アセット未検出 | 指定キーのアセットなし | - |

### リトライ仕様

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

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

読み取り専用のため、トランザクション管理は不要。

## パフォーマンス要件

- アセット一覧の表示は1秒以内
- サムネイル生成はキャッシュを活用し、2回目以降は即座に表示

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

- 権限チェック（fassets）によるアクセス制御
- asset_keyはMD5ハッシュ値で、直接的なファイルパス露出を防止

## 備考

- Dojo ToolkitのdijitコンポーネントによるAjaxダイアログを使用
- サムネイル画像はPhpThumbFactoryで動的生成・キャッシュ

---

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

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

### 推奨読解順序

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

アセット選択機能では、assetsテーブルとassets_foldersテーブルのデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AssetsController.php | `application/modules/admin/controllers/AssetsController.php` | indexAction()の59-114行目でフォルダ・アセット一覧取得のクエリ構造を確認 |

**読解のコツ**: Zend_Db_Select を使用したクエリビルダー形式。`$registry->db->select()->from()->where()->order()` の流れでSQLが構築される。

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

アセット選択のエントリーポイントは複数のアクションに分かれている。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AssetsController.php | `application/modules/admin/controllers/AssetsController.php` | indexAction()がアセット一覧表示の起点 |
| 2-2 | AssetsController.php | `application/modules/admin/controllers/AssetsController.php` | imageinsertAction()が画像挿入ダイアログの起点 |
| 2-3 | AssetsController.php | `application/modules/admin/controllers/AssetsController.php` | linkinsertAction()がリンク挿入ダイアログの起点 |

**主要処理フロー**:
1. **59-61行目**: 権限チェック（fassets）
2. **65-68行目**: パラメータ取得（type, folder, method, field）
3. **77-88行目**: 親フォルダ情報の取得（ルート以外の場合）
4. **92-108行目**: サブフォルダとアセット一覧の取得

#### Step 3: アセットタイプ判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AssetsController.php | `application/modules/admin/controllers/AssetsController.php` | assetType()メソッド（31-54行目）でMIMEタイプからアセット種別を判定 |

**主要処理フロー**:
- **33-38行目**: 各種ファイルタイプの配列定義（images, videos, audio, flash）
- **41-51行目**: in_array()で判定してタイプ文字列を返却

#### Step 4: 画像挿入処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AssetsController.php | `application/modules/admin/controllers/AssetsController.php` | imageinsertAction()（1043-1078行目）で画像サイズ取得 |
| 4-2 | imageinsert.phtml | `application/modules/admin/views/scripts/assets/imageinsert.phtml` | 画像挿入ダイアログのUI |

**主要処理フロー**:
- **1055-1061行目**: asset_keyでアセット情報を取得
- **1069-1071行目**: getimagesize()で画像の元サイズを取得してビューに渡す

#### Step 5: ビュー層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | index.phtml | `application/modules/admin/views/scripts/assets/index.phtml` | アセット一覧表示の全体構造 |
| 5-2 | imageinsert.phtml | `application/modules/admin/views/scripts/assets/imageinsert.phtml` | 画像挿入フォームとプレビュー |
| 5-3 | linkinsert.phtml | `application/modules/admin/views/scripts/assets/linkinsert.phtml` | リンク挿入フォーム |

**主要処理フロー**:
- **index.phtml 98-122行目**: typeフィルタとmethodによる表示分岐
- **index.phtml 102-122行目**: method=editor/link/selectそれぞれの処理分岐
- **imageinsert.phtml 53-68行目**: imagePreview()とimageInsert()のボタン

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

```
Admin_AssetsController
    │
    ├─ indexAction() [アセット一覧表示]
    │      ├─ setLayout()
    │      └─ DBクエリ（assets, assets_folders）
    │
    ├─ imageinsertAction() [画像挿入ダイアログ]
    │      ├─ DBクエリ（assets）
    │      └─ getimagesize()
    │
    ├─ linkinsertAction() [リンク挿入ダイアログ]
    │
    ├─ thumbpreviewAction() [サムネイルプレビュー]
    │      └─ PhpThumbFactory::create()
    │
    └─ assetType() [アセットタイプ判定]
```

### データフロー図

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

URLパラメータ         ┌─────────────────────┐
(type,folder,       │  AssetsController   │
method,field)  ────▶│                     │
                    │  indexAction()      │────▶  ビュー(index.phtml)
                    │  - 権限チェック      │       - フォルダ一覧
                    │  - DB検索           │       - アセット一覧
DBテーブル          │                     │
(assets,       ────▶│                     │
assets_folders)     └─────────────────────┘

URLパラメータ         ┌─────────────────────┐
(key)           ────▶│ imageinsertAction() │────▶  ビュー(imageinsert.phtml)
                    │ - アセット取得       │       - 画像サイズ情報
                    │ - サイズ取得         │       - プレビュー/挿入ボタン
                    └─────────────────────┘

JavaScript              ┌─────────────────────┐
imageInsert()      ────▶│  エディタ挿入処理    │────▶  リッチテキストエディタ
linkInsert()            │  (クライアントサイド) │       HTMLコンテンツ
chooseFile()            └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AssetsController.php | `application/modules/admin/controllers/AssetsController.php` | コントローラー | アセット管理の全アクション |
| index.phtml | `application/modules/admin/views/scripts/assets/index.phtml` | ビュー | アセット一覧表示 |
| imageinsert.phtml | `application/modules/admin/views/scripts/assets/imageinsert.phtml` | ビュー | 画像挿入ダイアログ |
| linkinsert.phtml | `application/modules/admin/views/scripts/assets/linkinsert.phtml` | ビュー | リンク挿入ダイアログ |
| imagepreview.phtml | `application/modules/admin/views/scripts/assets/imagepreview.phtml` | ビュー | 画像プレビュー表示 |
| AssetType.php | `application/modules/admin/views/helpers/AssetType.php` | ビューヘルパー | アセットタイプ判定 |
| assets.js | `public/_scripts/admin/assets.js` | JavaScript | クライアント側処理 |
| common.js | `public/_scripts/admin/common.js` | JavaScript | 共通Ajax処理(getDialog等) |
