# 画面設計書 3-プロファイラー検索

## 概要

本ドキュメントは、Symfony WebProfilerBundleが提供する「プロファイラー検索」画面の設計書である。本画面はプロファイラーの検索処理を実行し、検索条件をセッションに保存した上で検索結果画面またはプロファイラーパネルへリダイレクトする。

### 本画面の処理概要

本画面は、検索バー（No.4）から送信された検索条件を受け取り、検索処理を実行してリダイレクトを行う中間処理画面である。

**業務上の目的・背景**：開発者がプロファイリングデータを効率的に検索できるようにするための検索処理エンドポイントである。IP、HTTPメソッド、ステータスコード、URL、トークン、日付範囲、結果件数などの条件を受け取り、条件をセッションに保存して検索バーの値を維持しつつ、検索結果画面またはプロファイラーパネルへリダイレクトする。プロファイルタイプ（HTTPリクエスト/コンソールコマンド）ごとの検索もサポートする。

**画面へのアクセス方法**：プロファイラー検索バー（No.4）の検索フォームからGETメソッドで呼び出される。URLは`/_profiler/search`。

**主要な操作・処理内容**：
1. クエリパラメータから検索条件（ip, method, status_code, url, start, end, limit, token, type）を取得
2. セッションが利用可能な場合、検索条件をセッションに保存（検索バーの値の維持に使用）
3. トークンが直接指定されている場合、該当プロファイラーパネル画面へリダイレクト
4. トークン未指定の場合、Profiler::find()で検索を実行し、検索結果画面へリダイレクト
5. 検索結果がある場合は先頭トークンを使用、なければ`empty`トークンで検索結果画面へ遷移

**画面遷移**：
- 遷移元：プロファイラー検索バー（No.4）の検索フォーム
- 遷移先（トークン指定時）：プロファイラーパネル（No.2）
- 遷移先（トークン未指定時）：プロファイラー検索結果（No.5）

**権限による表示制御**：プロファイラーが有効な環境でのみ動作する。プロファイラーが無効な場合は404エラーが返される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | WebProfilerBundle | 主機能 | ProfilerController::searchActionによる検索実行とリダイレクト処理 |
| 3 | Routing | 主機能 | 検索条件を基にRouting（UrlGenerator）で検索結果画面へのリダイレクトURLを生成する |
| 2 | HttpKernel | 補助機能 | Profilerサービスによる検索条件に合致するプロファイルトークンの検索 |
| 1 | HttpFoundation | 補助機能 | Sessionへの検索条件の保存とRedirectResponseの生成 |

## 画面種別

リダイレクト（検索処理後にリダイレクト）

## URL/ルーティング

| 項目 | 値 |
|------|-----|
| ルート名 | `_profiler_search` |
| URLパターン | `/_profiler/search` |
| HTTPメソッド | GET |
| コントローラー | `web_profiler.controller.profiler::searchAction` |

## 入出力項目

### 入力（クエリパラメータ）

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| ip | 入力 | string | いいえ | 検索対象のIPアドレス（commandタイプの場合はApplication名） |
| method | 入力 | string | いいえ | HTTPメソッド（DELETE/GET/HEAD/PATCH/POST/PUT/QUERY）またはコマンドモード（BATCH/INTERACTIVE） |
| status_code | 入力 | string | いいえ | ステータスコード（HTTP: 100-599、コマンド: 0-255） |
| url | 入力 | string | いいえ | 検索対象のURL（commandタイプの場合はコマンド名） |
| start | 入力 | string | いいえ | 検索開始日（date形式） |
| end | 入力 | string | いいえ | 検索終了日（date形式） |
| limit | 入力 | string | いいえ | 検索結果の最大件数（10/50/100） |
| token | 入力 | string | いいえ | プロファイルトークン直接指定 |
| type | 入力 | string | いいえ | プロファイルタイプ（デフォルト: `request`）。`request`または`command` |

## 表示項目

本画面はHTMLを描画しない（リダイレクトレスポンスを返却するのみ）。

## イベント仕様

### 1-検索実行とリダイレクト

1. クエリパラメータから検索条件を取得
2. セッションが利用可能な場合（`_stateless`属性がfalseかつセッションが存在）、以下のキーで検索条件をセッションに保存：
   - `_profiler_search_ip`, `_profiler_search_method`, `_profiler_search_status_code`
   - `_profiler_search_url`, `_profiler_search_start`, `_profiler_search_end`
   - `_profiler_search_limit`, `_profiler_search_token`, `_profiler_search_type`
3. トークンが指定されている場合：`_profiler`ルートへリダイレクト（パラメータ: token）
4. トークン未指定の場合：
   - `Profiler::find()`で検索実行（profile_typeによるフィルタリング含む）
   - 検索結果がある場合は先頭トークン、なければ`empty`を使用
   - `_profiler_search_results`ルートへリダイレクト（全検索条件をクエリパラメータに含む）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 検索実行 | なし（ファイルベース） | SELECT | Profilerサービスがファイルシステムからプロファイルデータを検索する |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| profiler_disabled | エラー | "The profiler must be enabled." | プロファイラーが無効な場合 |

## 例外処理

| 例外クラス | 発生条件 | ユーザーへの影響 |
|-----------|---------|----------------|
| `NotFoundHttpException` | プロファイラーが無効な場合 | HTTP 404エラーページが表示される |

## 備考

- 本画面は画面描画を行わず、検索処理とリダイレクトのみを担当する
- セッション保存により、検索バーの入力値がリダイレクト先でも維持される
- `Profiler::find()`にコールバック関数が渡され、`virtual_type`によるプロファイルタイプのフィルタリングが行われる
- リダイレクト時のHTTPステータスコードは302、Content-Typeは`text/html`

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | profiler.php | `src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.php` | `_profiler_search`ルート（18-19行目）の定義を確認 |

**読解のコツ**: 検索処理は検索バー(searchBarAction)とは別のアクション(searchAction)で処理される。検索バーはフォームの表示を担当し、検索アクションが実際の検索ロジックとリダイレクトを担当する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ProfilerController.php | `src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php` | `searchAction`メソッド（264-309行目）が本画面のエントリーポイント。検索条件のセッション保存、トークン指定有無による分岐、Profiler::find()による検索実行の流れを把握する |

**主要処理フロー**:
1. **266行目**: プロファイラー有効性の確認
2. **268-276行目**: クエリパラメータからの検索条件取得
3. **278-290行目**: セッションへの検索条件保存（_stateless属性がfalseかつセッション存在時）
4. **292-293行目**: トークン指定時は_profilerルートへリダイレクト
5. **296行目**: Profiler::find()で検索実行（virtual_typeフィルタリング付き）
6. **298-308行目**: 検索結果の先頭トークン（またはempty）で_profiler_search_resultsへリダイレクト

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

```
ProfilerController::searchAction($request)
    |
    +-- denyAccessIfProfilerDisabled()
    |       +-- Profiler::disable()
    |
    +-- Request::query->get() [各検索条件の取得]
    |
    +-- Session::set() [検索条件のセッション保存] ※セッション利用可能時
    |
    +-- [トークン指定時]
    |       +-- UrlGeneratorInterface::generate('_profiler', ...)
    |       +-- new RedirectResponse(...)
    |
    +-- [トークン未指定時]
            +-- Profiler::find($ip, $url, $limit, $method, $start, $end, $statusCode, callback)
            +-- UrlGeneratorInterface::generate('_profiler_search_results', ...)
            +-- new RedirectResponse(...)
```

### データフロー図

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

HTTPリクエスト         --> ProfilerController            --> RedirectResponse
(GET /_profiler/search)    ::searchAction()
    |                           |
    +-- ip, method,         +-- Session::set()           --> (トークン指定時)
        status_code,        |                                /_profiler/{token}
        url, start,         +-- Profiler::find()
        end, limit,         |                            --> (トークン未指定時)
        token, type         +-- UrlGenerator::generate()     /_profiler/{token}/search/results
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ProfilerController.php | `src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php` | ソース | searchActionメソッドを含むコントローラー |
| profiler.php | `src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.php` | 設定 | ルーティング定義（_profiler_searchルート） |
| search.html.twig | `src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/search.html.twig` | テンプレート | 検索フォーム（本画面の呼び出し元） |
