# 機能設計書 52-タグオートコンプリート

## 概要

本ドキュメントは、LEGACY CMSにおけるタグオートコンプリート機能の設計を定義する。この機能は、タグ入力時に既存タグの候補を表示し、ユーザーの入力を補助するための機能である。

### 本機能の処理概要

**業務上の目的・背景**：コンテンツ管理システムにおいて、タグの一貫性を保つことは重要である。同じ意味のタグが異なる表記で登録されると、検索性が低下し、タグによる分類が機能しなくなる。オートコンプリート機能により、既存のタグを候補として提示することで、タグ表記の統一を促進し、タグ体系の一貫性を維持できる。

**機能の利用シーン**：管理画面で記事やページなどのコンテンツを編集する際、「Tags」タブ内のタグ入力フィールドに文字を入力すると、既存タグの中から入力文字列にマッチする候補がドロップダウンリストで表示される。ユーザーは候補から選択するか、新しいタグを入力できる。

**主要な処理内容**：
1. データベースから全タグの一意なリストを取得
2. Zend_Dojo_Data形式でJSON応答を生成
3. クライアントサイドのdijit.form.ComboBoxに候補データを提供
4. 入力に応じたリアルタイムフィルタリング（クライアント側）

**関連システム・外部連携**：Dojo ToolkitのComboBoxウィジェット（dojo.data.ItemFileReadStore）との連携。サーバーはJSON形式でタグ候補データを提供し、クライアント側でフィルタリングが行われる。

**権限による制御**：タグの入力・オートコンプリートは、該当コンテンツの編集権限を持つユーザーであれば利用可能。コントローラはCMS_Controller_Action_Adminを継承しており、管理者認証が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 36 | 記事編集画面 | 主画面 | タグタブ内でオートコンプリート入力 |
| 37 | 記事新規作成画面 | 主画面 | タグタブ内でオートコンプリート入力 |
| 49 | イベント編集画面 | 主画面 | タグタブ内でオートコンプリート入力 |
| 50 | イベント新規作成画面 | 主画面 | タグタブ内でオートコンプリート入力 |
| 61 | ページ編集画面 | 主画面 | タグタブ内でオートコンプリート入力 |
| 62 | ページ新規作成画面 | 主画面 | タグタブ内でオートコンプリート入力 |

## 機能種別

データ取得 / UI補助機能

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| q | string | No | 検索クエリ（現在は未使用） | なし |

### 入力データソース

- URLパラメータ経由（クエリパラメータ'q'）
- Ajax経由でItemFileReadStoreからリクエストされる

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| タグ候補リスト | JSON | Zend_Dojo_Data形式のタグ一覧 |

### 出力先

- HTTPレスポンス（Content-Type: application/json）
- dojo.data.ItemFileReadStoreが消費

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ autocompleteActionメソッドがコールされる
2. レイアウト無効化
   └─ JSON応答のためレイアウトレンダリングを無効化
3. データベースクエリ実行
   └─ tagsテーブルから重複なしのタグ名一覧を取得
4. クエリパラメータ取得
   └─ URLパラメータから検索クエリを取得（デフォルト空文字）
5. Dojo Data形式に変換
   └─ Zend_Dojo_Dataを使用してJSON形式に変換
6. レスポンス出力
   └─ JSONデータを出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[autocompleteAction呼び出し]
    B --> C[レイアウト無効化]
    C --> D[DB: tagsテーブルからDISTINCTクエリ]
    D --> E[タグ配列を取得]
    E --> F[クエリパラメータ'q'取得]
    F --> G[Zend_Dojo_Data生成]
    G --> H[JSONデータ出力]
    H --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-01 | 重複排除 | 同一タグ名は1件のみ表示される | 常時 |
| BR-52-02 | 全タグ取得 | コンテンツタイプに関係なく全タグを候補として表示 | 常時 |
| BR-52-03 | 降順ソート | タグはtag_tagフィールドの降順でソートされる | 常時 |

### 計算ロジック

計算ロジックは存在しない。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| タグ候補取得 | tags | SELECT | 重複なしのタグ名一覧を取得 |

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

#### tags

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT DISTINCT | tag_tag | ORDER BY t.tag_tag DESC | タグ名のみ取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | データベースエラー | DB接続失敗時 | Zend Frameworkの例外ハンドリング |

### リトライ仕様

リトライ処理は実装されていない。

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

SELECT文のみのため、トランザクション制御は不要。

## パフォーマンス要件

- タグ入力時のリアルタイム補完のため、高速なレスポンスが必要
- クライアント側でフィルタリングを行うため、初回取得時に全タグを返却
- タグ数が多い場合はパフォーマンス劣化の可能性あり

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

- CMS_Controller_Action_Adminを継承しており、管理者認証が必須
- 出力データはZend_Dojo_Dataによりエスケープ処理される

## 備考

- 現在の実装ではサーバーサイドフィルタリングは行われていない
- 全タグをクライアントに送信し、Dojoのコンポーネントがローカルフィルタリングを行う
- タグ数が非常に多い場合は、サーバーサイドフィルタリングの導入を検討すべき

---

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

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

### 推奨読解順序

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

オートコンプリートで使用されるデータ形式を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | autocomplete.phtml | `application/modules/admin/views/scripts/tags/autocomplete.phtml` | Zend_Dojo_Dataによる出力形式 |

**読解のコツ**: Zend_Dojo_Dataは、Dojo ToolkitのItemFileReadStoreが期待するJSON形式でデータを出力する。第1引数はidentifier、第2引数はデータ配列、第3引数はlabelフィールド名。

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

コントローラのアクションを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TagsController.php | `application/modules/admin/controllers/TagsController.php` | autocompleteActionメソッドの処理フロー |

**主要処理フロー**:
1. **196-212行目**: autocompleteAction - オートコンプリートデータ取得
2. **198行目**: レイアウト無効化
3. **203-206行目**: DISTINCTクエリでタグ一覧取得
4. **208行目**: ビューにタグ配列を渡す
5. **211行目**: クエリパラメータをビューに渡す

#### Step 3: クライアントサイドの連携を理解する

Dojo ToolkitのComboBoxとの連携を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tagspane.phtml | `application/modules/admin/views/scripts/_partials/tagspane.phtml` | ItemFileReadStoreとComboBoxの連携 |

**主要処理フロー**:
- **13行目**: ItemFileReadStoreのURL設定（/admin/tags/autocomplete）
- **16-26行目**: ComboBoxの設定（store、searchAttr等）

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

```
Admin_TagsController::autocompleteAction()
    │
    ├─ $this->_helper->layout->disableLayout()
    │
    ├─ $registry->db->select()
    │      ├─ ->distinct()
    │      ├─ ->from('tags', 'tag_tag')
    │      └─ ->order('t.tag_tag DESC')
    │
    ├─ $registry->db->fetchall($select)
    │
    └─ View: autocomplete.phtml
           └─ Zend_Dojo_Data('tag_tag', $tagArray, 'tag')
```

### データフロー図

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

HTTP Request ───▶ TagsController     ───▶ JSON Response
(GET /admin/       ::autocompleteAction()    (Dojo Data形式)
 tags/autocomplete)      │
                         ▼
                    tagsテーブル
                    (SELECT DISTINCT)
                         │
                         ▼
                    autocomplete.phtml
                    (Zend_Dojo_Data変換)
                         │
                         ▼
[クライアント]
dojo.data.ItemFileReadStore ◀───────────────┘
         │
         ▼
dijit.form.ComboBox
(ユーザーに候補表示)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TagsController.php | `application/modules/admin/controllers/TagsController.php` | コントローラ | オートコンプリートアクションを提供 |
| autocomplete.phtml | `application/modules/admin/views/scripts/tags/autocomplete.phtml` | ビュー | Dojo Data形式でJSON出力 |
| tagspane.phtml | `application/modules/admin/views/scripts/_partials/tagspane.phtml` | ビュー | ComboBoxのUI定義 |
| Tags.php | `application/models/Tags.php` | モデル | タグデータ操作（本機能では未使用） |
