Skip to content

fix(tmplvars): TVフォーム生成とURL型保存処理をPHP8対応#449

Merged
yama merged 5 commits into
mainfrom
fix/tmplvars-tv-form-php8
May 13, 2026
Merged

fix(tmplvars): TVフォーム生成とURL型保存処理をPHP8対応#449
yama merged 5 commits into
mainfrom
fix/tmplvars-tv-form-php8

Conversation

@yama
Copy link
Copy Markdown
Member

@yama yama commented May 10, 2026

closes #410 の内容を再現(ブランチ誤削除による再PR)

https://forum.modx.jp/viewtopic.php?t=2036

概要

  • normalize_url_tv_value() / tv_url_prefixes()helpers.php に追加し、URL型TVの保存処理を各所で共通化
  • rendarFormUrl() を新規追加し URL型TVを form_url.tpl テンプレートで描画(DocIDプレフィックス対応含む)
  • rendarFormDate()$row 引数を追加し form_name を動的に切り替え可能に(docmanagerとmutateで異なるフォーム名に対応)
  • rendarFormImage() / rendarFormFile()hsc() を適用しXSS対策を強化
  • tv.ajax.php のローカル renderFormElement を削除しコアの実装(tmplvars.inc.php)を利用
  • tv.ajax.php のJOINをINNER JOINに変更しORDER BY(tvtpl.rank, tv.rank, tv.id)を追加
  • main.tpl にブラウザ操作JS関数(OpenServerBrowser/BrowseServer/BrowseFileServer/SetUrl)を移動しPHP生成コードを削減
  • renderFormElement() の引数にnullチェックとstring型キャストを追加しPHP8での警告を解消

変更ファイル

ファイル 変更内容
manager/includes/helpers.php tv_url_prefixes()normalize_url_tv_value() を新規追加
manager/includes/docvars/inputform/form_url.tpl 新規テンプレートファイル作成
manager/includes/docvars/inputform/form_date.tpl フォーム名を [+form_name+] プレースホルダーに変更
manager/includes/docvars/inputform/form_file.tpl form_image.tpl style="%s" 形式に修正
manager/includes/traits/document.parser.subparser.trait.php rendarFormUrl() 追加、null安全処理、hsc() 適用、rendarFormDate()$row 引数追加
assets/modules/docmanager/tv.ajax.php ローカル renderFormElement を削除しコアのものを利用、INNER JOIN・ORDER BY追加
assets/modules/docmanager/templates/main.tpl ブラウザ操作JS関数をテンプレートへ移動
assets/modules/docmanager/classes/dm_backend.class.php normalize_url_tv_value() を利用
assets/plugins/qm/qm.inc.php URL TV保存時に正規化処理を追加
manager/actions/document/mutate_content/fields.php save_resource.processor.php normalize_url_tv_value() を利用
manager/actions/element/mutate_module.dynamic.php mutate_tmplvars.dynamic.php $chk$chks$notPublic 初期化

Test plan

  • URL型TVを持つドキュメントを編集し保存できること
  • URL型TVのプレフィックス(http:///https:///ftp:///mailto:/DocID/--)が正しく保存されること
  • DocIDプレフィックスで数値入力時に [~ID~] 形式で保存されること
  • date型TVの「日付クリア」ボタンが docmanager モジュール内で機能すること
  • image/file型TVのブラウザボタンが機能すること
  • docmanagerモジュールのTV一覧がAJAXで正しく表示されること

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • URL入力フォームテンプレートを追加しました
    • ファイル/画像ブラウザーのクライアント連携を強化し、ポップアップから選択したURLをフォームへ反映できるようになりました
  • Bug Fixes

    • URL型テンプレート変数の取り扱いを正規化し一貫性を向上しました
    • 各種フォーム出力で値・スタイルの適切なエスケープとフォーム名参照の不具合を修正しました
  • Refactor

    • URL正規化ロジックを共通ヘルパーに統合しました
  • Chores

    • 開発設定ファイルを更新しました

Review Change Stack

- normalize_url_tv_value()/tv_url_prefixes() をhelpers.phpに追加し、
  URL型TV保存処理を各所で共通化(dm_backend、fields.php、save_resource、qm、getPreviewObject)
- rendarFormUrl() を新規追加しURL型TVをform_url.tplテンプレートで描画
- rendarFormDate() に $row 引数を追加しform_name を動的に切り替え可能に
- rendarFormImage()/rendarFormFile() に hsc() を適用しXSS対策を強化
- tv.ajax.php のローカル renderFormElement を削除しコアの実装を利用
- tv.ajax.php のJOINをINNER JOINに変更しORDER BYを追加
- main.tpl にブラウザ操作JS関数を移動しPHP生成コードを削減
- renderFormElement() の引数にnullチェックとstring型キャストを追加

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 10, 2026 11:16
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d9ba9006-7812-40b1-ac2b-4ab0e111c1c1

📥 Commits

Reviewing files that changed from the base of the PR and between 164484e and f2ae18f.

📒 Files selected for processing (1)
  • assets/plugins/qm/qm.inc.php

📝 Walkthrough

Walkthrough

このPRはURL型テンプレート変数の正規化ロジックを集中化し、フォーム入力レンダリングをテンプレート化して複数の保存・表示経路で一貫した正規化とエスケープを適用しています。

Changes

URL TV正規化と Form Rendering統一

Layer / File(s) Summary
Helper関数
manager/includes/helpers.php
tv_url_prefixes()normalize_url_tv_value($value, $prefix='--')を新規追加。URLプレフィックス候補を集約し、DocID検出と既知スキーマの剥離・結合を実装。
Form入力テンプレート
manager/includes/docvars/inputform/*
新規form_url.tpl追加。既存form_date.tpl, form_file.tpl, form_image.tplのstyle属性挿入と動的form_name参照を修正。
Form Rendering - 入力値正規化
manager/includes/traits/document.parser.subparser.trait.php
renderFormElement()でnull値処理・文字列強制・PHP evalマーカー処理条件化を追加。URLは専用レンダーパスへ分岐。
URL Form専用Renderer
manager/includes/traits/document.parser.subparser.trait.php
新規rendarFormUrl()を追加。既存URL値のパース([~docid~]・プレフィックス検出)、プレフィックス選択肢生成、form_url.tplレンダリングを実装。
日付/ファイル/画像Renderer更新
manager/includes/traits/document.parser.subparser.trait.php
rendarFormDate()にrow・form_name推定とstyleエスケープを追加。rendarFormImage()/rendarFormFile()で値とstyleのHTMLエスケープを追加。プレビュー生成でもnormalizeを使用。
バックエンド保存処理
assets/modules/docmanager/classes/dm_backend.class.php, manager/actions/document/mutate_content/fields.php, manager/processors/document/save_resource.processor.php, assets/plugins/qm/qm.inc.php
複数の保存ポイントでnormalize_url_tv_value()を用い、選択されたプレフィックスとともにURL値を正規化してDBへ保存。
Document Manager - UI & JavaScript
assets/modules/docmanager/templates/main.tpl
サーバーブラウザー用JavaScript関数(OpenServerBrowser, BrowseServer, BrowseFileServer, SetUrl)を追加し、lastImageCtrl/lastFileCtrlでターゲット制御を追跡。
Document Manager - TV一覧クエリ最適化
assets/modules/docmanager/tv.ajax.php
tplIDをint化、INNER JOINでtv一覧取得、template_rank順ソート、caption/descriptionのHTMLエスケープ追加、renderFormElement()呼出しの引数を更新。
アクセス権限 - 変数初期化修正
manager/actions/element/mutate_module.dynamic.php, manager/actions/element/mutate_tmplvars.dynamic.php
チェックボックス生成で$chks$notPublic=falseを明示初期化する修正。
CI/レビュー設定
.coderabbit.yaml
レビューアシスタント設定(言語: ja-JP 等)を更新。

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive .coderabbit.yaml の設定変更(言語・レビュープロファイル)は主要な TV/URL 処理改修とは別の設定更新であり若干関連性が薄い。 .coderabbit.yaml の変更が #410 要件に関連しているか確認し、関連がなければ別 PR に分離することを検討してください。
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed タイトルは PR の主要な変更内容(PHP8 対応、TV フォーム生成、URL 型保存処理)を明確に要約している。
Description check ✅ Passed 説明は指定されたテンプレート形式に従い、概要・変更内容・確認手順・変更ファイル表とテスト項目チェックリストを網羅している。
Linked Issues check ✅ Passed PR の実装内容(ヘルパー関数追加、form_url.tpl 作成、hsc() 適用、JS 関数移動、null 安全処理)が #410 の全要件を満たしている。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/tmplvars-tv-form-php8

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1af27caeda

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread assets/plugins/qm/qm.inc.php Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
manager/includes/traits/document.parser.subparser.trait.php (1)

2291-2309: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

*_prefix が付いただけの非 URL TV まで正規化しない方が安全です。

いまは tv{id}_prefix が同時送信されるだけで TV の type を見ずに normalize_url_tv_value() を通すため、URL 以外の TV でも値が書き換わります。site_tmplvars から type も保持して、url のときだけ正規化してください。

🔧 修正例
-            $tvname[$tvid] = $row['name'];
+            $tvname[$tvid] = [
+                'name' => $row['name'],
+                'type' => $row['type'],
+            ];
...
-            if (isset($tvname[$k])) {
+            if (isset($tvname[$k])) {
                 if (is_array($v)) {
                     $v = implode('||', $v);
                 }
-                $name = $tvname[$k];
+                $name = $tvname[$k]['name'];
                 $prefix_key = "{$k}_prefix";
-                if (isset($input[$prefix_key])) {
+                if (($tvname[$k]['type'] ?? '') === 'url' && isset($input[$prefix_key])) {
                     $v = normalize_url_tv_value($v, $input[$prefix_key]);
                 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@manager/includes/traits/document.parser.subparser.trait.php` around lines
2291 - 2309, 現在は `site_tmplvars` から取得した TV を名前だけで参照し、`tv{id}_prefix`
が送信されていると値を無条件で `normalize_url_tv_value()` に通しているため、URL 以外の TV
も書き換わってしまいます。db()->select() で取得する列に `type` を含めて(`id,name,type,...` を利用)、ループ内で
`if (isset($tvname[$k]))` の代わりに TV 情報(名前と type)を参照し、`type === 'url'` のときだけ
`normalize_url_tv_value($v, $input[$prefix_key])` を呼ぶように変更してください(該当関数・変数:
normalize_url_tv_value, $tvname/$tvid, $input, $prefix_key, site_tmplvars)。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@manager/includes/docvars/inputform/form_url.tpl`:
- Around line 4-9: The template outputs unescaped attribute placeholders (e.g.
[+prefix_id+], [+prefix_name+], [+id+], [+name+], [+value+]) which permits
attribute-injection/XSS; update form_url.tpl to use attribute-escaped
placeholders (e.g. use the *_attr variants for id/name/value in the select and
input attributes) and update the renderer that builds these placeholders to pass
hsc()-escaped strings into the *_attr keys so all attribute values are
HTML-escaped before rendering.

---

Outside diff comments:
In `@manager/includes/traits/document.parser.subparser.trait.php`:
- Around line 2291-2309: 現在は `site_tmplvars` から取得した TV を名前だけで参照し、`tv{id}_prefix`
が送信されていると値を無条件で `normalize_url_tv_value()` に通しているため、URL 以外の TV
も書き換わってしまいます。db()->select() で取得する列に `type` を含めて(`id,name,type,...` を利用)、ループ内で
`if (isset($tvname[$k]))` の代わりに TV 情報(名前と type)を参照し、`type === 'url'` のときだけ
`normalize_url_tv_value($v, $input[$prefix_key])` を呼ぶように変更してください(該当関数・変数:
normalize_url_tv_value, $tvname/$tvid, $input, $prefix_key, site_tmplvars)。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8bd0e1db-8d7d-4c27-bd89-2e1074a07bae

📥 Commits

Reviewing files that changed from the base of the PR and between 1420a54 and 1af27ca.

📒 Files selected for processing (14)
  • assets/modules/docmanager/classes/dm_backend.class.php
  • assets/modules/docmanager/templates/main.tpl
  • assets/modules/docmanager/tv.ajax.php
  • assets/plugins/qm/qm.inc.php
  • manager/actions/document/mutate_content/fields.php
  • manager/actions/element/mutate_module.dynamic.php
  • manager/actions/element/mutate_tmplvars.dynamic.php
  • manager/includes/docvars/inputform/form_date.tpl
  • manager/includes/docvars/inputform/form_file.tpl
  • manager/includes/docvars/inputform/form_image.tpl
  • manager/includes/docvars/inputform/form_url.tpl
  • manager/includes/helpers.php
  • manager/includes/traits/document.parser.subparser.trait.php
  • manager/processors/document/save_resource.processor.php

Comment thread manager/includes/docvars/inputform/form_url.tpl
yama and others added 2 commits May 10, 2026 20:33
- rendarFormUrl()でid/name/prefix_id/prefix_nameにhsc()を適用しXSS対策を強化
- getPreviewObject()でtvnameにtype情報を追加し、url型TVのみnormalize_url_tv_valueを適用

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
QMフォームはrenderFormElement()にtvname(文字列)を渡すため
フォームのselectのname属性はtv<tvname>_prefixになる。
保存時にtv<tvId>_prefixのみ読んでいるとプレフィックスが常に'--'扱いになり
URLスキームが欠落するバグを修正。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@assets/plugins/qm/qm.inc.php`:
- Around line 434-442: The URL TV normalization is only called inside the if
($tvId) block so name-based TV submissions skip normalize_url_tv_value; change
the logic to determine $tvType by querying either id or name (use $tvId if
present otherwise look up by $tvName) and then, regardless of $tvId, call
normalize_url_tv_value when $tvType === 'url' using the existing prefix
resolution postv('tv'.$tvId.'_prefix', postv('tv'.$tvName.'_prefix', '--')),
keeping $tvContent and function normalize_url_tv_value as before.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 44b2a8b4-7a7c-4234-8f4d-f1a1f65e4a08

📥 Commits

Reviewing files that changed from the base of the PR and between f86b30d and 164484e.

📒 Files selected for processing (2)
  • assets/plugins/qm/qm.inc.php
  • manager/includes/traits/document.parser.subparser.trait.php

Comment thread assets/plugins/qm/qm.inc.php Outdated
tvIdが0の場合(tvid未送信)でもtvNameでtype照会し、
url型であればnormalize_url_tv_valueを適用するよう変更。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@yama yama merged commit d08d69a into main May 13, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants