fix(vip): let 积分兑换说明 support HTML like the reference theme

The points-exchange desc was stripped at all three layers: no sanitize_type on the schema fields (save ran sanitize_textarea_field), the runtime re-ran the same strip, and the points modal escaped it with esc_html. The reference theme declares sanitize=false and concatenates the value raw into the modal.

- Schema (SPA + PHP): sanitize_type html, rows 2, help text noting HTML support

- PaymentRuntime: output via wp_kses_post

- VipServiceModal points modal: render via wp_kses_post instead of esc_html

Verification: new contract test covers schema/runtime/modal layers; node --test tests/**/*.test.cjs 641/641 pass; php -l clean on both PHP files.
This commit is contained in:
kate522 committed 2026-10-18 15:06:29 +08:00
1 parent 2e2558e5ce
commit dcb80cff6e
5 files changed
+18 -4

No files matched your search

@@ -172,3 +172,15 @@ test('弹窗内 more 与卡密说明按 HTML 渲染而非纯文本', () => {
assert.ok(payVipJs.includes('htmlNode("div", "muted-2-color mb10 em09 muted-box padding-10 mini-radius", catalog.more)'));
assert.ok(payVipJs.includes('htmlNode("div", "muted-box muted-2-color padding-10 mb10 em09", cardPass.desc)'));
});
test('积分兑换说明按 post 级 HTML 放行并原样渲染', () => {
// 参考主题该字段 sanitize=false 且弹窗内原样拼接;AKSRT 对齐为保存/输出
// 双端 wp_kses_post + 弹窗 wp_kses_post 渲染。
assert.match(vipSchemaJs, /key: 'pay_vip_points_exchange_desc', label: '兑换说明', type: 'textarea', sanitize_type: 'html'/);
assert.match(schemaPhp, /'key' => 'pay_vip_points_exchange_desc', 'label' => '兑换说明', 'type' => 'textarea', 'sanitize_type' => 'html'/);
const vipSettings = slice(paymentRuntime, 'public static function get_payment_vip_settings', 'public static function get_payment_revenue_settings');
assert.match(vipSettings, /'desc'\s+=> wp_kses_post\(\(string\) \(\$settings\['pay_vip_points_exchange_desc'\]/);
// 弹窗渲染端不再 esc_html 剥标签。
assert.match(modalSource, /<div class="muted-box muted-2-color padding-10 em09 mt20">' \. wp_kses_post\(\$desc_text\)/);
assert.doesNotMatch(modalSource, /esc_html\(\$desc_text\)/);
});