# 機能設計書 36-ビューファクトリ

## 概要

本ドキュメントは、Laravel Frameworkにおけるビューファクトリ（View Factory）機能の設計書である。Bladeテンプレートやプレーンなビューファイルをレンダリングするための中核コンポーネントであり、ビューの作成、データバインディング、コンポーザー/クリエーターの管理を担当する。

### 本機能の処理概要

**業務上の目的・背景**：
WebアプリケーションのUIは、HTMLテンプレートとアプリケーションデータを組み合わせて生成される。ビューファクトリは、テンプレートエンジンの抽象化レイヤーを提供し、ビューの検索、データの注入、レンダリングを統一的に管理する。これにより、コントローラとビューの関心を分離し、テンプレートの再利用性と保守性を向上させる。

**機能の利用シーン**：
- コントローラからのビューレスポンス返却
- メールテンプレートのレンダリング
- PDFテンプレートの生成
- コンポーネントベースのUI構築
- レイアウトとセクションの組み合わせ

**主要な処理内容**：
1. ビュー作成（`make`, `file`, `first`メソッドによるビューインスタンス生成）
2. 条件付きレンダリング（`renderWhen`, `renderUnless`メソッド）
3. ループレンダリング（`renderEach`メソッド）
4. 共有データ管理（`share`メソッドによるグローバルデータ設定）
5. ビューコンポーザー/クリエーター（`composer`, `creator`メソッド）
6. 名前空間管理（`addNamespace`, `prependNamespace`メソッド）
7. 拡張子とエンジンのマッピング（`addExtension`メソッド）
8. レイアウト・セクション・スタック管理

**関連システム・外部連携**：
- BladeCompiler: Bladeテンプレートのコンパイル
- EngineResolver: ファイル拡張子に基づくエンジン解決
- ViewFinder: ビューファイルの検索
- EventDispatcher: ビューイベントの発火

**権限による制御**：
本機能自体は権限制御を行わない。ビュー内で`@can`等のディレクティブを使用して認可を実装する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 全画面 | 主処理 | 全てのHTMLレンダリングで使用 |

## 機能種別

テンプレート処理 / UI生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| view | string | Yes | ビュー名（ドット記法対応） | 存在するビュー |
| data | array\|Arrayable | No | ビューに渡すデータ | - |
| mergeData | array | No | 既存データとマージするデータ | - |

### 入力データソース

- コントローラからの呼び出し
- メール送信システムからの呼び出し
- Bladeコンポーネントからの呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| view | View | ビューインスタンス |
| rendered | string | レンダリングされたHTML |

### 出力先

- HTTPレスポンス（Response）
- メール本文
- 文字列として取得

## 処理フロー

### 処理シーケンス

```
1. ビュー作成（make呼び出し）
   └─ ビュー名とデータを受け取る
   └─ ビュー名を正規化（ドット→スラッシュ変換）
   └─ ViewFinderでファイルパスを解決

2. ビューインスタンス作成
   └─ パスに基づきエンジンを決定
   └─ Viewインスタンスを生成
   └─ クリエーターを呼び出し

3. レンダリング（render呼び出し）
   └─ コンポーザーを呼び出し
   └─ 共有データとビューデータをマージ
   └─ エンジンでテンプレートを評価
   └─ レンダリング結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[Factory::make呼び出し] --> B[ビュー名正規化]
    B --> C[ViewFinder::find]
    C --> D{ファイル存在?}
    D -->|No| E[InvalidArgumentException]
    D -->|Yes| F[getEngineFromPath]
    F --> G[Viewインスタンス作成]
    G --> H[callCreator]
    H --> I[Viewインスタンス返却]

    J[View::render呼び出し] --> K[callComposer]
    K --> L[共有データマージ]
    L --> M[Engine::get]
    M --> N[テンプレート評価]
    N --> O[HTML文字列返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-36-01 | ビュー名正規化 | ドット記法をディレクトリ区切りに変換 | ビュー名指定時 |
| BR-36-02 | 拡張子優先順位 | blade.php → php → css → html の順で検索 | ファイル検索時 |
| BR-36-03 | クリエーター実行 | ビュー作成時に登録済みクリエーターを実行 | ビュー作成時 |
| BR-36-04 | コンポーザー実行 | レンダリング時に登録済みコンポーザーを実行 | render時 |
| BR-36-05 | 共有データ | `share`で登録したデータは全ビューで利用可能 | 常時 |

### 計算ロジック

該当なし

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvalidArgumentException | ビューファイルが見つからない | ビュー名とパスを確認 |
| - | InvalidArgumentException | 認識できない拡張子 | addExtensionで登録 |
| - | ViewException | テンプレート内のエラー | テンプレートを修正 |

### リトライ仕様

本機能にリトライ機能は含まれない。

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

該当なし

## パフォーマンス要件

- ビュー名の正規化結果はキャッシュ（`$normalizedNameCache`）
- パスからエンジンへのマッピングはキャッシュ（`$pathEngineCache`）
- Bladeテンプレートはコンパイル結果をファイルキャッシュ
- コンポーネントの状態は`flushState`でリセット可能

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

- Bladeの`{{ }}`構文は自動的にHTMLエスケープ
- `{!! !!}`は生出力のため信頼できないデータには使用しない
- ビュー内でのユーザー入力はサニタイズを徹底

## 備考

- Macroableトレイトにより、カスタムメソッドを追加可能
- `__env`変数としてFactoryインスタンスがビューで利用可能
- Componentクラスのキャッシュはリクエスト終了時にフラッシュ

---

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

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

### 推奨読解順序

#### Step 1: インターフェースを理解する

まず、Factoryの契約を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Factory.php | `src/Illuminate/Contracts/View/Factory.php` | ビューファクトリの契約 |

#### Step 2: Factoryクラスを理解する

中核クラスの全体構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Factory.php | `src/Illuminate/View/Factory.php` | ビューファクトリの主実装 |

**主要処理フロー**:
- **114-121行目**: コンストラクタ - EngineResolver, ViewFinder, Dispatcherを保持
- **131-138行目**: `file()` - ファイルパスから直接ビュー作成
- **148-162行目**: `make()` - ビュー名からビュー作成のメインメソッド
- **174-185行目**: `first()` - 複数候補から最初に存在するビューを使用
- **196-203行目**: `renderWhen()` - 条件付きレンダリング
- **228-253行目**: `renderEach()` - ループレンダリング
- **261-264行目**: `normalizeName()` - ビュー名の正規化とキャッシュ
- **285-288行目**: `viewInstance()` - Viewインスタンス生成
- **296-305行目**: `exists()` - ビュー存在確認
- **315-328行目**: `getEngineFromPath()` - パスからエンジン解決
- **352-361行目**: `share()` - グローバルデータ共有
- **487-500行目**: `addExtension()` - 拡張子とエンジンのマッピング追加
- **507-516行目**: `flushState()` - 状態リセット

**読解のコツ**: FactoryはConcernsトレイトで機能を分割している。ManagesComponents, ManagesLayouts, ManagesStacks等を参照すると、Bladeの各機能の実装が理解できる。

#### Step 3: Viewクラスを理解する

実際のレンダリングを行うクラスを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | View.php | `src/Illuminate/View/View.php` | ビューインスタンスの実装 |

**読解のコツ**: `render()`メソッドがエントリーポイント。内部で`renderContents()`を呼び、エンジンの`get()`でテンプレートを評価する。

#### Step 4: サービスプロバイダーを理解する

コンテナ登録を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ViewServiceProvider.php | `src/Illuminate/View/ViewServiceProvider.php` | サービス登録 |

**主要処理フロー**:
- **20-30行目**: `register()` - 各コンポーネントの登録順序
- **37-62行目**: `registerFactory()` - Factoryのシングルトン登録
- **82-87行目**: `registerViewFinder()` - ViewFinderの登録
- **94-108行目**: `registerBladeCompiler()` - BladeCompilerの登録
- **115-129行目**: `registerEngineResolver()` - エンジンリゾルバの登録

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

```
view('users.index', ['users' => $users])
    │
    └─ Factory::make('users.index', ['users' => $users])
           │
           ├─ normalizeName('users.index') ... キャッシュ確認
           │
           ├─ finder->find('users.index')
           │      └─ FileViewFinder::find()
           │             └─ resources/views/users/index.blade.php
           │
           ├─ getEngineFromPath($path)
           │      └─ EngineResolver::resolve('blade')
           │             └─ CompilerEngine
           │
           ├─ viewInstance() ... Viewインスタンス作成
           │      └─ new View($factory, $engine, $view, $path, $data)
           │
           └─ callCreator($view)
                  └─ イベント: 'creating: users.index'

View::render()
    │
    ├─ callComposer($view)
    │      └─ イベント: 'composing: users.index'
    │
    └─ renderContents()
           │
           └─ engine->get($path, $data)
                  │
                  └─ CompilerEngine::get()
                         ├─ compiler->compile() ... 必要時のみ
                         └─ evalPath() ... コンパイル済みPHP実行
```

### データフロー図

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

ビュー名 + データ ─────────▶ Factory::make()
                               │
                         ビュー名正規化
                               │
                         ViewFinder検索
                               │
                         エンジン解決
                               │
                         Viewインスタンス作成
                               │
                         クリエーター呼び出し
                               │
                    View::render() ◀─────────────────────▶ HTML文字列
                               │
                         コンポーザー呼び出し
                               │
                         共有データマージ
                               │
                         Engine::get()
                               │
                         テンプレート評価
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Factory.php | `src/Illuminate/View/Factory.php` | ソース | ビューファクトリ主実装 |
| View.php | `src/Illuminate/View/View.php` | ソース | ビューインスタンス |
| ViewServiceProvider.php | `src/Illuminate/View/ViewServiceProvider.php` | ソース | サービス登録 |
| Factory.php | `src/Illuminate/Contracts/View/Factory.php` | インターフェース | ファクトリ契約 |
| ManagesComponents.php | `src/Illuminate/View/Concerns/ManagesComponents.php` | ソース | コンポーネント管理 |
| ManagesLayouts.php | `src/Illuminate/View/Concerns/ManagesLayouts.php` | ソース | レイアウト管理 |
| ManagesStacks.php | `src/Illuminate/View/Concerns/ManagesStacks.php` | ソース | スタック管理 |
| ManagesEvents.php | `src/Illuminate/View/Concerns/ManagesEvents.php` | ソース | イベント管理 |
| ViewName.php | `src/Illuminate/View/ViewName.php` | ソース | ビュー名正規化 |
