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

+1 -1
View File
@@ -243,7 +243,7 @@ class SchemaPayment {
['key' => 'points-exchange', 'title' => '积分兑换会员', 'fields' => [
['key' => 'pay_vip_points_exchange_s', 'label' => '启用积分兑换', 'type' => 'switch', 'default' => false],
['key' => 'payment_vip_points_packages', 'label' => '兑换套餐', 'type' => 'textarea', 'default' => "1|500|30|积分月卡\n1|5000|0|积分永久", 'dependsOn' => ['key' => 'pay_vip_points_exchange_s', 'value' => true], 'help' => '每行:等级|积分|天数|标题(天数 0=永久;普通用户可开通,已有会员可续费同等级或升级更高等级)'],
['key' => 'pay_vip_points_exchange_desc', 'label' => '兑换说明', 'type' => 'textarea', 'default' => '', 'dependsOn' => ['key' => 'pay_vip_points_exchange_s', 'value' => true]],
['key' => 'pay_vip_points_exchange_desc', 'label' => '兑换说明', 'type' => 'textarea', 'sanitize_type' => 'html', 'default' => '', 'rows' => 2, 'dependsOn' => ['key' => 'pay_vip_points_exchange_s', 'value' => true]],
]],
['key' => 'modal-copy', 'title' => '界面文案', 'fields' => [
['key' => 'pay_user_vip_desc', 'label' => '会员介绍', 'type' => 'input', 'default' => '开通VIP会员,享受会员专属折扣以及多项特权', 'dependsOn' => ['any' => [['key' => 'pay_user_vip_1_s', 'value' => true], ['key' => 'pay_user_vip_2_s', 'value' => true]]]],
+3 -1
View File
@@ -238,7 +238,9 @@ trait VipServiceModal {
$desc_text = trim((string) ($points_ex['desc'] ?? ''));
$desc = $desc_text !== ''
? '<div class="muted-box muted-2-color padding-10 em09 mt20">' . esc_html($desc_text) . '</div>'
// 管理员编辑的富文本说明:保存端已 wp_kses_post,这里同级别输出
// (参考主题 zibpay_get_vip_points_exchange_modal 原样拼接)。
? '<div class="muted-box muted-2-color padding-10 em09 mt20">' . wp_kses_post($desc_text) . '</div>'
: '';
// 最低价套餐仍超出用户积分 → 参考主题的 badg c-red btn-block 提示。
+1 -1
View File
@@ -261,7 +261,7 @@ class PaymentRuntime {
],
'points_exchange' => [
'enabled' => !empty($settings['pay_vip_points_exchange_s']),
'desc' => sanitize_textarea_field((string) ($settings['pay_vip_points_exchange_desc'] ?? '')),
'desc' => wp_kses_post((string) ($settings['pay_vip_points_exchange_desc'] ?? '')),
'packages_raw' => sanitize_textarea_field((string) ($settings['payment_vip_points_packages'] ?? "1|500|30|积分月卡\n1|5000|0|积分永久")),
],
];