# 画面設計書 52-言語設定

## 概要

本ドキュメントは、Shopware 6 管理画面における言語設定（sw-settings-language）画面の設計書です。ECサイトで使用する言語の登録・編集・管理を行う画面について記述します。

### 本画面の処理概要

**業務上の目的・背景**：グローバルなECサイト運営において、多言語対応は顧客体験向上に不可欠です。本画面では、ショップで使用可能な言語を管理し、親言語の継承設定やロケールとの紐付けを行うことで、多言語ECサイトの運営を実現します。言語の階層構造により、翻訳の継承と上書きを柔軟に設定できます。

**画面へのアクセス方法**：管理画面にログイン後、左メニューの「設定」 > 「一般」セクション > 「言語」をクリックして一覧画面にアクセスします。一覧画面から新規作成ボタンまたは既存の言語名をクリックして詳細画面に遷移します。

**主要な操作・処理内容**：
1. 言語一覧の表示・検索・ソート
2. 新規言語の作成（言語名、ロケール、翻訳コード、親言語の設定）
3. 既存言語の編集
4. 言語の有効/無効切り替え
5. ルート言語（親なし）と継承言語（親あり）のフィルタリング
6. インライン編集による迅速な更新
7. 言語の削除（システムデフォルト言語は削除不可）

**画面遷移**：設定メニュー → 言語一覧画面 → 言語詳細画面。詳細画面から一覧画面への戻り遷移も可能です。

**権限による表示制御**：`language.viewer`権限で閲覧可能、`language.editor`権限で編集可能、`language.creator`権限で新規作成可能、`language.deleter`権限で削除可能です。システムデフォルト言語の削除は権限に関わらず不可です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 70 | コンテキスト切替 | 補助機能 | 多言語対応の設定 |

## 画面種別

一覧 / 詳細 / 登録 / 編集

## URL/ルーティング

| 画面 | URL | コンポーネント |
|------|-----|---------------|
| 言語一覧 | `#/sw/settings/language/index` | sw-settings-language-list |
| 言語詳細 | `#/sw/settings/language/detail/:id` | sw-settings-language-detail |
| 言語新規作成 | `#/sw/settings/language/create` | sw-settings-language-detail |

## 入出力項目

### 一覧画面

| 項目名 | 項目ID | 型 | 入力/出力 | 必須 | 説明 |
|--------|--------|-----|----------|------|------|
| 名前 | name | string | 入出力 | ○ | 言語の表示名 |
| ロケール | locale | relation | 出力 | - | 関連するロケール |
| ISOコード | translationCode.code | string | 出力 | - | 翻訳コード |
| 有効 | active | boolean | 入出力 | - | 言語の有効/無効状態 |

### 詳細画面

| 項目名 | 項目ID | 型 | 入力/出力 | 必須 | 説明 |
|--------|--------|-----|----------|------|------|
| 名前 | name | string | 入力 | ○ | 言語の表示名 |
| ロケール | localeId | uuid | 入力 | ○ | 関連するロケールID |
| 翻訳コード | translationCodeId | uuid | 入力 | 条件付 | ISO翻訳コード（ルート言語は必須） |
| 親言語 | parentId | uuid | 入力 | - | 翻訳を継承する親言語 |

## 表示項目

### 一覧画面

| 項目名 | 説明 |
|--------|------|
| 言語名 | 言語の表示名（詳細画面へのリンク） |
| ロケール名 | 関連するロケールの名前 |
| ISOコード | 翻訳コード（例：en-GB） |
| 有効 | 言語の有効/無効状態（トグル） |

### 詳細画面

| 項目名 | 説明 |
|--------|------|
| 基本情報 | 言語名、ロケール、翻訳コード、親言語 |
| カスタムフィールド | カスタムフィールドセットが定義されている場合に表示 |

## イベント仕様

### 1-保存ボタン押下

ユーザーが「保存」ボタンを押下すると、入力された言語情報がバリデーションされ、languageリポジトリを通じてAPIに保存リクエストが送信されます。保存成功時はisSaveSuccessfulフラグがtrueになり、新規作成の場合は詳細画面にリダイレクトされます。

### 2-キャンセルボタン押下

ユーザーが「キャンセル」ボタンを押下すると、変更を破棄して言語一覧画面に遷移します。

### 3-親言語変更

親言語を変更すると、既存データがある場合に警告アラートが表示されます（showAlertForChangeParentLanguage）。翻訳の継承関係が変更されることを警告します。

### 4-ルート言語/継承言語フィルター

一覧画面のフィルターを使用して、ルート言語（親なし）のみまたは継承言語（親あり）のみを表示できます。

### 5-インライン編集

一覧画面でセルをダブルクリックすると、インライン編集モードが有効になります。名前と有効状態がインライン編集可能です。

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | language | INSERT/UPDATE | 言語情報の新規作成または更新 |
| 保存ボタン押下 | language_translation | INSERT/UPDATE | 言語の翻訳情報 |
| 削除ボタン押下 | language | DELETE | 言語の削除 |

### テーブル別更新項目詳細

#### language

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | id | UUIDv4 | 新規作成時は自動生成 |
| INSERT/UPDATE | name | 入力値 | 言語名 |
| INSERT/UPDATE | locale_id | 選択値 | ロケールへの外部キー |
| INSERT/UPDATE | translation_code_id | 選択値 | 翻訳コードへの外部キー |
| INSERT/UPDATE | parent_id | 選択値またはNULL | 親言語への外部キー |
| INSERT/UPDATE | active | 入力値 | 有効/無効フラグ |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|------------|------|--------------|----------|
| messageSaveSuccess | 成功 | 言語が正常に保存されました | 保存成功時 |
| messageSaveError | エラー | 言語の保存中にエラーが発生しました | 保存失敗時 |
| tooltipInheritanceNotPossible | 情報 | システムデフォルト言語は親言語を設定できません | デフォルト言語編集時 |
| tooltipLanguageNotChoosable | 情報 | この言語は選択できません | 選択不可言語 |

## 例外処理

| 例外ケース | 処理内容 |
|-----------|---------|
| 言語が見つからない | エラー通知を表示し、一覧画面にリダイレクト |
| システムデフォルト言語の削除試行 | 削除ボタンを無効化し、ツールチップで説明表示 |
| 権限不足 | 該当するアクションボタンを無効化し、ツールチップで警告表示 |
| 通信エラー | エラー通知を表示し、ローディング状態を解除 |
| バリデーションエラー | 該当項目にエラー表示し、保存を中止 |
| 使用済み翻訳コードの重複 | 既に使用されている翻訳コードを選択不可に表示 |

## 備考

- システムデフォルト言語は削除および親言語の設定ができません
- ルート言語（親言語なし）は翻訳コードが必須です
- 継承言語は親言語から翻訳コードを継承できます
- 翻訳コードは一意である必要があり、他の言語で使用中のコードは選択時に警告表示されます
- カスタムフィールドセットが定義されている場合、詳細画面にカスタムフィールドセクションが表示されます

---

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

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

### 推奨読解順序

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

言語エンティティとその関連データの構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | LanguageDefinition.php | `src/Core/System/Language/` | 言語エンティティの定義、親子関係 |
| 1-2 | LocaleDefinition.php | `src/Core/System/Locale/` | ロケールエンティティの定義 |

**読解のコツ**: 言語は親子関係を持つ再帰的な構造になっています。parentIdがNULLの場合がルート言語です。

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

モジュール登録とルーティング設定を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.js | `src/Administration/Resources/app/administration/src/module/sw-settings-language/index.js` | モジュール登録、ルート定義、権限設定 |

**主要処理フロー**:
1. **14-60行目**: Module.registerでモジュール登録
2. **24-52行目**: routes定義（index, detail, create）
3. **54-59行目**: settingsItem定義（設定メニューへの追加、generalグループ）

#### Step 3: 一覧画面コンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.js | `src/Administration/Resources/app/administration/src/module/sw-settings-language/page/sw-settings-language-list/index.js` | 一覧画面のロジック |

**主要処理フロー**:
- **45-63行目**: listingCriteria - 言語一覧取得条件（ソート、フィルター、アソシエーション）
- **69-94行目**: getColumns() - グリッドカラム定義
- **118-139行目**: getList() - 言語一覧の取得と親言語の解決
- **141-147行目**: getParentName() - 親言語名の取得

#### Step 4: 詳細画面コンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.js | `src/Administration/Resources/app/administration/src/module/sw-settings-language/page/sw-settings-language-detail/index.js` | 詳細画面のロジック |

**主要処理フロー**:
- **168-185行目**: createdComponent() - 初期化処理、使用済み翻訳コードの取得
- **187-202行目**: loadEntityData() - 言語データの読み込み
- **220-231行目**: onInputLanguage() - 親言語変更時の警告処理
- **239-258行目**: onSave() - 保存処理

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

```
sw-settings-language (モジュール)
    │
    ├─ sw-settings-language-list (一覧画面)
    │      ├─ languageRepository.search() - 一覧取得
    │      ├─ フィルター処理 (ルート言語/継承言語)
    │      └─ 親言語名の解決
    │
    └─ sw-settings-language-detail (詳細画面)
           ├─ languageRepository.get() - 詳細取得
           ├─ languageRepository.create() - 新規作成
           ├─ languageRepository.save() - 保存
           ├─ 使用済み翻訳コード取得 (aggregation)
           └─ 親言語の翻訳コード継承処理
```

### データフロー図

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

言語フォーム入力 ───▶ sw-settings-language-detail ───▶ language テーブル
                              │
                              ├─▶ バリデーション
                              │     └─▶ 翻訳コード重複チェック
                              │
                              └─▶ languageRepository.save()
                                        │
                                        ▼
                              Admin API (/api/language)
                                        │
                                        ▼
                              LanguageRepository (PHP)
                                        │
                                        ▼
                              データベース (language)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.js | `src/Administration/Resources/app/administration/src/module/sw-settings-language/index.js` | ソース | モジュール定義 |
| index.js | `src/Administration/Resources/app/administration/src/module/sw-settings-language/page/sw-settings-language-list/index.js` | ソース | 一覧画面ロジック |
| sw-settings-language-list.html.twig | `src/Administration/Resources/app/administration/src/module/sw-settings-language/page/sw-settings-language-list/sw-settings-language-list.html.twig` | テンプレート | 一覧画面UI |
| index.js | `src/Administration/Resources/app/administration/src/module/sw-settings-language/page/sw-settings-language-detail/index.js` | ソース | 詳細画面ロジック |
| sw-settings-language-detail.html.twig | `src/Administration/Resources/app/administration/src/module/sw-settings-language/page/sw-settings-language-detail/sw-settings-language-detail.html.twig` | テンプレート | 詳細画面UI |
| index.js | `src/Administration/Resources/app/administration/src/module/sw-settings-language/acl/index.js` | ソース | 権限定義 |
