# 機能設計書 25-イベント公開/非公開

## 概要

本ドキュメントは、LEGACY CMSにおけるイベント公開/非公開機能の設計仕様を定義する。

### 本機能の処理概要

イベント公開/非公開機能は、draft（下書き）状態のイベントをpublished（公開）状態に変更するための機能である。公開処理時にはイベント情報のバリデーションを行い、検索インデックスへの登録も同時に実行される。

**業務上の目的・背景**：イベント情報は作成時に下書き状態で保存され、内容の確認・修正後に公開される運用フローを想定している。公開前にバリデーションを実行することで、不完全な情報の公開を防止する。また、公開と同時に検索インデックスに登録することで、サイト内検索で即座に検索可能になる。

**機能の利用シーン**：イベント編集画面で「Publish」ボタンをクリックすると、確認ダイアログが表示される。確認後、イベント情報のバリデーションが行われ、問題なければ公開状態に変更される。

**主要な処理内容**：
1. 公開確認ダイアログの表示
2. イベント情報のバリデーション
3. event_statusをpublishedに更新
4. event_published（公開日時）を現在時刻で設定
5. 検索インデックスへの登録

**関連システム・外部連携**：Zend_Search_Luceneによる検索インデックス登録

**権限による制御**：「eevents」権限と「eeventpublish」権限の両方を持つロールのみがアクセス可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 49 | イベント編集画面 | 遷移元画面 | 公開ステータスの切り替え |

## 機能種別

CRUD操作（Update）/ ステータス変更 / バリデーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | int | Yes | イベントID | 数値 |
| confirm | string | No | 公開確認フラグ | '1'で確認済み |
| title | string | Yes | イベントタイトル | NotEmpty（confirm=1時） |
| category | int | Yes | カテゴリID | NotEmpty（confirm=1時） |
| venue | int | Yes | 会場ID | NotEmpty（confirm=1時） |
| datestart | string | Yes | 開始日 | NotEmpty（confirm=1時） |
| timestart | string | Yes | 開始時刻 | NotEmpty（confirm=1時） |
| dateend | string | No | 終了日 | allowEmpty |
| timeend | string | No | 終了時刻 | allowEmpty |
| description | string | Yes | 説明文 | NotEmpty（confirm=1時） |
| url | string | No | 関連URL | allowEmpty |
| ticket | string | No | チケット情報 | allowEmpty |
| comments | string | No | コメント許可フラグ | Y/N |
| moderate | string | No | コメントモデレーションフラグ | Y/N |

### 入力データソース

- URLパラメータ（イベントID、確認フラグ）
- フォームデータ（POSTリクエスト）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 確認メッセージ | string | 「Are you sure you want to publish this event?」 |
| 成功メッセージ | string | 「Event Published」 |
| エラーメッセージ | array | バリデーションエラーメッセージ |

### 出力先

- 画面表示（Ajaxダイアログ内）
- データベース（eventsテーブル UPDATE）
- 検索インデックス（Lucene ADD）

## 処理フロー

### 処理シーケンス

```
1. 公開要求受付
   └─ ACL権限チェック（eevents, eeventpublish）

2. 確認フラグチェック
   ├─ confirm != '1' の場合
   │     └─ 確認ダイアログ表示
   └─ confirm == '1' かつ id設定ありの場合
         ├─ 入力バリデーション
         ├─ バリデーション失敗時はエラー表示
         ├─ event_status を 'published' に更新
         ├─ event_published を NOW() に設定
         ├─ 検索インデックスに追加
         └─ 成功メッセージ表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{権限チェック}
    B -->|権限なし| C[権限エラー]
    B -->|権限あり| D{confirm = '1' かつ id設定あり?}
    D -->|No| E[確認ダイアログ表示]
    E --> F{ユーザー操作}
    F -->|Publish| G[confirm=1でフォームPOST]
    F -->|Cancel| H[ダイアログ閉じる]
    G --> D
    D -->|Yes| I[入力バリデーション]
    I --> J{バリデーション成功?}
    J -->|No| K[エラーメッセージ表示]
    J -->|Yes| L[日付フォーマット変換]
    L --> M[DB UPDATE]
    M --> N[会場情報取得]
    N --> O[検索インデックス追加]
    O --> P[成功メッセージ表示]
    P --> Q[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-25-01 | 公開前バリデーション | 公開時に必須項目のバリデーションを再実行 | 常時 |
| BR-25-02 | 公開日時設定 | 公開時にevent_publishedを現在日時で設定 | 常時 |
| BR-25-03 | ステータス変更 | event_statusを'published'に変更 | 常時 |
| BR-25-04 | 検索インデックス登録 | 公開と同時に検索インデックスに追加 | 常時 |

### 計算ロジック

- 公開日時: `new Zend_Db_Expr('NOW()')`
- 検索インデックスキー: 'e' + event_id
- 検索インデックス日付: 現在日付（Ymd形式）
- 検索インデックスURL: `/events/event/{event_id}/{urlencode(title)}/`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| イベント更新 | events | UPDATE | ステータス変更・公開日時設定 |
| 会場情報取得 | events_venues | SELECT (JOIN) | 検索インデックス用会場情報取得 |

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

#### events

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | event_title | 入力値 | タイトル更新 |
| UPDATE | event_category | 入力値 | カテゴリ更新 |
| UPDATE | event_venue | 入力値 | 会場更新 |
| UPDATE | event_date | フォーマット変換後 | 開始日時更新 |
| UPDATE | event_end | フォーマット変換後 | 終了日時更新 |
| UPDATE | event_description | html_entity_decode後 | 説明文更新 |
| UPDATE | event_user | ログインユーザーID | 更新者 |
| UPDATE | event_url | 入力値 | URL更新 |
| UPDATE | event_tickets | 入力値 | チケット情報更新 |
| UPDATE | event_comments | Y/N | コメント許可フラグ更新 |
| UPDATE | event_moderate | Y/N | モデレーションフラグ更新 |
| UPDATE | event_published | NOW() | 公開日時設定 |
| UPDATE | event_status | 'published' | ステータス変更 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 権限エラー | eevents/eeventpublish権限なし | 権限エラー画面へ転送 |
| - | バリデーションエラー | 必須項目未入力 | エラーメッセージ表示 |

### リトライ仕様

特になし（フォーム修正後に再度公開試行）

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

単一UPDATE操作のため、明示的なトランザクション制御は不要

## パフォーマンス要件

- Ajaxダイアログでの表示のため、レスポンスは軽量であること

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

- 管理画面へのアクセスはACLによる権限チェック必須（eevents + eeventpublish）
- 公開前のバリデーションで不正データの公開を防止
- 入力値はZend_Filter_Inputによるバリデーション

## 備考

- 非公開（unpublish）機能は本システムでは実装されていない
- 一度公開されたイベントを下書きに戻す機能は別途検討が必要

---

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

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

### 推奨読解順序

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

イベントテーブルのステータス関連カラムを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | eventsテーブル | データベース | event_status, event_published カラムの役割 |

**読解のコツ**: event_statusは'draft'と'published'の2値をとり、event_publishedは公開時刻を格納する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Admin_EventsController.php | `application/modules/admin/controllers/EventsController.php` | publishAction |

**主要処理フロー（publishAction）**:
1. **449-451行目**: 権限チェック（eevents, eeventpublish）
2. **453-454行目**: レイアウト・ビュー無効化
3. **456-457行目**: パラメータ取得（confirm, id）
4. **459行目**: 確認フラグとイベントIDの存在チェック
5. **462-473行目**: コメント/モデレーションフラグ処理
6. **475-516行目**: バリデーション定義
7. **518行目**: Zend_Filter_Inputでバリデーション実行
8. **521行目**: レジストリ取得
9. **523行目**: バリデーション成功判定
10. **525-527行目**: 日付フォーマット変換
11. **530-544行目**: UPDATEデータ配列作成（status='published', published=NOW()含む）
12. **547行目**: データベースUPDATE実行
13. **550-558行目**: 公開後イベント情報再取得（会場情報含む）
14. **561行目**: 検索インデックスURL生成
15. **563-571行目**: 会場情報に基づくdetails生成
16. **573-580行目**: 検索インデックス追加（searchIndex->add）
17. **582-587行目**: 成功メッセージ表示
18. **602-610行目**: 確認ダイアログ表示（confirm != '1'の場合）

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

```
Admin_EventsController
    │
    └─ publishAction()
           │
           ├─ [confirm != '1'] 確認ダイアログ表示
           │
           └─ [confirm == '1']
                  ├─ Zend_Filter_Input - バリデーション
                  ├─ date() - 日付フォーマット変換
                  ├─ Zend_Db_Adapter::update() - DB更新
                  ├─ Zend_Db_Select - 会場情報取得
                  └─ searchIndex->add() - 検索インデックス追加
```

### データフロー図

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

URLパラメータ               publishAction()
  id              ───▶
  confirm                   [confirm != '1']
                            │
                            └───▶ 確認ダイアログHTML

フォーム入力                publishAction()
  全フィールド    ───▶      [confirm == '1']
  confirm='1'               │
                            ├─ バリデーション
                            ├─ UPDATE events       ───▶   eventsテーブル
                            │   (status='published')      (UPDATE)
                            │
                            ├─ SELECT venues       ◀───   events_venuesテーブル
                            │
                            ├─ ADD index           ───▶   Luceneインデックス
                            │
                            └───▶ 成功メッセージHTML
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| EventsController.php | `application/modules/admin/controllers/EventsController.php` | コントローラー | イベント公開処理 |
| Admin.php | `library/CMS/Controller/Action/Admin.php` | 親クラス | 認証・ACL基盤処理 |
| edit.phtml | `application/modules/admin/views/scripts/events/edit.phtml` | ビュー | 公開ボタン（呼び出し元） |
| SearchIndex.php | ライブラリ | ヘルパー | 検索インデックス操作 |
