# 画面設計書 63-ページ詳細画面

## 概要

本ドキュメントは、Legacy CMSの管理画面における「ページ詳細画面」の設計仕様を定義するものである。この画面はページ編集画面内にAjax経由で読み込まれるパーシャルビューであり、ページの詳細情報と操作ボタンを表示する。

### 本画面の処理概要

**業務上の目的・背景**：ページ編集画面において、ユーザーがページの現在の状態（著者、ステータス、各種日時）を一目で確認できるようにするとともに、保存・削除・公開などの主要な操作ボタンを提供する。この情報パネルにより、編集作業中でもページの基本情報を常に把握でき、適切なタイミングで操作を実行できる。また、Ajax経由で読み込まれるため、編集画面の初期表示を高速化しつつ、必要な情報を非同期で取得する設計となっている。

**画面へのアクセス方法**：ページ編集画面（/admin/pages/edit/id/{page_id}/）の読み込み時に、ContentPaneウィジェットにより `/admin/pages/details?id={page_id}` からAjax経由で自動的に読み込まれる。直接URLアクセスも技術的には可能だが、レイアウトなしの部分的なHTMLが返されるため、通常は編集画面経由でのみ使用される。

**主要な操作・処理内容**：
1. ページの著者名、ステータス、作成日時、公開日時、最終編集日時の表示
2. 「Save」ボタンによるページ保存処理の実行
3. 「Delete」ボタンによるページ削除処理の実行（保護されていないページのみ）
4. 「Publish」ボタンによるページ公開処理の実行（下書き状態のみ）
5. 「Pages...」ボタンによるページ管理画面への遷移

**画面遷移**：本画面自体は遷移元/遷移先を持たないパーシャルビューである。保存・削除・公開ボタンはAjaxダイアログを表示し、「Pages...」ボタンはページ管理画面へリダイレクトする。

**権限による表示制御**：`ppages`権限と`ppageedit`権限が必要。保護されたページ（page_protected = 'Y'）の場合は「Delete」ボタンが非表示となる。下書き状態でない場合は「Publish」ボタンが非表示となる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | ページ一覧表示 | 主機能 | ページの詳細情報を表示 |
| 44 | コメント一覧表示 | 補助機能 | ページのコメントを表示 |
| 49 | タグ一覧表示 | 補助機能 | ページのタグを表示 |
| 54 | 添付ファイル一覧表示 | 補助機能 | ページの添付ファイルを表示 |

## 画面種別

詳細（パーシャルビュー/Ajax読み込み）

## URL/ルーティング

- URL: `/admin/pages/details?id={page_id}`
- モジュール: admin
- コントローラー: PagesController
- アクション: detailsAction

## 入出力項目

本画面はGETパラメータのみを受け取り、表示専用である。

| 項目名 | 項目ID | データ型 | 必須 | 入力形式 | 備考 |
|--------|--------|----------|------|----------|------|
| ページID | id | integer | Yes | URLパラメータ | 表示対象のページを指定 |

## 表示項目

| 項目名 | データソース | 表示形式 | 備考 |
|--------|--------------|----------|------|
| 著者名 | users.user_alias | テキスト | "Author: {著者名}" |
| ステータス | pages.page_status | テキスト | ucwords()で整形、"Status: {ステータス}" |
| 作成日時 | pages.page_date | d/m/Y H:i | "Created: {日時}" |
| 公開日時 | pages.page_published | d/m/Y H:i | 公開済みの場合のみ表示、"Published: {日時}" |
| 最終編集日時 | pages.page_edit | d/m/Y H:i | "Last Edited: {日時}" |

## イベント仕様

### 1-Saveボタン押下

FCKeditorの内容を更新した後、postDialog()関数を使用して `/admin/pages/save/id/{page_id}/` にPOSTリクエストを送信する。editFormの内容がフォームデータとして送信され、結果はAjaxダイアログに表示される。

### 2-Deleteボタン押下

保護されていないページの場合のみ表示される。getDialog()関数を使用して `/admin/pages/delete/id/{page_id}/` を呼び出し、削除確認ダイアログを表示する。

### 3-Publishボタン押下

下書き状態（page_status != 'published'）の場合のみ表示される。FCKeditorの内容を更新した後、getDialog()関数を使用して `/admin/pages/publish/id/{page_id}/` を呼び出し、公開確認ダイアログを表示する。

### 4-Pages...ボタン押下

goTo()関数を使用して `/admin/pages/` にリダイレクトする。ページ管理画面に戻る。

## データベース更新仕様

本画面は表示専用であり、直接的なデータベース更新は行わない。ボタン押下時に呼び出される各アクション（save, delete, publish）でデータベース更新が行われる。

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Saveボタン押下 | pages | - | saveActionへ遷移（本画面では更新しない） |
| Deleteボタン押下 | pages | - | deleteActionへ遷移（本画面では更新しない） |
| Publishボタン押下 | pages | - | publishActionへ遷移（本画面では更新しない） |

### テーブル別更新項目詳細

本画面ではデータベース更新は行わない。detailsAction()はSELECTのみを実行する。

#### pages（SELECT）

| 操作 | 項目（カラム名） | 取得条件 | 備考 |
|-----|-----------------|----------|------|
| SELECT | page_id | WHERE page_id = {id} | 主キー |
| SELECT | page_status | - | 表示用 |
| SELECT | page_date | - | 作成日時 |
| SELECT | page_published | - | 公開日時 |
| SELECT | page_edit | - | 最終編集日時 |
| SELECT | page_protected | - | 削除ボタン表示制御用 |

## メッセージ仕様

本画面自体はメッセージを表示しない。ボタン押下時に呼び出される各アクションでメッセージが表示される。

## 例外処理

| 例外状態 | 対応処理 |
|----------|----------|
| ページIDが未指定または無効 | 空のレスポンスを返す（エラー画面は表示しない） |
| 該当ページが存在しない | 空のレスポンスを返す |
| 権限不足（ppagesまたはppageedit権限なし） | 権限エラー画面へフォワード |

## 備考

- 本画面はページ編集画面（edit.phtml）のContentPaneウィジェットに読み込まれるパーシャルビューである
- レイアウトは無効化されており（disableLayout）、本画面のHTMLのみが返される
- FCKeditorの更新はMyFCKObject.UpdateEditorFormValue()で行われるが、この処理は本画面ではなく編集画面側で定義されている
- 日時表示にはビューヘルパーMakeDate()を使用している

---

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

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

### 推奨読解順序

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

詳細画面で表示されるページデータの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Pages.php | `application/models/Pages.php` | fetchPage()メソッドで取得されるカラムを確認 |

**読解のコツ**: fetchPage()はpagesテーブルとusersテーブルをJOINしており、user_aliasも取得している点に注意。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | PagesController.php | `application/modules/admin/controllers/PagesController.php` | detailsAction()メソッド（313-330行目）が処理の起点 |

**主要処理フロー**:
1. **315行目**: 権限チェック（ppagesとppageedit）
2. **317行目**: レイアウトを無効化（Ajax読み込み用）
3. **319行目**: URLパラメータからページIDを取得
4. **321-323行目**: Pagesモデルを使用してページデータを取得
5. ビューに$pageArrayを渡してレンダリング

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

Ajax読み込みされるビューファイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | details.phtml | `application/modules/admin/views/scripts/pages/details.phtml` | 詳細情報の表示とボタンの配置 |

**主要処理フロー**:
- **9-23行目**: 左カラム - 詳細情報（著者、ステータス、日時）
- **14行目**: 著者名の表示
- **15行目**: ステータスの表示（ucwords()で整形）
- **17行目**: 作成日時の表示
- **18-20行目**: 公開日時の条件付き表示
- **21行目**: 最終編集日時の表示
- **27-41行目**: 右カラム - 機能ボタン
- **31行目**: Saveボタン
- **32-34行目**: Deleteボタン（保護されていない場合のみ）
- **35-37行目**: Publishボタン（下書き状態の場合のみ）
- **38行目**: Pages...ボタン

#### Step 4: 親画面との連携を理解する

詳細画面が読み込まれる親画面を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | edit.phtml | `application/modules/admin/views/scripts/pages/edit.phtml` | ContentPaneによるAjax読み込み（39行目） |

**主要処理フロー**:
- **39行目**: ContentPaneウィジェットのhref属性で詳細画面のURLを指定
- preload="true"により、編集画面の読み込み時に自動的に詳細画面を取得

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

```
edit.phtml [親画面]
    │
    └─ ContentPane [dijit.layout.ContentPane]
           │
           └─ Ajax Request: /admin/pages/details?id={page_id}
                  │
                  ▼
           detailsAction() [PagesController.php:313]
                  │
                  ├─ acl->isAllowed() [権限チェック]
                  │
                  ├─ _helper->layout->disableLayout() [レイアウト無効化]
                  │
                  └─ Pages->fetchPage() [Pages.php:146]
                         │
                         └─ registry->db->fetchall() [DB検索]
                                │
                                ▼
                         View rendering [details.phtml]

[ボタン押下時]
Save ────▶ postDialog() ────▶ /admin/pages/save/
Delete ──▶ getDialog() ─────▶ /admin/pages/delete/
Publish ─▶ getDialog() ─────▶ /admin/pages/publish/
Pages... ▶ goTo() ──────────▶ /admin/pages/
```

### データフロー図

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

URLパラメータ ─────────▶ PagesController ─────────▶ HTMLレスポンス
(id={page_id})           detailsAction()              (パーシャルビュー)
                              │
                              │
                              ▼
                         Pages->fetchPage()
                              │
                              ├──────────▶ pagesテーブル
                              │            (SELECT)
                              │
                              └──────────▶ usersテーブル
                                           (JOIN - 著者名取得)
                                                │
                                                ▼
                                           details.phtml
                                           (HTML生成)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| PagesController.php | `application/modules/admin/controllers/PagesController.php` | ソース | ページ管理のコントローラー |
| Pages.php | `application/models/Pages.php` | ソース | ページデータのモデル |
| details.phtml | `application/modules/admin/views/scripts/pages/details.phtml` | テンプレート | 詳細画面のビュー |
| edit.phtml | `application/modules/admin/views/scripts/pages/edit.phtml` | テンプレート | 編集画面（親画面） |
| common.js | `public/_scripts/admin/common.js` | JavaScript | postDialog(), getDialog(), goTo()等の共通関数 |
| template.css | `public/_styles/admin/template.css` | スタイル | 管理画面共通スタイル |
