# 機能設計書 60-ヘッダー表示

## 概要

本ドキュメントは、Shopware Storefrontにおける「ヘッダー表示」機能の設計仕様を定義する。ショップの共通ヘッダー領域（ロゴ、ナビゲーションメニュー、言語・通貨セレクター、カート・アカウントアイコン等）をレンダリングする機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：ECサイトのヘッダーは、全ページで共通して表示される重要なUI要素であり、ブランドロゴの表示、主要カテゴリへのナビゲーション、言語・通貨の切り替え、ログイン状態の表示、カートへのアクセス等、多くの機能を統合している。ESI（Edge Side Includes）対応により、ヘッダーは別途キャッシュ可能で、パフォーマンス最適化に貢献する。

**機能の利用シーン**：全ページの表示時にヘッダー領域をレンダリングするために呼び出される。ESI対応のため、CDNやリバースプロキシによってキャッシュされ、ページ本体とは独立してキャッシュ管理される。

**主要な処理内容**：
1. メインナビゲーション（カテゴリツリー）の取得
2. 利用可能な言語一覧の取得
3. 利用可能な通貨一覧の取得
4. ページレットオブジェクトの構築
5. イベント発火による拡張ポイント提供
6. ヘッダーテンプレートをレンダリング

**関連システム・外部連携**：本機能は Store API の `LanguageRoute`、`CurrencyRoute`、および`NavigationLoader`を利用してヘッダーに必要なデータを取得する。`HeaderPageletLoadedEvent`イベントを発火し、プラグインによる拡張を可能にする。

**権限による制御**：本機能はログイン不要で利用可能。HTTPキャッシュが有効で、ESI対応により個別にキャッシュされる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | ホームページ | 参照画面 | 共通ヘッダーの表示 |
| 全画面 | 全ページ共通 | 主画面 | ヘッダー領域として表示 |

## 機能種別

ページレット表示 / ナビゲーション / ESI対応

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| headerParameters | array | No | 追加パラメータ（クエリパラメータ経由） | - |

### 入力データソース

- SalesChannelContext: 販売チャネル情報、言語ID、通貨情報を含む

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| header | HeaderPagelet | ヘッダーページレット（ナビゲーション、言語、通貨情報含む） |
| headerParameters | array | 追加パラメータ |

### 出力先

- HTTPレスポンス: Twigテンプレートによるヘッダー表示
- ESI対応で個別キャッシュ可能

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ NavigationController::header が呼び出される

2. ナビゲーション取得
   └─ NavigationLoaderでメインナビゲーションツリーを取得
   └─ 販売チャネルのナビゲーションカテゴリから指定深度まで

3. 言語一覧取得
   └─ LanguageRouteで利用可能な言語を取得
   └─ 販売チャネルのドメインに紐付く言語のみ

4. 通貨一覧取得
   └─ CurrencyRouteで利用可能な通貨を取得

5. ページレット作成
   └─ HeaderPageletを作成
   └─ ナビゲーション、言語、通貨を設定

6. イベント発火
   └─ HeaderPageletLoadedEvent をディスパッチ

7. レスポンス返却
   └─ header.html.twig でレンダリング
```

### フローチャート

```mermaid
flowchart TD
    A[開始: header呼び出し] --> B[NavigationLoader::load]
    B --> C[メインナビゲーション取得]
    C --> D[LanguageRoute::load]
    D --> E[利用可能な言語取得]
    E --> F[CurrencyRoute::load]
    F --> G[利用可能な通貨取得]
    G --> H[HeaderPagelet作成]
    H --> I[HeaderPageletLoadedEvent発火]
    I --> J[header.html.twigレンダリング]
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-60-01 | ログイン不要 | ログインなしでアクセス可能 | 全リクエスト |
| BR-60-02 | HTTPキャッシュ有効 | HTTPキャッシュ属性が設定される | 全リクエスト |
| BR-60-03 | ESI対応 | Edge Side Includesでページ本体と別キャッシュ | 全リクエスト |
| BR-60-04 | XmlHttpRequest | Ajax呼び出し用エンドポイント | 全リクエスト |
| BR-60-05 | ナビゲーション深度 | 販売チャネル設定のnavigationCategoryDepthを使用 | ナビゲーション取得時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| カテゴリ取得 | category | SELECT | ナビゲーションカテゴリツリーを取得 |
| 言語取得 | language | SELECT | 利用可能な言語一覧を取得 |
| 通貨取得 | currency | SELECT | 利用可能な通貨一覧を取得 |
| ドメイン取得 | sales_channel_domain | SELECT | 言語に紐付くドメインを取得 |

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

#### category

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, parent_id, active, visible | ナビゲーションカテゴリ配下、深度制限 | ナビゲーションツリー取得 |

#### language

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name | salesChannelDomains.salesChannelId = ? | ドメインに紐付く言語のみ |

#### currency

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, isoCode, symbol | 販売チャネルで利用可能な通貨 | 通貨一覧取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| LANGUAGE_NOT_FOUND | 言語未存在 | コンテキストの言語が見つからない | 販売チャネル設定を確認 |

### リトライ仕様

特になし

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

- 読み取り専用のため、トランザクション管理は不要
- SELECTクエリのみ実行

## パフォーマンス要件

- レスポンス時間: 200ms以内（キャッシュヒット時は50ms以内）
- ESI対応によりCDNキャッシュ可能

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

- HTTPキャッシュが有効のため、ユーザー固有情報は含めない
- 言語・通貨セレクターはフォーム送信で変更（CSRF対策あり）

## 備考

- ESI: `/_esi/global/header` エンドポイントでCDN/プロキシが個別にキャッシュ
- v6.8.0.0でactiveLanguage/activeCurrencyのプロパティは非推奨
- ヘッダー内のカート情報は別のウィジェット（CheckoutController::info）で提供

---

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

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

### 推奨読解順序

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

まず、ヘッダーページレットのデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | HeaderPagelet.php | `src/Storefront/Pagelet/Header/HeaderPagelet.php` | ページレット構造。navigation（Tree）、languages（LanguageCollection）、currencies（CurrencyCollection）プロパティを確認 |

**読解のコツ**: HeaderPageletは全ページ共通で使用される。ESIにより個別キャッシュされるため、ユーザー固有情報は含めない設計。

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

処理の起点となるコントローラーを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | NavigationController.php | `src/Storefront/Controller/NavigationController.php` | Storefront側のエントリーポイント。headerメソッドがヘッダー表示の入口 |

**主要処理フロー**:
1. **120-129行目**: headerメソッドのルート定義。GET `/_esi/global/header`、XmlHttpRequest、HTTPキャッシュ有効、ESI有効
2. **130-140行目**: headerメソッドの実装
3. **132行目**: HeaderPageletLoaderでページレットをロード
4. **134行目**: HeaderPageletLoadedHookを発火
5. **136-139行目**: Twigテンプレートでレンダリング、headerParametersを渡す

#### Step 3: ページレットローダーを理解する

実際のビジネスロジックはページレットローダーに実装されている。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | HeaderPageletLoader.php | `src/Storefront/Pagelet/Header/HeaderPageletLoader.php` | ページレット生成のロジック |

**主要処理フロー**:
- **43-76行目**: loadメソッドの実装
- **45行目**: 販売チャネル取得
- **47-52行目**: NavigationLoaderでメインナビゲーションを取得
- **53行目**: getLanguagesで言語一覧取得
- **55-59行目**: HeaderPageletを作成
- **61-71行目**: Feature flagでactiveLanguage/activeCurrency設定（非推奨）
- **73行目**: イベント発火

#### Step 4: 言語・通貨取得を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | HeaderPageletLoader.php | `src/Storefront/Pagelet/Header/HeaderPageletLoader.php` | getLanguages、getCurrenciesメソッド |

**主要処理フロー**:
- **78-92行目**: getLanguagesメソッド
  - **80-81行目**: Criteriaを作成、タイトル設定
  - **83-85行目**: ドメインに紐付く言語のみフィルタ
  - **86行目**: 名前でソート
  - **88-89行目**: イベント発火
  - **91行目**: LanguageRouteで取得
- **94-103行目**: getCurrenciesメソッド
  - **96-97行目**: Criteriaを作成、タイトル設定
  - **99-100行目**: イベント発火
  - **102行目**: CurrencyRouteで取得

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

```
NavigationController::header (Storefront)
    │
    └─ HeaderPageletLoader::load
           │
           ├─ NavigationLoader::load
           │      └─ メインナビゲーションツリー取得
           │
           ├─ getLanguages
           │      ├─ LanguageRouteRequestEvent発火
           │      └─ LanguageRoute::load
           │
           ├─ getCurrencies
           │      ├─ CurrencyRouteRequestEvent発火
           │      └─ CurrencyRoute::load
           │
           └─ EventDispatcher::dispatch
                  └─ HeaderPageletLoadedEvent
```

### データフロー図

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

Request ───────────────▶ NavigationController::header
                              │
SalesChannelContext ───────▶ │
                              ▼
                         HeaderPageletLoader::load
                              │
                              ├─▶ category テーブル (SELECT - ナビゲーション)
                              │
                              ├─▶ language テーブル (SELECT - 言語一覧)
                              │
                              └─▶ currency テーブル (SELECT - 通貨一覧)
                                          │
                                          ▼
                                   Twigテンプレート ──────▶ ヘッダーHTML (ESI対応)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| NavigationController.php | `src/Storefront/Controller/NavigationController.php` | ソース | Storefrontコントローラー、エントリーポイント |
| HeaderPageletLoader.php | `src/Storefront/Pagelet/Header/HeaderPageletLoader.php` | ソース | ページレットローダー、ビジネスロジック |
| HeaderPagelet.php | `src/Storefront/Pagelet/Header/HeaderPagelet.php` | ソース | ページレットクラス |
| NavigationLoader.php | `src/Core/Content/Category/Service/NavigationLoader.php` | ソース | ナビゲーションツリー生成 |
| LanguageRoute.php | `src/Core/System/Language/SalesChannel/LanguageRoute.php` | ソース | 言語取得ルート |
| CurrencyRoute.php | `src/Core/System/Currency/SalesChannel/CurrencyRoute.php` | ソース | 通貨取得ルート |
| HeaderPageletLoadedEvent.php | `src/Storefront/Pagelet/Header/HeaderPageletLoadedEvent.php` | ソース | イベントクラス |
| header.html.twig | `src/Storefront/Resources/views/storefront/layout/header.html.twig` | テンプレート | ヘッダーテンプレート |
