# 機能設計書 12-ページ新規作成

## 概要

本ドキュメントは、LEGACY CMSにおける新規固定ページの作成機能について記述する。この機能は管理画面のAjaxダイアログを通じて、新しい固定ページをドラフト状態で作成し、その後の編集画面へ遷移させる。

### 本機能の処理概要

**業務上の目的・背景**：ウェブサイトに新しい固定ページ（会社概要、利用規約、キャンペーン告知ページなど）を追加する際、まず基本情報（タイトル）のみで下書きを作成し、詳細なコンテンツは編集画面で入力するワークフローを実現する。これにより、ページ作成の敷居を下げ、段階的なコンテンツ作成を可能にしている。

**機能の利用シーン**：管理者がページ管理画面で「New Page」ボタンをクリックした際にダイアログが表示され、ページタイトルを入力して作成を実行する。作成後は自動的に編集画面へ遷移し、本文やURL等の詳細設定を行う。

**主要な処理内容**：
1. ユーザーの権限チェック（ppages + ppagenew権限の確認）
2. Ajaxダイアログでのフォーム表示（GETリクエスト時）
3. POSTリクエスト時のバリデーション（タイトル必須チェック）
4. Pagesモデルを使用した新規レコード挿入
5. 作成完了後、編集画面へのリダイレクト用UIの表示

**関連システム・外部連携**：特になし。内部データベースへの挿入処理のみ。

**権限による制御**：`ppages`および`ppagenew`リソースへのアクセス権限が必要。権限がない場合は権限エラー画面（privileges）へフォワードされる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 62 | ページ新規作成画面 | 主画面 | 新規ページ作成ダイアログ |
| 60 | ページ管理画面 | 呼び出し元画面 | 新規作成ボタンからダイアログ呼び出し |
| 61 | ページ編集画面 | 遷移先画面 | 作成完了後の編集画面への遷移 |

## 機能種別

CRUD操作（Create）/ データ新規作成 / Ajaxダイアログ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pagetitle | string | Yes | ページタイトル | NotEmpty（空でないこと） |

### 入力データソース

- POSTリクエストボディ（フォームデータ）
- セッション（ログインユーザー情報、ACL情報）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| posted | string | フォーム投稿状態（'N'=未投稿/バリデーションエラー） |
| messages | array | バリデーションエラーメッセージ |
| pagetitle | string | 入力されたタイトル（エラー時の再表示用） |

### 作成されるページデータ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| page_title | string | 入力されたタイトル |
| page_user | integer | 作成者のユーザーID |
| page_date | datetime | 作成日時（NOW()） |
| page_edit | datetime | 最終編集日時（NOW()） |
| page_status | string | デフォルト値 'draft' |

### 出力先

- Ajaxダイアログ内のHTML（成功時：Continueボタン、エラー時：フォーム再表示）
- pagesテーブルへの新規レコード挿入

## 処理フロー

### 処理シーケンス

```
1. newAction()が呼び出される（Ajaxダイアログ経由）
   └─ レイアウト無効化

2. 権限チェック
   ├─ ppages権限チェック
   └─ ppagenew権限チェック
      ├─ 権限なし → privileges画面へフォワード
      └─ 権限あり → 次のステップへ

3. リクエスト種別の判定
   ├─ GETリクエスト → フォーム表示（posted='N'）
   └─ POSTリクエスト → バリデーション処理へ

4. バリデーション処理（POSTの場合）
   └─ Zend_Filter_Inputによる入力検証
      ├─ pagetitle: NotEmpty必須チェック
      ├─ バリデーション失敗 → エラーメッセージ設定、フォーム再表示
      └─ バリデーション成功 → 次のステップへ

5. ページ作成処理
   └─ Pages::newPage()
      ├─ INSERT文の構築
      └─ pagesテーブルへ挿入

6. 結果表示
   └─ 成功メッセージとContinueボタン表示
      └─ Continueクリックで編集画面へ遷移
```

### フローチャート

```mermaid
flowchart TD
    A[開始: newAction] --> B[レイアウト無効化]
    B --> C{ppages+ppagenew権限あり?}
    C -->|No| D[privileges画面へフォワード]
    C -->|Yes| E{POSTリクエスト?}
    E -->|No| F[フォーム表示 posted=N]
    E -->|Yes| G[Zend_Filter_Inputでバリデーション]
    G --> H{バリデーション成功?}
    H -->|No| I[エラーメッセージ設定]
    I --> F
    H -->|Yes| J[Pages::newPage実行]
    J --> K[DB INSERT]
    K --> L[lastInsertId取得]
    L --> M[成功メッセージ+Continueボタン表示]
    M --> N[終了]
    F --> N
    D --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 初期ステータス | 新規作成時はドラフト状態で作成 | 常時 |
| BR-02 | 作成者記録 | ログインユーザーを作成者として記録 | 常時 |
| BR-03 | タイムスタンプ | 作成日時と最終編集日時を現在時刻で設定 | 常時 |
| BR-04 | タイトル必須 | タイトルは空でないことが必須 | 常時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ページ新規作成 | pages | INSERT | 新規ページレコード挿入 |

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

#### pagesテーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | page_title | 入力されたタイトル | 必須 |
| INSERT | page_user | ログインユーザーID | 自動設定 |
| INSERT | page_date | NOW() | 自動設定 |
| INSERT | page_edit | NOW() | 自動設定 |
| INSERT | page_status | 'draft' | デフォルト値（テーブル定義） |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 権限エラー | ppages/ppagenew権限なし | privileges画面へフォワード |
| IS_EMPTY | バリデーションエラー | タイトルが空 | "Title is required"メッセージ表示 |

### リトライ仕様

特になし（ユーザーがフォームを再入力して再送信）

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

単一INSERT操作のため、明示的なトランザクション管理は行っていない。データベースアダプタのauto-commitに依存。

## パフォーマンス要件

- 単一レコードのINSERT操作のため、特別なパフォーマンス要件なし
- Ajaxダイアログでの非同期処理により、ユーザー体験を向上

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

- ACLによる権限チェック（ppages + ppagenewリソース）
- Zend_Filter_Inputによる入力バリデーション
- XSS対策：ビューでのエスケープ処理
- CSRF対策：Ajaxダイアログ内でのPOST送信（ただし明示的なトークンチェックは未実装）

## 備考

- ダイアログ表示のためレイアウトを無効化
- Dojo ToolkitのdijitウィジェットによるフォームUI
- 作成成功後はJavaScript関数`goTo()`で編集画面へ遷移

---

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

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

### 推奨読解順序

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

pagesテーブルの構造と、INSERT時に設定されるカラムを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | database.sql | `database.sql` | pagesテーブル定義（206-220行目）、特にDEFAULT値に注目 |
| 1-2 | Pages.php | `application/models/Pages.php` | newPage()メソッドの実装（166-181行目） |

**読解のコツ**: `page_status`のDEFAULT値が'draft'に設定されているため、INSERTで明示的に指定しなくてもドラフト状態になる。

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

コントローラーのnewActionを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | PagesController.php | `application/modules/admin/controllers/PagesController.php` | newAction()の実装（335-393行目） |

**主要処理フロー**:
1. **337行目**: ppages + ppagenew権限の複合チェック
2. **339行目**: レイアウト無効化（Ajaxダイアログ用）
3. **341行目**: POSTリクエストの判定
4. **347-352行目**: バリデータ定義（pagetitle必須）
5. **355行目**: Zend_Filter_Inputによるバリデーション実行
6. **357行目**: バリデーション成功判定
7. **359-362行目**: Pages::newPage()呼び出しとDB挿入
8. **368行目**: lastInsertId()で挿入されたIDを取得
9. **364-369行目**: 成功メッセージとContinueボタンの出力

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

Pagesモデルのnewpage処理を詳細に確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Pages.php | `application/models/Pages.php` | newPage()メソッド（166-181行目） |

**主要処理フロー**:
- **168行目**: パラメータの存在確認とバリデーション
- **170-175行目**: INSERT用データ配列の構築
- **177行目**: $this->registry->db->insert()でDB挿入

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

ダイアログ内のフォームUIを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | new.phtml | `application/modules/admin/views/scripts/pages/new.phtml` | 新規作成フォームのテンプレート |

**主要処理フロー**:
- **9行目**: posted='N'の場合のみフォーム表示
- **10行目**: エラーメッセージのレンダリング
- **11-41行目**: Dojo dijitを使用したフォーム定義
- **14-24行目**: ValidationTextBoxによるタイトル入力欄
- **28-33行目**: Createボタンの定義、doDialog()関数呼び出し

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

```
manage.phtml [New Pageボタンクリック]
    │
    └─ getDialog('/admin/pages/new/','New Page')
           │
           └─ PagesController::newAction()
                  │
                  ├─ ACL::isAllowed() [権限チェック x2]
                  │
                  ├─ [GETの場合] new.phtml表示
                  │
                  └─ [POSTの場合]
                         │
                         ├─ Zend_Filter_Input [バリデーション]
                         │
                         └─ Pages::newPage()
                                │
                                └─ Zend_Db::insert() [DB挿入]
                                       │
                                       └─ lastInsertId() [ID取得]
                                              │
                                              └─ Continueボタン表示
                                                     │
                                                     └─ goTo('/admin/pages/edit/id/{id}')
```

### データフロー図

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

ダイアログ表示要求 ───▶ newAction (GET)          ───▶ new.phtml
                         └─ レイアウト無効化             └─ フォーム表示

                                    │
                                    ▼

フォーム送信         ───▶ newAction (POST)        ───▶
(pagetitle)               ├─ 権限チェック               ├─ [成功] 成功メッセージ
                          ├─ バリデーション             │         + Continueボタン
                          └─ Pages::newPage()          │
                                    │                   └─ [失敗] フォーム再表示
                                    ▼                            + エラーメッセージ
                          pagesテーブル
                          INSERT INTO pages
                          (page_title, page_user,
                           page_date, page_edit)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| PagesController.php | `application/modules/admin/controllers/PagesController.php` | コントローラー | newActionの実装 |
| Pages.php | `application/models/Pages.php` | モデル | newPage()メソッド |
| new.phtml | `application/modules/admin/views/scripts/pages/new.phtml` | ビュー | 新規作成フォーム |
| manage.phtml | `application/modules/admin/views/scripts/pages/manage.phtml` | ビュー | New Pageボタン配置 |
| common.js | `public/_scripts/admin/common.js` | JavaScript | getDialog(), doDialog()関数 |
| database.sql | `database.sql` | スキーマ | pagesテーブル定義 |
