# 機能設計書 42-スライド編集

## 概要

本ドキュメントは、LEGACY CMSのローテーター管理機能における「スライド編集」機能の設計仕様を定義する。

### 本機能の処理概要

既存のローテータースライドの内容を編集・更新するための機能である。管理者はAjaxダイアログを通じてスライドのタイトル、説明文、リンクURL、表示優先度、および画像アセットを変更し、データベースのスライド情報を更新できる。

**業務上の目的・背景**：Webサイトに表示されるバナースライドは、時間の経過やキャンペーン内容の変更に伴い更新が必要となる。リンク先の変更、画像の差し替え、表示順序の調整など、既存スライドのメンテナンスを効率的に行うための機能が求められる。本機能により、サイトの鮮度を維持し、ユーザーに最新の情報を提供できる。

**機能の利用シーン**：キャンペーン期間の延長に伴うバナー情報の更新、リンク切れの修正、画像デザインの変更、表示順序の見直しなど、既存スライドの内容を変更する際に使用される。ローテーター編集画面でスライド一覧から対象スライドをクリックすることでAjaxダイアログが開き、編集フォームが表示される。

**主要な処理内容**：
1. 対象スライドの既存データを取得してフォームに表示
2. 入力値（タイトル、説明、リンク、優先度、画像）のバリデーション
3. rotators_slidesテーブルの対象レコードを更新
4. 更新完了メッセージの表示とダイアログクローズ

**関連システム・外部連携**：アセット管理システムと連携し、スライド画像の選択・変更機能を提供する。Dojo Toolkitを使用したAjaxダイアログでユーザーインターフェースを実現している。

**権限による制御**：`rotrotators`（ローテーターモジュールアクセス権限）と`rotrotatoredit`（ローテーター編集権限）の両方を持つユーザーのみがスライドを編集できる。権限がない場合は権限エラー画面に遷移する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 89 | スライド編集画面 | 主画面 | スライドの編集処理 |
| 88 | ローテーター編集画面 | 遷移元画面 | スライド一覧からクリックしてダイアログを開く |
| 83 | 画像挿入画面 | 参照画面 | スライド画像の変更選択 |

## 機能種別

CRUD操作（Update） / Ajaxダイアログ処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | integer | Yes | 対象スライドのID | URLパラメータから取得、数値チェック |
| slidetitle | string | Yes | スライドのタイトル | NotEmpty、空文字不可 |
| slidedescription | string | No | スライドの説明文（キャプション） | allowEmpty: true |
| slidelink | string | Yes | クリック時の遷移先URL | NotEmpty、空文字不可 |
| slidepriority | integer | Yes | 表示優先度（数値） | NotEmpty、空文字不可 |
| asset | string | Yes | 画像アセットのキー | NotEmpty、空文字不可 |

### 入力データソース

- id: URLパラメータから取得（/admin/rotators/slide/id/{id}/）
- その他: POSTリクエストのフォームデータ
- 初期表示値: fetchSlide()で取得した既存データ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 成功メッセージ | HTML | 「Slide Saved」のメッセージと閉じるボタン |
| エラーメッセージ | array | バリデーションエラー時のメッセージ配列 |
| slideArray | array | 既存スライドデータ（フォーム初期値用） |

### 出力先

- Ajaxダイアログ内にHTMLレスポンスとして出力
- rotators_slidesテーブルの既存レコードを更新

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ slideActionがコールされる
2. 権限チェック
   └─ rotrotators, rotrotatoredit権限を確認
3. レイアウト無効化
   └─ Ajaxダイアログ用にレイアウトを無効化
4. 既存データ取得
   └─ fetchSlide()でスライド情報を取得
5. POSTリクエスト判定
   └─ POSTでない場合はフォームを表示（既存データをセット）
6. バリデーション実行
   └─ Zend_Filter_Inputでフォーム入力を検証
7. バリデーション結果判定
   └─ 失敗時: エラーメッセージを設定してフォーム再表示
   └─ 成功時: 次のステップへ
8. データベース更新
   └─ Rotators::updateSlide()でrotators_slidesを更新
9. 成功レスポンス出力
   └─ 「Slide Saved」メッセージとCloseボタンを表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{権限チェック}
    B -->|NG| C[権限エラー画面へ]
    B -->|OK| D[レイアウト無効化]
    D --> E[fetchSlide実行]
    E --> F{POSTリクエスト?}
    F -->|No| G[既存データでフォーム表示]
    F -->|Yes| H[バリデーション実行]
    H --> I{バリデーション成功?}
    I -->|No| J[エラーメッセージ設定]
    J --> G
    I -->|Yes| K[updateSlide実行]
    K --> L[rotators_slides UPDATE]
    L --> M[成功メッセージ出力]
    M --> N[終了]
    G --> N
    C --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-42-01 | タイトル必須 | スライドのタイトルは必須入力 | 常時 |
| BR-42-02 | リンク必須 | 遷移先URLは必須入力 | 常時 |
| BR-42-03 | 優先度必須 | 表示順序を決める優先度は必須 | 常時 |
| BR-42-04 | 画像必須 | スライド画像は必須選択 | 常時 |
| BR-42-05 | 権限チェック | rotrotatorsとrotrotatoredit権限が必要 | 常時 |
| BR-42-06 | 存在確認 | 指定IDのスライドが存在すること | 更新前 |

### 計算ロジック

特になし。優先度(rots_order)は数値として保存され、一覧表示時のソート順序に使用される。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スライド取得 | rotators_slides | SELECT | 対象スライドの既存データを取得 |
| スライド更新 | rotators_slides | UPDATE | スライド情報を更新 |

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

#### rotators_slides（SELECT）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | WHERE rots_id = {id} | 全カラムを取得 |

#### rotators_slides（UPDATE）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | rots_title | フォーム入力値(slidetitle) | スライドタイトル |
| UPDATE | rots_description | フォーム入力値(slidedescription) | キャプション |
| UPDATE | rots_link | フォーム入力値(slidelink) | 遷移先URL |
| UPDATE | rots_order | フォーム入力値(slidepriority) | 表示優先度 |
| UPDATE | rots_asset | フォーム入力値(asset) | 画像アセットキー |
| WHERE | rots_id | URLパラメータ(id) | 更新対象の条件 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 権限エラー | rotrotators/rotrotatoredit権限なし | privileges画面へフォワード |
| - | バリデーションエラー | タイトルが空 | 「Title is required」メッセージ表示 |
| - | バリデーションエラー | リンクが空 | 「Link is required」メッセージ表示 |
| - | バリデーションエラー | 優先度が空 | 「Priority is required」メッセージ表示 |
| - | バリデーションエラー | アセットが空 | 「Asset is required」メッセージ表示 |
| Exception | IDエラー | IDがNULLまたは非数値 | 「Invalid slide id」例外をスロー |

### リトライ仕様

特になし。バリデーションエラー時は入力値を保持してフォームを再表示する。

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

単一のUPDATE操作のため、明示的なトランザクション制御は行っていない。

## パフォーマンス要件

- Ajaxダイアログのレスポンス時間: 1秒以内
- レイアウトを無効化することでレスポンスサイズを最小化

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

- ACLによるアクセス制御（rotrotators, rotrotatoredit権限の確認）
- Zend_Filter_Inputによる入力値のサニタイズ
- IDパラメータの数値チェック（is_numeric）

## 備考

- Dojo Toolkitのdijit.form.ValidationTextBoxを使用したクライアントサイドバリデーションも実装されている
- 画像選択はアセット管理機能と連携し、openAssetMan()関数でポップアップ表示される
- 更新完了後、location.reload(true)でページ全体をリロードしてスライド一覧を更新する
- rots_rotator（所属ローテーター）は編集対象外

---

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

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

### 推奨読解順序

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

まず、スライドデータの構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | database.sql | `database.sql` | rotators_slidesテーブルの構造を確認（320-329行目） |

**読解のコツ**: rots_idが主キー、rots_rotatorが外部キー参照として機能する。編集時はrots_idで特定し、rots_rotator以外のカラムを更新する。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RotatorsController.php | `application/modules/admin/controllers/RotatorsController.php` | slideActionメソッド（171-257行目） |

**主要処理フロー**:
1. **173行目**: ACL権限チェック（rotrotators AND rotrotatoredit）
2. **175行目**: レイアウト無効化
3. **177-181行目**: IDパラメータ取得とfetchSlide実行
4. **183-215行目**: POSTリクエスト時のバリデータ定義
5. **217行目**: Zend_Filter_Inputでバリデーション実行
6. **219-227行目**: バリデーション成功時の処理（updateSlide呼び出し、成功メッセージ出力）
7. **236-241行目**: バリデーション失敗時の処理（エラーメッセージ設定）

#### Step 3: モデル層を理解する

データベース操作を行うモデルクラスを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Rotators.php | `application/models/Rotators.php` | fetchSlideメソッド（123-136行目） |
| 3-2 | Rotators.php | `application/models/Rotators.php` | updateSlideメソッド（179-190行目） |

**主要処理フロー**:
- **fetchSlide（125-135行目）**: IDの数値チェック、SELECTクエリ実行、配列で返却
- **updateSlide（181-189行目）**: 更新データ配列の構築、UPDATEクエリ実行

#### Step 4: ビュー層を理解する

フォーム表示を行うビューファイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | slide.phtml | `application/modules/admin/views/scripts/rotators/slide.phtml` | フォームHTML構造（11-114行目） |

**主要処理フロー**:
- **11行目**: Dojoフォームの開始
- **23行目**: タイトル入力フィールドの初期値（slideArray['rots_title']）
- **37行目**: 説明入力フィールドの初期値（slideArray['rots_description']）
- **52行目**: リンク入力フィールドの初期値（slideArray['rots_link']）
- **68行目**: 優先度入力フィールドの初期値（slideArray['rots_order']）
- **93行目**: アセットhidden値の初期値（slideArray['rots_asset']）
- **106行目**: 送信ボタン（doDialog関数呼び出しでslideAction実行）

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

```
Admin_RotatorsController::slideAction()
    │
    ├─ $this->view->acl->isAllowed()
    │      └─ 権限チェック
    │
    ├─ $this->_helper->layout->disableLayout()
    │      └─ レイアウト無効化
    │
    ├─ Rotators::fetchSlide($id)
    │      └─ $registry->db->select() → fetchall()
    │             └─ 既存データ取得
    │
    ├─ new Zend_Filter_Input()
    │      └─ POSTデータのバリデーション
    │
    └─ Rotators::updateSlide()
           └─ $registry->db->update('rotators_slides', $data, 'rots_id = '.$id)
                  └─ MySQLへのUPDATE実行
```

### データフロー図

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

URLパラメータ            RotatorsController            rotators_slides
  - id            ─────▶  ::slideAction()      ─────▶  テーブル
                          │                            │
                          ├─ fetchSlide($id)           │
                          │   └─ 既存データ取得          │
                          │                            │
POSTデータ                │                            ├─ rots_title
  - slidetitle    ─────▶  ├─ バリデーション            ├─ rots_description
  - slidedescription      │                           ├─ rots_link
  - slidelink             └─ updateSlide()            ├─ rots_order
  - slidepriority                                      └─ rots_asset
  - asset
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RotatorsController.php | `application/modules/admin/controllers/RotatorsController.php` | コントローラー | スライド編集アクションの定義 |
| Rotators.php | `application/models/Rotators.php` | モデル | スライドのCRUD操作 |
| slide.phtml | `application/modules/admin/views/scripts/rotators/slide.phtml` | ビュー | スライド編集フォームのHTML |
| database.sql | `database.sql` | スキーマ | rotators_slidesテーブル定義 |
| common.js | `public/_scripts/admin/common.js` | JavaScript | doDialog関数等の共通処理 |
