# 機能設計書 52-Intl

## 概要

本ドキュメントは、Symfony Intlコンポーネントの機能設計を記述する。IntlコンポーネントはICU(International Components for Unicode)ライブラリのローカライゼーションデータへのアクセスを提供し、通貨、言語、地域、スクリプト、タイムゾーン等の国際化データをPHPから利用可能にする。

### 本機能の処理概要

Intlコンポーネントは、PHPの intl 拡張が提供するICUデータへのアクセスを、オブジェクト指向のAPIとして提供する。intl 拡張がインストールされていない環境でもスタブデータを通じて利用可能にする互換レイヤーとしても機能する。

**業務上の目的・背景**：多言語・多地域対応アプリケーションでは、国名、通貨名、言語名をユーザーのロケールに応じた表示名で提供する必要がある。Intlコンポーネントは、ICUが管理する信頼性の高い国際化データをSymfonyフレームワーク内で統一的に利用するための基盤を提供する。

**機能の利用シーン**：国名・地域名のドロップダウンリスト生成、通貨記号・通貨名の表示、言語名のローカライズ表示、タイムゾーン一覧の提供、ISO 3166国コード変換(alpha-2/alpha-3/numeric)、通貨のフラクションデジット取得など。

**主要な処理内容**：
1. 国名・地域コード(ISO 3166 alpha-2/alpha-3/numeric)のデータ提供と変換
2. 通貨データ(通貨コード、通貨名、記号、小数桁数、丸め単位)の提供
3. 言語名データのロケール対応提供
4. スクリプト名データの提供
5. ロケール名データの提供
6. タイムゾーンデータの提供
7. ICUバージョン情報の取得

**関連システム・外部連携**：PHP intl拡張(オプション)、ICUデータリポジトリ(ビルド時にResources/dataディレクトリに格納)。

**権限による制御**：権限制御は実装されていない。全データは読み取り専用で公開される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接関連する画面はないが、フォームのCountryType、CurrencyType、LanguageType、TimezoneType等のフォームタイプのデータソースとして機能する |

## 機能種別

データ参照 / マスタデータ提供

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| displayLocale | string|null | No | 表示名のロケール(nullの場合はデフォルトロケール) | ICUリソースに存在するロケールであること |
| countryCode | string | Yes(各メソッド) | ISO 3166 alpha-2国コード(例: JP, US) | 大文字2文字であること |
| alpha3Code | string | Yes(該当メソッド) | ISO 3166 alpha-3国コード(例: JPN, USA) | 大文字3文字であること |
| currencyCode | string | Yes(該当メソッド) | ISO 4217通貨コード(例: JPY, USD) | 大文字3文字であること |

### 入力データソース

`src/Symfony/Component/Intl/Resources/data/` 配下のPHPデータファイル(ICUデータをPHP配列形式にコンパイルしたもの)。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| countryNames | array<string, string> | alpha-2コードをキーとする国名の連想配列 |
| currencyNames | array<string, string> | 通貨コードをキーとする通貨名の連想配列 |
| languageNames | array<string, string> | 言語コードをキーとする言語名の連想配列 |
| timezoneNames | array<string, string> | タイムゾーンIDをキーとするタイムゾーン名の連想配列 |
| fractionDigits | int | 通貨の小数桁数 |
| currencySymbol | string | 通貨記号(例: $, EUR, JPY) |

### 出力先

呼び出し元のアプリケーションコード(フォームタイプ、テンプレート、サービスクラス等)。

## 処理フロー

### 処理シーケンス

```
1. データアクセスクラスの静的メソッド呼び出し(例: Countries::getNames())
   └─ ResourceBundleの継承クラスとして実装
2. readEntry()でデータファイルからエントリを読み込み
   └─ PHPデータファイル(Resources/data/)をrequireして読み込み
3. ロケールに応じたデータファイルの選択
   └─ displayLocaleが指定された場合はそのロケールのファイル、なければデフォルト
4. データの整形と返却
   └─ 名前一覧の場合はasort()でソートして返却
```

### フローチャート

```mermaid
flowchart TD
    A[Countries::getNames等の呼び出し] --> B[readEntry実行]
    B --> C{displayLocaleの指定?}
    C -->|あり| D[指定ロケールのデータファイル読み込み]
    C -->|なし| E[デフォルトロケールのデータファイル読み込み]
    D --> F[PHPデータファイルをrequire]
    E --> F
    F --> G{データ存在?}
    G -->|Yes| H[データ整形・ソート]
    G -->|No| I[MissingResourceException]
    H --> J[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-01 | ユーザー割当コード | SYMFONY_INTL_WITH_USER_ASSIGNED環境変数がtrueの場合、ユーザー割当コード(例: XK=コソボ)を含める | Countries::withUserAssigned()がtrueの場合 |
| BR-52-02 | ロケール順ソート | 名前一覧はdisplayLocaleに応じたCollatorでソートされる | getNames()系メソッドの返却時 |
| BR-52-03 | ICUバージョン互換 | ICUスタブバージョン(78.1)と互換性のあるデータを提供する | intl拡張未インストール環境 |

### 計算ロジック

通貨の小数桁数(fractionDigits)とcashFractionDigitsは異なる場合がある。現金取引では丸め単位が異なるため(例: CHFの通常fractionDigitsは2、cash rounding incrementは5)。

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

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

本コンポーネントは直接的なデータベース操作を行わない。全データはResources/dataディレクトリのPHPファイルから読み取り専用で提供される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | MissingResourceException | 指定されたコード(国コード、通貨コード等)が存在しない場合 | 有効なコードを指定する、exists()で事前確認 |

### リトライ仕様

リトライ機構は不要。全データはローカルファイルから読み取られる。

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

トランザクション管理は対象外(読み取り専用データ)。

## パフォーマンス要件

- ResourceBundleクラスでバッファサイズ(BUFFER_SIZE = 10)によるデータキャッシュを実装(Intl.php 25行目)
- PHPデータファイルのrequireにより、opcacheが有効な環境では高速にロード可能

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

- 読み取り専用のデータ提供であり、セキュリティリスクは低い
- ユーザー入力をデータキーとして使用する場合は事前バリデーションを推奨

## 備考

ICUデータは定期的に更新される。Symfonyのマイナーバージョンアップ時にICUデータバージョンが更新される場合がある。

---

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

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

### 推奨読解順序

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

まず、ICUデータの格納構造と基底クラスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Intl.php | `src/Symfony/Component/Intl/Intl.php` | 定数定義(BUFFER_SIZE, ディレクトリ名)、データディレクトリパス、ICUバージョン取得 |
| 1-2 | ResourceBundle.php | `src/Symfony/Component/Intl/ResourceBundle.php` | データ読み込みの基底クラス、readEntry()の実装、バッファリング機構 |

**読解のコツ**: Intlクラスは全てstatic構成でインスタンス化不可。getDataDirectory()がResources/dataへの絶対パスを返す。

#### Step 2: 各データアクセスクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Countries.php | `src/Symfony/Component/Intl/Countries.php` | 国コード変換(alpha-2/alpha-3/numeric)、withUserAssigned()フラグ |
| 2-2 | Currencies.php | `src/Symfony/Component/Intl/Currencies.php` | 通貨データ(名前、記号、小数桁数)、国別通貨取得 |
| 2-3 | Languages.php | `src/Symfony/Component/Intl/Languages.php` | 言語名データの提供 |
| 2-4 | Scripts.php | `src/Symfony/Component/Intl/Scripts.php` | スクリプト名データの提供 |
| 2-5 | Locales.php | `src/Symfony/Component/Intl/Locales.php` | ロケール名データの提供 |
| 2-6 | Timezones.php | `src/Symfony/Component/Intl/Timezones.php` | タイムゾーンデータの提供 |

**主要処理フロー**:
- **Countries.php 38-45行目**: getCountryCodes() - withUserAssigned()に応じてユーザー割当コードを含める
- **Countries.php 199-206行目**: getNames() - asort()でロケール順にソートして返却
- **Countries.php 234-241行目**: withUserAssigned() - 環境変数による制御
- **Currencies.php 90-97行目**: getFractionDigits() - 通貨固有値がなければDEFAULT値を返却

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

```
Countries::getNames($displayLocale)
    |
    +-- ResourceBundle::readEntry(['Names'], $displayLocale)
    |       |
    |       +-- ResourceBundle::getPath() -> Intl::getDataDirectory()/regions
    |       +-- PHPデータファイルをrequire
    |
    +-- ResourceBundle::asort($names, $displayLocale)
            |
            +-- Collator($displayLocale)::asort() [intl拡張利用時]
            +-- asort() [intl拡張なし時]
```

### データフロー図

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

$displayLocale ──────────> ResourceBundle::readEntry() ──> array<string, string>
                                |                           (コード => 名前)
                                v
                    Resources/data/{type}/{locale}.php
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Intl.php | `src/Symfony/Component/Intl/Intl.php` | ソース | ICUデータへのアクセスエントリポイント |
| ResourceBundle.php | `src/Symfony/Component/Intl/ResourceBundle.php` | ソース | データ読み込みの基底クラス |
| Countries.php | `src/Symfony/Component/Intl/Countries.php` | ソース | 国/地域データアクセス |
| Currencies.php | `src/Symfony/Component/Intl/Currencies.php` | ソース | 通貨データアクセス |
| Languages.php | `src/Symfony/Component/Intl/Languages.php` | ソース | 言語データアクセス |
| Scripts.php | `src/Symfony/Component/Intl/Scripts.php` | ソース | スクリプトデータアクセス |
| Locales.php | `src/Symfony/Component/Intl/Locales.php` | ソース | ロケールデータアクセス |
| Locale.php | `src/Symfony/Component/Intl/Locale.php` | ソース | ロケールユーティリティ |
| Timezones.php | `src/Symfony/Component/Intl/Timezones.php` | ソース | タイムゾーンデータアクセス |
| Resources/data/ | `src/Symfony/Component/Intl/Resources/data/` | データ | ICUデータファイル群 |
