# 帳票設計書 10-Qt TS翻訳ファイル

## 概要

Symfonyの翻訳コンポーネントにおけるQt Linguist TS（Translation Source）形式の翻訳ファイル出力機能の設計書である。メッセージカタログをQt Linguist互換のTS形式XMLファイルとして出力する。

### 本帳票の処理概要

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

**業務上の目的・背景**：Qt Linguist TS形式は、Qtフレームワークの翻訳管理ツール（Qt Linguist）で使用されるXMLベースの翻訳ファイルフォーマットである。Qtアプリケーションとの翻訳データ共有が必要な場合や、Qt Linguistの翻訳エディタ機能を活用したい場合に使用される。ソース位置情報（ファイル名:行番号）のメタデータにも対応しており、翻訳者が原文の使用箇所を確認しながら翻訳作業を行える。

**帳票の利用シーン**：Qtアプリケーションとの翻訳データ共有時、Qt Linguistツールでの翻訳編集時、C++/Qt開発チームとPHP/Symfony開発チーム間での翻訳リソース共有時に利用される。

**主要な出力内容**：
1. TS形式のXMLドキュメント（context要素にname/message要素を含む）
2. 各messageにsource/translation要素のペア
3. ソース位置情報（location要素、filename/line属性）のメタデータ

**帳票の出力タイミング**：プログラム内から`QtFileDumper::dump()`メソッドを呼び出した時に出力される。

**帳票の利用者**：アプリケーション開発者、Qt開発者、翻訳者（Qt Linguist利用者）

## 帳票種別

翻訳データファイル（Qt Linguist TS XML）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | プログラムAPI | `QtFileDumper::dump()` | メソッド呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | XML（Qt Linguist TS形式） |
| 用紙サイズ | N/A（データファイル） |
| 向き | N/A |
| ファイル名 | `%domain%.%locale%.ts`（デフォルト） |
| 出力方法 | ファイルシステムへの書き込み（file_put_contents） |
| 文字コード | UTF-8 |

### Qt TS固有設定

| 項目 | 内容 |
|-----|------|
| ルート要素 | `<TS>` |
| コンテキスト名 | ドメイン名が`<name>`要素として出力 |
| ソース位置 | metadata['sources']からファイル名:行番号を抽出してlocation要素に設定 |

## 帳票レイアウト

### レイアウト概要

Qt TS形式のXML構造で出力される。

```
┌─────────────────────────────────────┐
│ <?xml version="1.0" encoding="utf-8"?>│
│ <TS>                                 │
│   <context>                          │
│     <name>domain</name>              │
│     <message>                        │
│       <location filename="..." line="..."/>│
│       <source>原文</source>           │
│       <translation>訳文</translation> │
│     </message>                       │
│     ...                              │
│   </context>                         │
│ </TS>                                │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | XML宣言 | XML宣言 | DOMDocument | `<?xml version="1.0" encoding="utf-8"?>` |
| 2 | context/name | コンテキスト名（ドメイン名） | formatCatalogue()のdomain引数 | `<name>domain</name>` |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | location | ソース位置情報 | metadata['sources'] | `<location filename="..." line="..."/>` | N/A |
| 2 | source | 原文 | MessageCatalogue::all($domain)のキー | `<source>text</source>` | N/A |
| 3 | translation | 訳文 | MessageCatalogue::all($domain)の値 | `<translation>text</translation>` | N/A |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| N/A | なし | XML閉じタグで終了 | - | `</context></TS>` |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| path | 出力先ディレクトリパス | Yes |

### ソート順

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

### 改ページ条件

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

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

### 参照テーブル一覧

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

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

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

| 参照項目（プロパティ） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| messages[$domain] | source/translation | all($domain) | ドメイン別メッセージ配列 |
| metadata[$domain][$source]['sources'] | location要素 | getMetadata($source, $domain) | ソース位置情報（"filename:line"形式） |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| location分割 | `explode(':', $location, 2)` | N/A | コロン区切りでファイル名と行番号を分離（最大2分割） |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[dump呼び出し] --> B{pathオプション存在?}
    B -->|No| C[InvalidArgumentException]
    B -->|Yes| D[ドメインループ開始]
    D --> E[formatCatalogue呼び出し]
    E --> F[DOMDocument生成]
    F --> G[TS/context/name要素生成]
    G --> H[メッセージループ]
    H --> I[message要素生成]
    I --> J{metadata sources存在?}
    J -->|Yes| K[location要素生成]
    J -->|No| L[source要素生成]
    K --> L
    L --> M[translation要素生成]
    M --> H
    H -->|ループ完了| N[saveXML]
    N --> O[file_put_contentsで書き込み]
    O --> D
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| InvalidArgumentException | pathオプションが未指定 | "The file dumper needs a path option." | pathオプションを指定する |
| RuntimeException | 出力先ディレクトリの作成失敗 | 'Unable to create directory "%s".' | ディレクトリの書き込み権限を確認する |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数百〜数千メッセージ/ドメイン |
| 目標出力時間 | 特に規定なし（DOMDocument使用のため大量データ時はメモリに注意） |
| 同時出力数上限 | 特に規定なし |

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

- DOMDocumentを使用しておりXMLエスケープは自動的に行われる
- 出力先ディレクトリのパーミッションは0o777で作成される（umaskにより制限される）

## 備考

- TS形式はXLIFF形式と同様にXMLベースだが、Qt Linguistツール固有のスキーマに準拠している
- 1つのファイルに1つのcontext（ドメイン）が出力される
- metadata['sources']が存在する場合のみlocation要素が出力される。各sourcesエントリは"filename:line"形式の文字列
- メタデータは出力に含まれない（sourcesのみ）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MessageCatalogue.php | `src/Symfony/Component/Translation/MessageCatalogue.php` | all($domain)とgetMetadata($source, $domain)の戻り値を確認 |

**読解のコツ**: QtFileDumperはメタデータのうちsourcesフィールドのみを使用する。sources配列の各要素は"filename:line"形式の文字列であり、explode(':', $location, 2)で分割される。

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

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | QtFileDumper.php | `src/Symfony/Component/Translation/Dumper/QtFileDumper.php` | formatCatalogue()のDOMDocument構築処理を理解する |

**主要処理フロー**:
- **25-26行目**: DOMDocument生成（UTF-8、formatOutput有効）
- **27-29行目**: TS/context/name要素の構築
- **31-46行目**: メッセージループ
- **32行目**: message要素の作成
- **33行目**: メタデータ取得
- **34-43行目**: metadata['sources']が存在する場合のlocation要素構築（filename/line属性）
- **36行目**: explode(':', $location, 2)でファイル名と行番号を分離
- **44行目**: source要素の作成
- **45行目**: translation要素の作成
- **48行目**: saveXML()でXML文字列化

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

```
DumperInterface::dump()
    │
    └─ FileDumper::dump()                          [FileDumper.php:41]
           │
           ├─ MessageCatalogue::getDomains()        [MessageCatalogue.php:42]
           ├─ FileDumper::getRelativePath()          [FileDumper.php:93]
           │      └─ QtFileDumper::getExtension()    [QtFileDumper.php:51]
           └─ QtFileDumper::formatCatalogue()        [QtFileDumper.php:23]
                  │
                  ├─ MessageCatalogue::all($domain)   [MessageCatalogue.php:56]
                  └─ MessageCatalogue::getMetadata()   [MessageCatalogue.php:214]
```

### データフロー図

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

MessageCatalogue ───────▶ FileDumper::dump()
  ├─ messages[domain]           │
  └─ metadata[domain]           ├─ ドメインループ
     └─ sources                 │     │
                                │     ├─ formatCatalogue()
                options ────────▶     │     │
                  └─ path              │     ├─ DOMDocument構築
                                      │     ├─ context/name生成
                                      │     ├─ message/location生成 ▶ {domain}.{locale}.ts
                                      │     ├─ source/translation     （Qt TS XML）
                                      │     └─ saveXML()
                                      │
                                      └─ file_put_contents()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DumperInterface.php | `src/Symfony/Component/Translation/Dumper/DumperInterface.php` | ソース | Dumperインターフェース定義 |
| FileDumper.php | `src/Symfony/Component/Translation/Dumper/FileDumper.php` | ソース | ファイル出力共通基底クラス |
| QtFileDumper.php | `src/Symfony/Component/Translation/Dumper/QtFileDumper.php` | ソース | Qt TS形式固有のフォーマット処理 |
| MessageCatalogue.php | `src/Symfony/Component/Translation/MessageCatalogue.php` | ソース | メッセージカタログデータ構造 |
| MessageCatalogueInterface.php | `src/Symfony/Component/Translation/MessageCatalogueInterface.php` | ソース | メッセージカタログインターフェース |
