# 機能設計書 9-ページ作成・編集

## 概要

本ドキュメントは、QuickerSite CMSのページ作成・編集機能について記述する。

### 本機能の処理概要

本機能は、新規ページの作成および既存ページのコンテンツ編集を行うための機能を提供する。WYSIWYGエディタを使用してページ本文を編集でき、タイトル、URL、SEO設定、テンプレート、表示設定など多岐にわたる属性を管理できる。

**業務上の目的・背景**：CMSの中核機能として、サイトコンテンツの作成と更新を可能にする。非技術者でもHTMLの知識なしにWebページを作成・編集できることが、CMSの最大の価値である。

**機能の利用シーン**：
- 新規コンテンツページの作成
- 既存ページの内容更新
- ページのSEO設定（個別キーワード・説明文）
- ページテンプレートの変更
- 表示期間の設定
- URLフレンドリーURLの設定
- フォーム・カタログとの連携設定

**主要な処理内容**：
1. ページタイプの選択（コンテンツページ、コンテナ、外部URL、リストページ、フリーページ）
2. ページタイトル・本文の編集
3. 表示設定（オンライン/オフライン、表示期間）
4. SEO設定（キーワード、説明文、SEOタイトル）
5. テンプレート・テーマの設定
6. URL設定（ユーザーフレンドリーURL、リダイレクト先）
7. フォーム・カタログ・フィードとの連携

**関連システム・外部連携**：なし

**権限による制御**：
- ページ作成: secondAdmin.bPagesAdd
- ページ本文編集: secondAdmin.bPageBody
- ホームページ設定: secondAdmin.bPageSetHomepage
- テンプレート設定: secondAdmin.bTemplates
- アプリケーション設定: secondAdmin.bApplicationpath
- フォーム設定: secondAdmin.bForms

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 13 | ページ編集 | 主画面 | ページ内容の編集 |
| 15 | ページタイプ選択 | 前画面 | 新規ページのタイプ選択 |
| 16 | コンテナ編集 | 関連画面 | コンテナページの編集 |
| 17 | 外部URL編集 | 関連画面 | 外部URLページの編集 |
| 18 | リストページ編集 | 関連画面 | リストページの編集 |

## 機能種別

CRUD操作 / コンテンツ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| sTitle | String | Yes | ページタイトル | 最大250文字、必須 |
| sValue | String | No | ページ本文（HTML） | 空の場合は他の要素が必要 |
| bOnline | Boolean | No | オンライン状態 | true/false |
| bHomepage | Boolean | No | ホームページフラグ | true/false |
| sCode | String | No | アプリケーションコード | 英数字、一意 |
| sUserFriendlyURL | String | No | ユーザーフレンドリーURL | 英数字・ハイフン、一意 |
| sKeywords | String | No | ページ固有キーワード | - |
| sDescription | String | No | ページ固有説明文 | - |
| sSEOtitle | String | No | SEO用タイトル | - |
| iTemplateID | Integer | No | テンプレートID | - |
| iThemeID | Integer | No | テーマID | - |
| dOnlineFrom | Date | No | 公開開始日時 | - |
| dOnlineUntill | Date | No | 公開終了日時 | - |
| sRedirectTo | String | No | リダイレクト先URL | - |
| iFormID | Integer | No | 連携フォームID | - |
| iCatalogId | Integer | No | 連携カタログID | - |
| iFeedId | Integer | No | 連携フィードID | - |
| sApplication | String | No | アプリケーションパス | - |

### 入力データソース

- 画面入力（編集フォーム）
- WYSIWYGエディタ（FCKEditor）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| page.iId | Integer | ページID |
| page.sTitle | String | ページタイトル |
| page.sValue | String | ページ本文（HTML） |
| page.sValueTextOnly | String | 本文のテキスト抽出版 |
| page.bOnline | Boolean | オンライン状態 |
| 他の属性 | 各種 | 入力パラメータに対応 |

### 出力先

- データベース（tblPage）
- アプリケーションキャッシュ（メニューキャッシュクリア）

## 処理フロー

### 処理シーケンス

```
1. ページ作成フロー
   └─ bs_setupPage.asp: ページタイプ選択
      └─ ページタイプに応じた編集画面へ遷移
         └─ sb_item: bs_editItem.asp（コンテンツページ）
         └─ sb_container: bs_editContainer.asp（コンテナ）
         └─ sb_externalURL: bs_editExternalURL.asp（外部URL）
         └─ sb_list: bs_editList.asp（リストページ）
         └─ sb_lossePagina: bs_editItem.asp（フリーページ）

2. ページ編集フロー
   └─ 既存ページIDで編集画面へ直接アクセス
   └─ 現在のページ情報を取得・表示

3. 保存処理（btnaction="save"）
   └─ CSRF検証
   └─ page.getRequestValues()でフォーム値取得
   └─ page.check()でバリデーション
   └─ page.save()でデータベース保存
   └─ メニューキャッシュクリア
```

### フローチャート

```mermaid
flowchart TD
    A[ページ作成/編集] --> B{新規 or 編集?}
    B -->|新規| C[bs_setupPage.asp]
    C --> D[ページタイプ選択]
    D --> E[編集画面へ遷移]
    B -->|編集| E
    E --> F[編集フォーム表示]
    F --> G{保存ボタン押下}
    G -->|No| F
    G -->|Yes| H[CSRF検証]
    H --> I[getRequestValues]
    I --> J[check - バリデーション]
    J --> K{バリデーションOK?}
    K -->|No| L[エラー表示]
    L --> F
    K -->|Yes| M[save]
    M --> N{ホームページ?}
    N -->|Yes| O[他ページのホームページフラグ解除]
    N -->|No| P[メニューキャッシュクリア]
    O --> P
    P --> Q[成功メッセージ表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | タイトル必須 | ページタイトルは必須 | 常時 |
| BR-02 | コンテンツ必須 | 本文が空の場合、外部URLまたはアプリ連携が必要 | 非コンテナ・非メニューグループ |
| BR-03 | コード一意 | sCodeはサイト内で一意 | sCode設定時 |
| BR-04 | UFL一意 | sUserFriendlyURLはサイト内で一意 | UFL設定時 |
| BR-05 | UFL英数字 | UFL英数字・ハイフンのみ | UFL設定時 |
| BR-06 | ホームページ単一 | ホームページは1つのみ、設定時に他を解除 | ホームページ設定時 |
| BR-07 | パスワード継承 | 親ページのパスワードを継承 | 新規作成時 |
| BR-08 | イントラネット継承 | 親がイントラネットならイントラネット | 新規作成時 |
| BR-09 | オフライン伝播 | 親をオフラインにすると子もオフライン | 親オフライン時 |
| BR-10 | カタログ・フォーム排他 | カタログとフォームは同時に設定不可 | 設定時 |

### 計算ロジック

- UFL自動生成: `replace(sTitle, " ", "-")` + 特殊文字除去 + 小文字化
- テキスト抽出: `RemoveHTML(treatConstants(sValue))` でHTML除去
- 表示順: 新規作成時は `getRang+1` で末尾に追加

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ページ取得 | tblPage | SELECT | 既存ページ情報取得 |
| ページ作成 | tblPage | INSERT | 新規ページ作成 |
| ページ更新 | tblPage | UPDATE | ページ情報更新 |
| ホームページ解除 | tblPage | UPDATE | 他ページのbHomepage=false |
| コード重複チェック | tblPage | SELECT | sCodeの一意性確認 |
| UFL重複チェック | tblPage | SELECT | sUserFriendlyURLの一意性確認 |

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

#### tblPage

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | sTitle | 入力値（最大250文字） | タイトル |
| INSERT/UPDATE | sValue | 入力値（HTML） | 本文 |
| INSERT/UPDATE | sValueTextOnly | RemoveHTML(sValue) | テキスト版本文 |
| INSERT/UPDATE | bOnline | true/false | オンライン状態 |
| INSERT/UPDATE | bHomepage | true/false | ホームページフラグ |
| INSERT/UPDATE | sUserFriendlyURL | 入力値または自動生成 | UFL |
| INSERT/UPDATE | sKeywords | 入力値 | SEOキーワード |
| INSERT/UPDATE | sDescription | 入力値 | SEO説明文 |
| INSERT/UPDATE | iTemplateID | 選択値 | テンプレートID |
| INSERT/UPDATE | iRang | 計算値 | 表示順序 |
| INSERT | createdTS | now() | 作成日時 |
| UPDATE | updatedTS | now() | 更新日時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| err_mandatory | 入力エラー | タイトルが空、またはコンテンツと必須要素がすべて空 | 必須項目を入力 |
| err_appCode | 入力エラー | sCodeが重複 | 別のコードを設定 |
| err_ufl | 入力エラー | sUserFriendlyURLが重複 | 別のUFLを設定 |
| err_ufl_an | 入力エラー | sUserFriendlyURLに不正文字 | 英数字・ハイフンのみ使用 |
| err_catorform | 入力エラー | カタログとフォームを同時設定 | どちらか一方のみ設定 |
| err_listpagepurl | 入力エラー | リストページ外部URLと本文の両方を設定 | どちらか一方のみ設定 |

### リトライ仕様

- エラー時は同一画面で再入力可能
- 入力値は保持される

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

- 保存処理: 単一トランザクションで完結
- ホームページ設定時: メインページ更新後に他ページのフラグ更新

## パフォーマンス要件

- ページ保存: 即座に完了
- メニューキャッシュクリア: 保存後に自動実行

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

- CSRF対策トークン検証
- 各操作に対する権限チェック（secondAdmin.*）
- ページIDの暗号化（EnCrypt/DeCrypt）
- WYSIWYGエディタでのスクリプト実行制限

## 備考

- WYSIWYGエディタとしてFCKEditor（またはCKEditor）を使用
- ページ削除は別機能（No.10）として扱う
- イントラネットページは親ページの設定を継承
- フリーページは階層構造に属さない独立ページ

---

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

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

### 推奨読解順序

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

ページのデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | page.asp | `asp/includes/page.asp` | cls_pageクラスのプロパティ定義（4-11行目） |

**読解のコツ**: cls_pageクラスの主要プロパティ:
- `sTitle`: ページタイトル
- `sValue`: ページ本文（HTML）
- `sValueTextOnly`: 本文のテキスト抽出版
- `bOnline`: オンライン状態
- `bHomepage`: ホームページフラグ
- `sUserFriendlyURL`: ユーザーフレンドリーURL
- `sKeywords`, `sDescription`: SEO設定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bs_setupPage.asp | `asp/bs_setupPage.asp` | ページタイプ選択画面（14行） |
| 2-2 | bs_editItem.asp | `asp/bs_editItem.asp` | コンテンツページ編集画面（17行） |

**bs_setupPage.asp 主要処理フロー**:
1. **4行目**: secondAdmin.bPagesAdd権限チェック
2. **5-6行目**: ページタイプリスト取得
3. **9-12行目**: タイプ選択ラジオボタン生成

**bs_editItem.asp 主要処理フロー**:
1. **4行目**: bs_processPage.aspインクルード（保存処理）
2. **4行目**: フォーム表示（タイトル、本文等）
3. **13行目**: FCKEditor（WYSIWYGエディタ）生成

#### Step 3: 保存処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | bs_processPage.asp | `asp/bs_processPage.asp` | ページ保存処理（83行） |

**主要処理フロー**:
- **11-25行目**: btnaction="save"処理
- **13行目**: checkCSRF()
- **14行目**: page.getRequestValues()
- **15行目**: page.save()

#### Step 4: バリデーションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | page.asp | `asp/includes/page.asp` | check関数（337-423行目） |

**主要バリデーション**:
- **343-346行目**: タイトル必須チェック
- **352-362行目**: コンテンツ必須チェック
- **364-371行目**: sCode一意性チェック
- **384-412行目**: sUserFriendlyURL検証
- **419-422行目**: カタログ・フォーム排他チェック

#### Step 5: 保存ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | page.asp | `asp/includes/page.asp` | save関数（424-599行目） |

**主要処理フロー**:
- **434-437行目**: ホームページ設定時の処理
- **438-443行目**: パスワード継承
- **467-480行目**: INSERT/UPDATE判定
- **484-569行目**: 各カラムの値設定
- **576-585行目**: ホームページフラグの排他処理
- **596-597行目**: メニューキャッシュクリア

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

```
bs_setupPage.asp（新規作成時）
    │
    ├─ secondAdmin.bPagesAdd権限チェック
    │
    └─ ページタイプ選択
           │
           └─ bs_editItem.asp（コンテンツページ）
              bs_editContainer.asp（コンテナ）
              bs_editExternalURL.asp（外部URL）
              bs_editList.asp（リストページ）

bs_editItem.asp（編集時）
    │
    ├─ begin.asp（インクルード）
    │      └─ includes/page.asp（cls_pageクラス）
    │
    ├─ bs_security.asp（認証チェック）
    │
    ├─ bs_processPage.asp（保存処理）
    │      │
    │      └─ btnaction = "save"
    │             ├─ checkCSRF()
    │             ├─ page.getRequestValues()
    │             └─ page.save()
    │                    ├─ check()（バリデーション）
    │                    ├─ INSERT/UPDATE実行
    │                    ├─ ホームページ排他処理
    │                    └─ clearMenuCache()
    │
    ├─ bs_common.asp（共通フォーム要素）
    │
    ├─ FCKEditor（WYSIWYGエディタ）
    │
    └─ フォーム表示
```

### データフロー図

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

フォーム入力 ────▶ getRequestValues()
                        │
                        ▼
                   check()
                   (バリデーション)
                        │
               ┌────────┴────────┐
               ▼                 ▼
         エラーあり          エラーなし
               │                 │
               ▼                 ▼
         エラー表示          save()
                                 │
                        ┌────────┴────────┐
                        ▼                 ▼
                    新規作成           既存更新
                    (INSERT)          (UPDATE)
                        │                 │
                        └────────┬────────┘
                                 │
                                 ▼
                           tblPage
                                 │
                        ┌────────┴────────┐
                        ▼                 ▼
               ホームページ設定      オフライン設定
               (他を解除)           (子も連動)
                        │                 │
                        └────────┬────────┘
                                 │
                                 ▼
                        clearMenuCache()
                                 │
                                 ▼
                        成功メッセージ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| bs_setupPage.asp | `asp/bs_setupPage.asp` | ソース | ページタイプ選択画面 |
| bs_editItem.asp | `asp/bs_editItem.asp` | ソース | コンテンツページ編集画面 |
| bs_editContainer.asp | `asp/bs_editContainer.asp` | ソース | コンテナページ編集画面 |
| bs_editExternalURL.asp | `asp/bs_editExternalURL.asp` | ソース | 外部URL編集画面 |
| bs_editList.asp | `asp/bs_editList.asp` | ソース | リストページ編集画面 |
| bs_processPage.asp | `asp/bs_processPage.asp` | ソース | ページ保存処理 |
| page.asp | `asp/includes/page.asp` | ソース | cls_pageクラス定義 |
| bs_common.asp | `asp/bs_common.asp` | ソース | 共通フォーム要素 |
| bs_security.asp | `asp/bs_security.asp` | ソース | 認証・権限チェック |
| secondAdmin.asp | `asp/includes/secondAdmin.asp` | ソース | 権限定義 |
