fix(vip): preserve equity HTML instead of re-splitting into list items

This commit is contained in:
kate522 committed 2026-07-21 20:19:11 +08:00
1 parent ee5a16f9a0
commit fce5ab3088
5 files changed
+110 -102

No files matched your search

+77
View File
@@ -415,3 +415,80 @@ if (!function_exists('aksrt_get_vip_purchase_url')) {
return home_url('/');
}
}
/**
* Format VIP equity HTML for front-end display.
*
* Admin field is free-form HTML (typically one or more <li>). Do NOT
* re-parse / re-split the content into synthetic list items by punctuation
* or Chinese keyword heuristics — that mangles intentional HTML.
*
* Rules:
* - Sanitize with a small allowlist.
* - If markup already has <li>, wrap the items in <ul class="v-equity …">.
* - Otherwise output the sanitized HTML inside <div class="v-equity …">.
* - Plain multi-line text: each non-empty line becomes one <li> (only \n split).
* - Empty input → empty string.
*
* @param string $raw Equity HTML/plain from settings.
* @param string $class Extra classes on the wrapper (e.g. "mb10 relative").
*/
if (!function_exists('aksrt_format_vip_equity_html')) {
function aksrt_format_vip_equity_html(string $raw, string $class = ''): string {
$raw = trim($raw);
if ($raw === '') {
return '';
}
$allowed = [
'li' => ['class' => true],
'ul' => ['class' => true],
'ol' => ['class' => true],
'strong' => [],
'b' => [],
'em' => [],
'i' => ['class' => true],
'span' => ['class' => true],
'br' => [],
'p' => ['class' => true],
'div' => ['class' => true],
'a' => ['href' => true, 'target' => true, 'rel' => true, 'class' => true],
];
$clean = trim(wp_kses($raw, $allowed));
if ($clean === '') {
return '';
}
$class = trim('v-equity ' . $class);
$class_attr = esc_attr($class);
// Already list items — preserve them, only re-wrap.
if (preg_match('/<li[\s>]/i', $clean)) {
$inner = preg_replace('#</?(ul|ol)[^>]*>#i', '', $clean) ?? $clean;
$inner = trim($inner);
if ($inner === '') {
return '';
}
return '<ul class="' . $class_attr . '">' . $inner . '</ul>';
}
// Other HTML (p/br/a/…) — keep as-is, no list fabrication.
if (preg_match('/<[^>]+>/', $clean)) {
return '<div class="' . $class_attr . '">' . $clean . '</div>';
}
// Plain text only: split by newlines (author-authored line breaks), never
// by commas / Chinese keywords.
$lines = preg_split('/\R+/u', $clean) ?: [];
$lines = array_values(array_filter(array_map('trim', $lines), static fn($s) => $s !== ''));
if ($lines === []) {
return '';
}
$html = '<ul class="' . $class_attr . '">';
foreach ($lines as $line) {
$html .= '<li>' . esc_html($line) . '</li>';
}
$html .= '</ul>';
return $html;
}
}