# 画面設計書 23-フォームパネル

## 概要

本ドキュメントは、Symfony WebProfilerBundleが提供する「フォームパネル」画面の設計書である。Symfony Formコンポーネントで作成されたフォームの構造、バリデーション情報、データ変換情報を表示するプロファイラーパネルの仕様を定義する。

### 本画面の処理概要

**業務上の目的・背景**：Symfony Formコンポーネントはフォームの構築・バリデーション・データ変換を自動化する強力な仕組みであるが、フォームの動作をデバッグする際には、各フォームフィールドの設定・エラー・データ変換の過程を可視化する必要がある。本パネルは、フォームの階層構造をツリー表示し、各フォーム要素のエラー、デフォルトデータ、送信データ、オプション、View変数を詳細に表示することで、フォーム関連の問題の迅速な特定を支援する。

**画面へのアクセス方法**：プロファイラーパネル画面（No.2）の左側メニューから「Forms」パネルを選択する。フォームが存在しない場合はメニューが無効表示される。ツールバー（No.12）にもフォーム数とエラー数のバッジが表示され、クリックでプロファイラーパネルへ遷移する。

**主要な操作・処理内容**：
1. フォーム数・エラー数のメトリクス表示（ツールバー）
2. フォームツリーの階層表示（左ペイン）
3. フォームツリー要素の選択によるフォーム詳細の切替表示
4. フォーム詳細のタブ切替（Errors / Default Data / Submitted Data / Passed Options / Resolved Options / View Vars）
5. 子フォーム要素の開閉操作（トグルボタン）

**画面遷移**：
- 遷移元：プロファイラーパネル（No.2）の左メニュー「Forms」から遷移
- 遷移元：Webデバッグツールバー（No.12）のFormsアイコンクリック

**権限による表示制御**：本画面は開発環境でのみ利用可能である。特定のロールや権限による表示制御はない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | WebProfilerBundle | 主機能 | フォームの構造・バリデーション情報を表示するパネル |
| 34 | Form | 主機能 | Formコンポーネントで作成されたフォームの構造・データ変換情報の表示 |
| 33 | Validator | 補助機能 | フォームに適用されたバリデーション制約の表示 |

## 画面種別

詳細（ツリー＋タブ構成）

## URL/ルーティング

本パネルはプロファイラーパネル（`/_profiler/{token}?panel=form`）の一部として表示される。独自のルートは持たない。

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| token | 入力（URLパラメータ） | string | 必須 | プロファイルトークン（親パネル経由） |
| panel | 入力（クエリパラメータ） | string | 必須 | "form"（親パネル経由） |

## 表示項目

### ツールバー領域

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| フォームアイコン | form.svgアイコン | 静的リソース |
| 数値バッジ | エラー数（エラーあり時）またはフォーム数 | collector.data.nb_errors / collector.data.forms|length |
| Number of forms | フォーム数 | collector.data.forms|length |
| Number of errors | エラー数（エラーあり時は赤色表示） | collector.data.nb_errors |

### メニュー領域

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| Forms | メニューラベル | 固定値 |
| エラーバッジ | エラー数（エラーあり時のみ表示） | collector.data.nb_errors |

### パネル領域 - フォームツリー（左ペイン）

| 項目名 | 説明 |
|--------|------|
| フォーム名 | フォーム要素の名前 |
| エラーバッジ | エラー数（エラーあり時のみ赤色バッジ） |
| トグルボタン | 子フォーム要素の開閉 |

### パネル領域 - フォーム詳細（右ペイン）

#### Errorsタブ

| 項目名 | 説明 |
|--------|------|
| Message | エラーメッセージ |
| Origin | エラーの発生元フォーム |
| Cause | エラーの原因（スタックトレース） |

#### Default Dataタブ

| 項目名 | 説明 |
|--------|------|
| Model Format | モデル形式のデフォルトデータ |
| Normalized Format | 正規化形式のデフォルトデータ |
| View Format | ビュー形式のデフォルトデータ |

#### Submitted Dataタブ

| 項目名 | 説明 |
|--------|------|
| View Format | ビュー形式の送信データ |
| Normalized Format | 正規化形式の送信データ |
| Model Format | モデル形式の送信データ |

#### Passed Optionsタブ

| 項目名 | 説明 |
|--------|------|
| Option | オプション名 |
| Passed Value | 渡された値 |
| Resolved Value | 解決された値（渡された値と異なる場合のみ表示） |

#### Resolved Optionsタブ

| 項目名 | 説明 |
|--------|------|
| Option | オプション名 |
| Value | 解決された値 |

#### View Varsタブ

| 項目名 | 説明 |
|--------|------|
| Variable | 変数名 |
| Value | 変数値 |

## イベント仕様

### 1-フォームツリー要素選択

フォームツリーの要素をクリックすると、JavaScriptにより以下が実行される：
1. 前の選択要素からactiveクラスを除去
2. 前の詳細パネルを非表示にする
3. クリックされた要素にactiveクラスを付加
4. 対応する詳細パネルを表示する

### 2-子フォーム要素の開閉

トグルボタンをクリックすると、JavaScriptにより以下が実行される：
1. 子要素リストの表示/非表示を切り替え
2. ボタンのclosed/openedアイコンを切り替え
3. sessionStorageに開閉状態を保存

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| パネル表示 | （なし） | SELECT | Profilerストレージからプロファイルデータを読み込む |

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

本画面ではデータベースの更新は行わない。

## メッセージ仕様

| 条件 | メッセージ | 種別 |
|------|-----------|------|
| フォームなし | "No forms were submitted." | 情報 |
| エラーなし | "This form has no errors." | 情報 |
| デフォルトデータなし | "This form has default data defined." | 情報 |
| 未送信 | "This form was not submitted." | 情報 |
| Passedオプションなし | "No options were passed when constructing this form." | 情報 |

## 例外処理

- フォームデータが存在しない場合は「No forms were submitted.」メッセージを表示
- ツールバーはフォームが1つも存在しない場合は表示されない（4行目の条件分岐）

## 備考

- フォームデータの表示にはprofiler_dump()関数を使用しており、VarDumperコンポーネントのダンプ表示が行われる
- ツリーの開閉状態はsessionStorageに保存され、ページリロード時に復元される
- エラーがある場合はErrorsタブがアクティブになり、エラーがない場合はDefault Dataタブがアクティブになる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | FormDataCollector.php | `src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php` | フォームデータコレクターのデータ構造。dataByForm, dataByView, formsByView（43-61行目）。collect()メソッドは空実装で、フォームイベントリスナー経由でデータが収集される |

**読解のコツ**: FormDataCollectorはcollect()が空であり、Formコンポーネントのイベントリスナー経由でデータが収集される点が特殊。

#### Step 2: テンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | form.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig` | フォームパネルの主テンプレート。toolbar(3行目)、menu(28行目)、panel(378行目)の3ブロック構造 |

**主要処理フロー**:
1. **3-26行目**: ツールバーブロック - エラー数またはフォーム数をバッジ表示
2. **28-38行目**: メニューブロック - Formsラベルとエラーバッジ
3. **378-400行目**: パネルブロック - ツリーメニュー（左）と詳細コンテナ（右）の2カラム構成
4. **402-431行目**: form_tree_entryマクロ - フォームツリーの再帰的レンダリング
5. **433-498行目**: form_tree_detailsマクロ - フォーム詳細の6タブ表示
6. **500-544行目**: render_form_errorsマクロ - エラーテーブルの表示

#### Step 3: JavaScriptを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | form.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig` | SymfonyProfilerFormPanelクラス（205-374行目）。ツリー選択とトグル状態管理のJavaScript実装 |

**主要処理フロー**:
- **218-241行目**: `#initTrees()` - ツリーアイテムのクリックイベント設定と初期選択
- **243-264行目**: `#selectTreeItem()` - ツリーアイテム選択時の表示切替
- **266-302行目**: `#initTogglerButtons()` - トグルボタンの初期化とsessionStorage復元
- **354-356行目**: `#saveTogglerStates()` - 開閉状態のsessionStorage保存

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

```
ProfilerController::panelAction
    |
    +-- layout.html.twig
           |
           +-- form.html.twig (panelブロック)
                  |
                  +-- form_tree_entry マクロ (再帰)
                  |      +-- 子フォームのツリーレンダリング
                  |
                  +-- form_tree_details マクロ (再帰)
                         |
                         +-- render_form_errors マクロ
                         +-- render_form_default_data マクロ
                         +-- render_form_submitted_data マクロ
                         +-- render_form_passed_options マクロ
                         +-- render_form_resolved_options マクロ
                         +-- render_form_view_variables マクロ
```

### データフロー図

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

FormInterface
    |
    +---> FormDataCollector
             (イベントリスナー経由)
             |
             +---> data.forms ---------> フォームツリー（左ペイン）
             |     data.forms_by_hash     フォーム詳細（右ペイン）
             |     data.nb_errors
             |
             +---> profiler_dump() ----> VarDumper表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| form.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig` | テンプレート | フォームパネルのTwigテンプレート |
| FormDataCollector.php | `src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php` | ソース | フォームデータの収集（イベントリスナー経由） |
| FormDataExtractorInterface.php | `src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractorInterface.php` | ソース | フォームデータ抽出のインターフェース |
| layout.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig` | テンプレート | プロファイラーレイアウトテンプレート |
| toolbar_item.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_item.html.twig` | テンプレート | ツールバーアイテムテンプレート |
