# 機能設計書 51-タグ削除

## 概要

本ドキュメントは、LEGACY CMSにおけるタグ削除機能の設計を定義する。この機能は、コンテンツ（記事、ページ、イベント等）に紐づけられたタグを削除するための機能である。

### 本機能の処理概要

**業務上の目的・背景**：コンテンツ管理において、タグは記事やページなどのコンテンツを分類・整理するための重要なメタデータである。不要になったタグや誤って追加されたタグを削除する機能は、コンテンツの整理・管理において必須の機能である。この機能により、管理者はコンテンツに付与されたタグを柔軟に管理し、サイトのタグ体系を適切に維持できる。

**機能の利用シーン**：管理画面で記事やページなどのコンテンツを編集する際、「Tags」タブ内に表示されているタグをクリックして削除する。タグにマウスオーバーすると削除可能な状態に変化し、クリックすることで即座に削除が実行される。

**主要な処理内容**：
1. 削除対象タグIDの受け取りとバリデーション
2. データベースからのタグレコード削除
3. 削除完了メッセージの表示
4. タグ一覧の動的更新（Ajax経由）

**関連システム・外部連携**：Dojo Toolkitを使用したAjaxダイアログとの連携。タグ削除後、ContentPaneの再読み込みによりタグ一覧が自動更新される。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 36 | 記事編集画面 | 主画面 | タグタブ内でタグ削除を実行 |
| 49 | イベント編集画面 | 主画面 | タグタブ内でタグ削除を実行 |
| 61 | ページ編集画面 | 主画面 | タグタブ内でタグ削除を実行 |

## 機能種別

CRUD操作（Delete）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | integer | Yes | 削除対象のタグID | 数値チェック、NULL不可 |

### 入力データソース

- URLパラメータ経由で削除対象タグIDを取得
- Ajax経由でリクエストされる

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 結果メッセージ | HTML | 削除完了メッセージとCloseボタンを含むHTML |

### 出力先

- Ajaxダイアログ（dijit.Dialog）内にHTML形式で出力

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ deleteActionメソッドがコールされる
2. レイアウト・ビュー無効化
   └─ Ajax応答のためレイアウトとビューレンダリングを無効化
3. パラメータ取得
   └─ URLパラメータからタグIDを取得
4. タグID検証
   └─ IDがセットされているか確認
5. データベース削除実行
   └─ tagsテーブルから該当レコードを削除
6. 結果出力
   └─ 削除完了メッセージとCloseボタンをHTML出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[deleteAction呼び出し]
    B --> C[レイアウト・ビュー無効化]
    C --> D[パラメータ'id'取得]
    D --> E{idがセット?}
    E -->|Yes| F[DB: tagsテーブルから削除]
    F --> G[削除完了HTML出力]
    E -->|No| H[処理終了]
    G --> I[終了]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-51-01 | タグID必須 | 削除対象のタグIDは必須パラメータである | 常時 |
| BR-51-02 | 物理削除 | タグは論理削除ではなく物理削除される | 常時 |
| BR-51-03 | 単一削除 | 一度に削除できるタグは1件のみ | 常時 |

### 計算ロジック

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

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| タグ削除 | tags | DELETE | 指定IDのタグレコードを削除 |

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

#### tags

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | tag_id | WHERE tag_id = {パラメータID} | 主キーによる削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パラメータエラー | idパラメータが未指定 | 処理を行わず終了 |
| Exception | 無効なID | idがNULLまたは非数値（Tagsモデル使用時） | 例外スロー |

### リトライ仕様

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

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

単一のDELETE文による削除のため、明示的なトランザクション制御は行われていない。

## パフォーマンス要件

- Ajax経由での即時応答が求められる
- 主キーによる削除のため、インデックスを活用した高速な処理が期待される

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

- CMS_Controller_Action_Adminを継承しており、管理者認証が必須
- SQLインジェクション対策として、直接SQL連結が使用されている（改善の余地あり）

## 備考

- 削除後のタグ一覧更新は、クライアントサイドJavaScriptによるContentPaneの再読み込みで実現される
- Tagsモデルクラスにはバリデーション付きのdeleteTagメソッドがあるが、コントローラではレジストリ経由で直接削除を実行している

---

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

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

### 推奨読解順序

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

タグの削除処理を理解するために、まずデータベーススキーマとモデルクラスを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Tags.php | `application/models/Tags.php` | タグモデルの構造、deleteTagメソッドのバリデーションロジック |

**読解のコツ**: Zend_Registry経由でデータベースアダプタにアクセスする設計パターンに注目。

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

削除処理の起点となるコントローラのアクションを確認する。

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

**主要処理フロー**:
1. **52-76行目**: deleteAction - タグ削除処理のエントリーポイント
2. **54-55行目**: レイアウトとビューの無効化（Ajax応答用）
3. **57行目**: パラメータからタグIDを取得
4. **59-74行目**: IDが設定されている場合にDB削除と結果出力

#### Step 3: ビューテンプレートを理解する

タグ一覧表示と削除UIの連携を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.phtml | `application/modules/admin/views/scripts/tags/show.phtml` | タグ一覧の表示とクリックイベントによる削除呼び出し |
| 3-2 | tagspane.phtml | `application/modules/admin/views/scripts/_partials/tagspane.phtml` | タグ管理UI全体の構造 |

**主要処理フロー**:
- **11行目**: onClickイベントでdeleteTag関数を呼び出し（JavaScript）

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

```
Admin_TagsController::deleteAction()
    │
    ├─ $this->_helper->layout()->disableLayout()
    │
    ├─ $this->_helper->viewRenderer->setNoRender(true)
    │
    ├─ $this->_getParam('id')
    │
    └─ $registry->db->delete('tags', 'tag_id = '.$id)
```

### データフロー図

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

URLパラメータ ───▶ TagsController     ───▶ HTML応答
(id=タグID)        ::deleteAction()         (削除完了メッセージ)
                        │
                        ▼
                   tagsテーブル
                   (DELETE)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TagsController.php | `application/modules/admin/controllers/TagsController.php` | コントローラ | タグ削除アクションを提供 |
| Tags.php | `application/models/Tags.php` | モデル | タグデータの操作（deleteTag, deleteSlaveTag） |
| show.phtml | `application/modules/admin/views/scripts/tags/show.phtml` | ビュー | タグ一覧表示と削除UI |
| tagspane.phtml | `application/modules/admin/views/scripts/_partials/tagspane.phtml` | ビュー | タグ管理パネル全体 |
| TagCount.php | `application/modules/admin/views/helpers/TagCount.php` | ヘルパー | タグ数カウント表示 |
