# 機能設計書 90-テーマ/フォーラム作成・編集

## 概要

本ドキュメントは、QuickerSite CMSにおける「テーマ/フォーラム作成・編集」機能について、その設計仕様を詳細に記述したものである。

### 本機能の処理概要

テーマ/フォーラム作成・編集機能は、掲示板・フォーラム・ブログのテーマを新規作成または編集する機能である。テーマの基本設定、投稿ルール、通知設定など多数のオプションを設定できる。

**業務上の目的・背景**：会員制サイトやコミュニティサイトにおいて、目的に応じた掲示板やブログを柔軟に構成する必要がある。本機能により、管理者はフォーラム、パーソナルブログ、タスクシステムの3種類のテーマを作成し、投稿権限、返信設定、通知メール、表示設定などを細かくカスタマイズできる。

**機能の利用シーン**：新しいフォーラムを作成する際、既存フォーラムの設定を変更する際、通知メールのテンプレートを編集する際、テーマを削除する際に使用する。

**主要な処理内容**：
1. テーマの新規作成・編集
2. テーマ種別設定（フォーラム/ブログ/タスク）
3. 投稿・返信ルール設定
4. 通知メールテンプレート設定
5. 表示オプション設定
6. テーマの削除

**関連システム・外部連携**：テーマ/フォーラム一覧機能（No.89）から遷移。テーマはページに埋め込まれて公開される。投稿通知時にSMTPでメール送信。

**権限による制御**：テーマ管理権限（secondAdmin.bTheme）を持つ管理者のみがアクセス可能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 78 | テーマ編集 | 主画面 | テーマの新規作成・編集・削除 |
| 77 | テーマ一覧 | 戻り先 | 一覧画面への遷移 |

## 機能種別

CRUD（Create: テーマ新規作成、Read: テーマ詳細取得、Update: テーマ編集、Delete: テーマ削除）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| iThemeId | String(暗号化) | No | テーマID（編集時） | 復号後に数値チェック |
| sName | String | Yes | テーマ名 | 最大255文字、必須 |
| sCode | String | No | 埋め込みコード | 最大45文字、重複不可 |
| iType | Integer | Yes | テーマ種別 | 必須 |
| iContactID | Integer | 条件付 | モデレーター/ブロガーID | ブログ時は必須 |
| bForwardPostsToModerator | Boolean | No | 投稿をモデレーターに転送 | - |
| bValidation | Boolean | No | 投稿の承認要否 | - |
| iSubLevel | Integer | No | 購読レベル | - |
| iSearchType | Integer | No | サイト検索への包含 | - |
| bOnline | Boolean | No | 公開状態 | - |
| bLocked | Boolean | No | テーマのロック | - |
| bAllowHTML | Boolean | No | HTML許可 | - |
| bUpload | Boolean | No | アップロード許可 | HTML許可時のみ |
| bEmbed | Boolean | No | 埋め込み許可 | HTML許可時のみ |
| bSmileys | Boolean | No | スマイリー使用 | - |
| bFileUploads | Boolean | No | ファイル添付許可 | - |
| bCompactList | Boolean | No | コンパクト表示 | - |
| iLimitTopicTo | Integer | No | トピック文字数制限 | 500-9000 |
| bAllowComments | Boolean | No | 返信許可 | - |
| bAllowAP | Boolean | No | 匿名返信許可 | 返信許可時のみ |
| sLabelYourName | String | 条件付 | 匿名時の名前ラベル | 匿名許可時は必須 |
| iLimitReplyTo | Integer | No | 返信文字数制限 | 150-3500 |
| iPageSize | Integer | No | 1ページあたりのトピック数 | 1-100 |
| sColorEven | String | No | 偶数行の背景色 | - |
| sColorUnEven | String | No | 奇数行の背景色 | - |
| iWidth | Integer | No | 表示幅 | 150-1500 |
| bPushRSS | Boolean | No | RSS配信 | タスク時は無効 |
| sTopicSubjectNotification | String | Yes | トピック通知メール件名 | 必須 |
| sTopicBodyNotification | String | Yes | トピック通知メール本文 | 必須 |
| sSubjectNotification | String | Yes | 返信通知メール件名 | 必須 |
| sBodyNotification | String | Yes | 返信通知メール本文 | 必須 |

### 入力データソース

- フォーム入力（全パラメータ）
- URLパラメータ（テーマID）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 編集フォーム | HTML | テーマ設定フォーム |
| 使用箇所一覧 | HTML | テーマが使用されているページ一覧 |

### 出力先

- 画面表示（編集フォーム）

## 処理フロー

### 処理シーケンス

```
1. 認証・権限チェック
   └─ テーマ管理権限の確認
2. テーマデータ取得（編集時）
   └─ IDからテーマ情報をPick
3. 保存処理（btnaction="save"）
   └─ CSRF検証 → バリデーション → 保存 → サブスクリプション整理
4. 削除処理（btnaction="delete"）
   └─ CSRF検証 → 関連データ削除 → テーマ削除 → 一覧へリダイレクト
5. 画面表示
   └─ 編集フォーム出力 → 使用箇所検索 → 結果表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{認証チェック}
    B -->|失敗| C[アクセス拒否]
    B -->|成功| D{btnaction?}
    D -->|save| E[CSRF検証]
    E --> F[フォーム値取得]
    F --> G{バリデーション}
    G -->|NG| H[エラー表示]
    G -->|OK| I[テーマ保存]
    I --> J[サブスクリプション整理]
    J --> K[成功メッセージ]
    D -->|delete| L[CSRF検証]
    L --> M[関連投稿削除]
    M --> N[テーマ削除]
    N --> O[一覧へリダイレクト]
    D -->|none| P[フォーム表示]
    H --> P
    K --> P
    P --> Q[使用箇所検索]
    Q --> R[終了]
    O --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-90-01 | CSRF検証 | 保存・削除時はCSRFトークン検証必須 | アクション実行時 |
| BR-90-02 | 名前必須 | テーマ名は必須入力 | 保存時 |
| BR-90-03 | 通知設定必須 | 通知メールの件名・本文は必須 | 保存時 |
| BR-90-04 | ブロガー必須 | パーソナルブログ時はブロガー指定必須 | iType=QS_theme_pb時 |
| BR-90-05 | コード重複不可 | 埋め込みコードはサイト内で一意 | コード指定時 |
| BR-90-06 | 匿名時ラベル必須 | 匿名返信許可時は名前ラベル必須 | bAllowAP=true時 |
| BR-90-07 | 削除確認 | 削除前に確認ダイアログ表示 | 削除ボタンクリック時 |
| BR-90-08 | 購読整理 | 購読レベル変更時に不要なサブスクリプション削除 | 保存時 |
| BR-90-09 | コメント削除 | 返信不許可設定時に既存返信を削除 | bAllowComments=false時 |
| BR-90-10 | タスク固定設定 | タスクシステムはiSubLevel固定、bPushRSS無効 | iType=QS_theme_ts時 |

### 計算ロジック

- 推奨幅：`recomWidth = iWidth`（デフォルト500px）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| テーマ取得 | tblTheme | SELECT | IDによるテーマ詳細取得 |
| テーマ作成 | tblTheme | INSERT | 新規テーマレコード作成 |
| テーマ更新 | tblTheme | UPDATE | テーマ情報更新 |
| テーマ削除 | tblTheme | DELETE | テーマレコード削除 |
| コード重複チェック | tblTheme | SELECT | 埋め込みコードの重複確認 |
| 購読削除 | tblThemeSubscription | DELETE | テーマ購読の削除 |
| トピック購読削除 | tblThemeTopicSubscription | DELETE | トピック購読の削除 |
| 投稿削除 | tblPost | DELETE | テーマに紐づく投稿削除 |
| ページ更新 | tblPage | UPDATE | テーマIDの解除 |

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

#### tblTheme

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | iCustomerID = cId AND iId = パラメータ値 | 詳細取得 |
| INSERT | 全カラム | フォーム入力値 | 新規作成 |
| UPDATE | 全カラム | フォーム入力値 | 編集 |
| DELETE | - | iId = パラメータ値 | 削除 |

#### tblThemeSubscription

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | iThemeID = テーマID | テーマ削除時/購読レベル変更時 |

#### tblThemeTopicSubscription

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | iPostId IN (テーマの投稿) | 購読レベル変更時 |

#### tblPost

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | iThemeID = テーマID AND iPostID is not null | コメント削除時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| err_mandatory | 必須エラー | 必須項目未入力 | エラーメッセージ表示 |
| err_doublefeed | 重複エラー | 埋め込みコード重複 | エラーメッセージ表示 |

### リトライ仕様

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

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

削除処理時、関連データ（投稿、購読）は個別に削除される（明示的なトランザクション制御なし）。

## パフォーマンス要件

特に明示的な要件なし。使用箇所検索（cls_fullSearch）は正規表現パターンマッチングで実行。

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

- 認証必須：`logon.hasaccess secondAdmin.bTheme`による権限チェック
- CSRF対策：`checkCSRF()`による検証（保存・削除時）、`QS_secCodeHidden`トークン
- 削除確認：confirm()ダイアログによる誤操作防止
- ID暗号化：`encrypt()`/`decrypt()`関数によるテーマIDの暗号化
- 入力値のサニタイズ：`quotRep()`によるクォート置換
- JS除去：`removeJS()`によるJavaScriptコード除去（HTML許可時、埋め込み不許可の場合）

## 備考

- テーマ種別（iType）：
  - QS_theme_cd: コミュニティディスカッション（フォーラム）
  - QS_theme_pb: パーソナルブログ
  - QS_theme_ts: タスクシステム
- 購読レベル（iSubLevel）：
  - QS_theme_sublevel_none: 購読なし
  - QS_theme_sublevel_authortopic: 投稿者のみ購読可
  - QS_theme_sublevel_topic: トピック購読可
  - QS_theme_sublevel_theme: テーマ全体購読可
- 通知メールの差し込みフィールド：
  - [QS_theme:postsubject]: 投稿件名
  - [QS_theme:Replyer]/[QS_theme:Poster]: 投稿者名
  - [QS_theme:reply]/[QS_theme:post]: 投稿内容
  - [QS_theme:postlink]: 投稿リンク
  - [QS_theme:Name]: テーマ名
- 保存後にRSSキャッシュをクリア
- FCKeditorを使用したリッチテキスト編集（通知メール本文）
- JQColorPickerによる色選択

---

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

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

### 推奨読解順序

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

テーマクラスのプロパティ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | theme.asp | `asp/includes/theme.asp` | cls_themeクラスのプロパティ（2-6行目） |

**読解のコツ**: プロパティは多数存在する。iType（種別）、iSubLevel（購読レベル）、bAllowHTML/bAllowComments（投稿ルール）が重要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bs_themeEdit.asp | `asp/bs_themeEdit.asp` | 編集画面と保存・削除処理 |

**主要処理フロー**:
1. **4行目**: 権限チェック（`secondAdmin.bTheme`）
2. **5-10行目**: ポストバック時のフォーム値取得
3. **11-22行目**: アクション分岐（save/delete）
4. **13-17行目**: 保存処理（checkCSRF、theme.save）
5. **18-21行目**: 削除処理（checkCSRF、theme.remove、リダイレクト）
6. **23-37行目**: 各種リスト取得（テーマ種別、コンタクト検索、購読レベル、検索種別）
7. **38-49行目**: 使用箇所検索（cls_fullSearch）

#### Step 3: テーマクラスの各メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | theme.asp | `asp/includes/theme.asp` | Pick, Check, Save, remove, getRequestValuesメソッド |

**主要処理フロー**:
- **58-98行目**: `Pick`関数 - IDからテーマデータ取得
- **99-134行目**: `Check`関数 - バリデーション
  - 101-104: 名前必須チェック
  - 105-112: 通知設定必須チェック
  - 113-118: 匿名時ラベル必須チェック
  - 119-124: ブログ時ブロガー必須チェック
  - 125-133: コード重複チェック
- **135-218行目**: `Save`関数 - テーマ保存
  - 142-184: tblThemeへの保存
  - 186-208: 購読レベル変更時のサブスクリプション整理
  - 209-213: コメント不許可時の返信削除
  - 214-217: RSSキャッシュクリア、テーマキャッシュ更新
- **232-263行目**: `getRequestValues`関数 - フォーム値取得
- **264-280行目**: `remove`関数 - テーマ削除

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

```
bs_themeEdit.asp（エントリーポイント）
    │
    ├─ begin.asp（共通初期化）
    │
    ├─ bs_security.asp（認証チェック）
    │      └─ logon.hasaccess（権限検証）
    │
    ├─ cls_theme（テーマクラス）
    │      ├─ pick()（データ取得）
    │      ├─ getRequestValues()（フォーム値取得）
    │      ├─ check()（バリデーション）
    │      ├─ save()（保存処理）
    │      │      ├─ tblTheme INSERT/UPDATE
    │      │      ├─ tblThemeSubscription DELETE
    │      │      ├─ tblThemeTopicSubscription DELETE
    │      │      ├─ tblPost DELETE（コメント）
    │      │      └─ clearRSScache()
    │      │             └─ cls_page.clearRSScache()
    │      └─ remove()（削除処理）
    │             ├─ cls_post.remove()（投稿削除）
    │             ├─ tblPage UPDATE
    │             ├─ tblThemeSubscription DELETE
    │             └─ tblTheme DELETE
    │
    ├─ cls_themeTypeList（テーマ種別リスト）
    │
    ├─ cls_contactSearch（コンタクト検索）
    │
    ├─ cls_theme_sublevelList（購読レベルリスト）
    │
    ├─ cls_siteSearchTypeList（サイト検索種別リスト）
    │
    └─ cls_fullSearch（使用箇所検索）
```

### データフロー図

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

フォーム入力 ───▶ getRequestValues()
                        │
                        ▼
                  check()（バリデーション）
                        │
                        ├─ 名前必須チェック
                        ├─ 通知設定必須チェック
                        ├─ コード重複チェック
                        └─ 条件付き必須チェック
                              │
                        ┌─────┴─────┐
                        │NG        │OK
                        ▼          ▼
                  エラー表示    save()
                                  │
                                  ├─ tblTheme保存
                                  ├─ サブスクリプション整理
                                  ├─ コメント削除（条件付き）
                                  └─ キャッシュクリア
                                        │
                                        ▼
                                  成功メッセージ

削除ボタン ─────▶ remove()
                        │
                        ├─ 投稿削除（posts.remove）
                        ├─ tblPage更新
                        ├─ tblThemeSubscription削除
                        └─ tblTheme削除
                              │
                              ▼
                        一覧へリダイレクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| bs_themeEdit.asp | `asp/bs_themeEdit.asp` | ソース | テーマ編集画面 |
| bs_themesList.asp | `asp/bs_themesList.asp` | ソース | テーマ一覧画面 |
| theme.asp | `asp/includes/theme.asp` | ソース | cls_themeクラス定義 |
| post.asp | `asp/includes/post.asp` | ソース | cls_postクラス定義 |
| begin.asp | `asp/begin.asp` | ソース | 共通初期化処理 |
| bs_security.asp | `asp/bs_security.asp` | ソース | 認証・権限チェック |
| urlenCodeJS.asp | `asp/includes/urlenCodeJS.asp` | ソース | URLエンコード用JS |
