# 帳票設計書 5-YAML翻訳ファイル

## 概要

Symfonyの翻訳コンポーネントにおけるYAML形式の翻訳ファイル出力機能の設計書である。メッセージカタログをYAML形式のテキストファイルとして出力する。

### 本帳票の処理概要

本帳票は、Symfonyアプリケーション内部のメッセージカタログ（MessageCatalogue）に格納された翻訳メッセージを、YAML形式のテキストファイルとして出力する機能を提供する。

**業務上の目的・背景**：YAML（YAML Ain't Markup Language）はSymfonyで最も一般的に使用される設定・翻訳ファイル形式である。人間が読み書きしやすいフォーマットであり、Symfonyプロジェクトの標準的な翻訳リソース形式として広く採用されている。本帳票により、プログラムで管理する翻訳データをYAMLファイルとしてエクスポートし、手動編集やバージョン管理が容易な形式で保存できる。

**帳票の利用シーン**：Symfonyプロジェクトの標準翻訳ファイル生成時、翻訳データのバージョン管理用エクスポート時、開発者が直接編集可能な翻訳ファイルの出力時、ツリー構造への変換によるキーの階層化が必要な場合に利用される。

**主要な出力内容**：
1. フラットなkey: value形式のYAML出力（デフォルト）
2. ツリー構造のYAML出力（as_treeオプション有効時、ドット区切りキーを階層展開）
3. インラインレベルの制御（inlineオプション）

**帳票の出力タイミング**：`translation:update`コマンド実行時（format指定）、またはプログラム内から`YamlFileDumper::dump()`メソッドを呼び出した時に出力される。

**帳票の利用者**：アプリケーション開発者、翻訳者、DevOpsエンジニア

## 帳票種別

翻訳データファイル（YAMLテキスト）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | CLIコマンド | `php bin/console translation:update` | コマンド実行（--output-format=yml） |
| N/A | プログラムAPI | `YamlFileDumper::dump()` | メソッド呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | YAML |
| 用紙サイズ | N/A（データファイル） |
| 向き | N/A |
| ファイル名 | `%domain%.%locale%.yml`（デフォルト、コンストラクタで拡張子変更可能） |
| 出力方法 | ファイルシステムへの書き込み（file_put_contents） |
| 文字コード | UTF-8 |

### YAML固有設定

| 項目 | 内容 |
|-----|------|
| as_tree | trueの場合、ドット区切りキーを階層構造に展開（ArrayConverter::expandToTree()） |
| inline | YAMLのインラインレベル（Yaml::dump()の第2引数） |
| Yamlコンポーネント依存 | symfony/yamlが必要（存在しない場合LogicException） |

## 帳票レイアウト

### レイアウト概要

フラット形式（デフォルト）の場合:

```
┌─────────────────────────────────────┐
│ 'key1': value1                       │
│ 'key2': value2                       │
│ 'foo.bar': value3                    │
│ ...                                  │
└─────────────────────────────────────┘
```

ツリー形式（as_tree=true）の場合:

```
┌─────────────────────────────────────┐
│ key1: value1                         │
│ key2: value2                         │
│ foo:                                 │
│   bar: value3                        │
│ ...                                  │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| N/A | なし | YAMLファイルにヘッダー部は存在しない | - | - |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | key | 翻訳キー | MessageCatalogue::all($domain)のキー | YAML key | 可変 |
| 2 | value | 翻訳値 | MessageCatalogue::all($domain)の値 | YAML value | 可変 |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| N/A | なし | YAMLファイルにフッターは存在しない | - | - |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| path | 出力先ディレクトリパス | Yes |
| as_tree | ツリー構造で出力するか（デフォルト: false） | No |
| inline | YAMLインラインレベル（正の整数） | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | メッセージカタログの格納順 | 格納順（挿入順） |

### 改ページ条件

N/A（データファイルのため改ページなし）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| N/A | 本帳票はデータベースを直接参照しない | - |

### テーブル別参照項目詳細

#### MessageCatalogue（入力データ構造）

| 参照項目（プロパティ） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| messages[$domain] | key: value | all($domain) | ドメイン別メッセージ配列 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| ツリー展開 | ArrayConverter::expandToTree($data) | N/A | ドット区切りキーを再帰的にネスト配列に変換（as_tree有効時のみ） |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[dump呼び出し] --> B{pathオプション存在?}
    B -->|No| C[InvalidArgumentException]
    B -->|Yes| D[ドメインループ開始]
    D --> E[formatCatalogue呼び出し]
    E --> F{Yaml::classが存在?}
    F -->|No| G[LogicException]
    F -->|Yes| H[all domain でデータ取得]
    H --> I{as_treeオプション?}
    I -->|Yes| J[ArrayConverter::expandToTree]
    I -->|No| K{inlineオプション?}
    J --> K
    K -->|Yes| L[Yaml::dump data, inline]
    K -->|No| M[Yaml::dump data]
    L --> N[file_put_contentsで書き込み]
    M --> N
    N --> D
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| InvalidArgumentException | pathオプションが未指定 | "The file dumper needs a path option." | pathオプションを指定する |
| LogicException | Symfony Yamlコンポーネントが未インストール | "Dumping translations in the YAML format requires the Symfony Yaml component." | `composer require symfony/yaml`でインストール |
| RuntimeException | 出力先ディレクトリの作成失敗 | 'Unable to create directory "%s".' | ディレクトリの書き込み権限を確認する |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数百〜数千メッセージ/ドメイン |
| 目標出力時間 | 特に規定なし |
| 同時出力数上限 | 特に規定なし |

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

- Symfony Yamlコンポーネントが適切なYAMLエスケープを行う
- 出力先ディレクトリのパーミッションは0o777で作成される（umaskにより制限される）

## 備考

- コンストラクタでファイル拡張子をカスタマイズ可能（デフォルト: "yml"）。"yaml"等に変更することも可能
- as_treeオプションを使用すると、`foo.bar.baz: value`のようなドット区切りキーを`foo: { bar: { baz: value }}`のようなツリー構造に変換して出力する
- Symfony Yamlコンポーネント（`symfony/yaml`）が必要。未インストール時はLogicExceptionが発生する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MessageCatalogue.php | `src/Symfony/Component/Translation/MessageCatalogue.php` | all($domain)の戻り値（key-value配列）を確認 |
| 1-2 | ArrayConverter.php | `src/Symfony/Component/Translation/Util/ArrayConverter.php` | expandToTree()メソッド（34-47行目）でドット区切りキーをツリー構造に変換する処理を理解する |

**読解のコツ**: ArrayConverterは`foo.bar`のようなドット区切りキーを`['foo' => ['bar' => ...]]`に変換する。同一プレフィックスの衝突（`foo: value`と`foo.bar: value`が共存する場合）の処理が複雑であるため、getElementByPath()とcancelExpand()の挙動に注意。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | FileDumper.php | `src/Symfony/Component/Translation/Dumper/FileDumper.php` | dump()メソッドの共通処理フロー（41-77行目） |

#### Step 3: YAML固有のフォーマット処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | YamlFileDumper.php | `src/Symfony/Component/Translation/Dumper/YamlFileDumper.php` | formatCatalogue()でのオプション処理とYaml::dump()呼び出しを理解する |

**主要処理フロー**:
- **26-29行目**: コンストラクタ（拡張子カスタマイズ）
- **33-35行目**: Yamlクラス存在チェック
- **37行目**: all($domain)でメッセージ取得
- **39-41行目**: as_treeオプション処理（ArrayConverter::expandToTree()呼び出し）
- **43-44行目**: inlineオプション処理
- **47行目**: Yaml::dump()によるYAML文字列生成

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

```
DumperInterface::dump()
    │
    └─ FileDumper::dump()                          [FileDumper.php:41]
           │
           ├─ MessageCatalogue::getDomains()        [MessageCatalogue.php:42]
           ├─ FileDumper::getRelativePath()          [FileDumper.php:93]
           │      └─ YamlFileDumper::getExtension()  [YamlFileDumper.php:50]
           └─ YamlFileDumper::formatCatalogue()      [YamlFileDumper.php:31]
                  │
                  ├─ MessageCatalogue::all($domain)   [MessageCatalogue.php:56]
                  ├─ ArrayConverter::expandToTree()    [ArrayConverter.php:34]（as_tree時）
                  └─ Yaml::dump()                     [Yaml component]
```

### データフロー図

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

MessageCatalogue ───────▶ FileDumper::dump()
  └─ messages[domain]           │
                                ├─ ドメインループ
                options ────────▶     │
                  ├─ path              ├─ formatCatalogue()
                  ├─ as_tree           │     │
                  └─ inline            │     ├─ データ取得
                                      │     ├─ ツリー変換（任意） ──▶ {domain}.{locale}.yml
                                      │     └─ Yaml::dump()          （YAML文書）
                                      │
                                      └─ file_put_contents()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DumperInterface.php | `src/Symfony/Component/Translation/Dumper/DumperInterface.php` | ソース | Dumperインターフェース定義 |
| FileDumper.php | `src/Symfony/Component/Translation/Dumper/FileDumper.php` | ソース | ファイル出力共通基底クラス |
| YamlFileDumper.php | `src/Symfony/Component/Translation/Dumper/YamlFileDumper.php` | ソース | YAML形式固有のフォーマット処理 |
| ArrayConverter.php | `src/Symfony/Component/Translation/Util/ArrayConverter.php` | ソース | ドット区切りキーからツリー構造への変換ユーティリティ |
| MessageCatalogue.php | `src/Symfony/Component/Translation/MessageCatalogue.php` | ソース | メッセージカタログデータ構造 |
| MessageCatalogueInterface.php | `src/Symfony/Component/Translation/MessageCatalogueInterface.php` | ソース | メッセージカタログインターフェース |
