The theme was renamed Zibll/子比 → AKSRT → Jio, but upstream branding survived the sweeps in CSS classes, the SVG sprite prefix, a persisted widget field ID, JS events, admin Vue class names, test infrastructure and docblocks. Renames: - zib-widget / zib-widget-wrap / zib-slider → jio-widget-box / jio-widget-box-wrap / jio-slider-box (jio-widget is taken by the modern widget shell, jio-box-* by the card primitives) - zib-partners-scroll + zps-* → jio-partners-scroll + jps-* - zib-combo-info-card + zci-* → jio-combo-info-card + jci-* - zibsvg- → jiosvg-, including the exported picker helpers and the fa-zibsvg- family-prefix guard - zibpay_type → pay_type; the dual-read fallback in PostQuery collapses to a single key - [zibajax="submit"] dropped (no PHP emitter); zib_ajax.success → jio_ajax.success - aks-* admin Vue classes → jio-* - zib_palette() → palette() User-facing vendor traces are gone: the floating "more" button default no longer ships a zibll.com link or 子比主题 marketing copy, the notice widget ships no preset promo entries, and the four 官网教程 links are removed from the post-list admin schema. Test infrastructure renamed to neutral names (docker-compose.reference.yml, Caddyfile, article-baseline.json, modern-widgets-contract.test.cjs) with their DB/volume/env/slug identifiers following. Kept intentionally, documented in tests/fixtures/README.md: the golden fixture reference fingerprint (a SHA-256 record of an external directory, read by validate-widget-golden / generate-widget-golden-fixture / audit-widget-system), the doesNotMatch guards that prove the old tokens are gone, and the reference theme's own meta key in the visual fixtures. No backward-compat or data migration: saved widget configs holding old icon keys or the old field ID silently lose them, per the project's rewrite-over-compatibility rule. Verified: 132/132 node contract tests, php tests/widget-system/run.php (146 assertions), audit-admin-contracts, audit-psr4-paths and validate-widget-golden all green; tracked bundles regenerated and in sync. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
190 lines
8.5 KiB
PHP
190 lines
8.5 KiB
PHP
<?php
|
||
/**
|
||
* User center VIP tab (legacy 我的会员 1:1 structure).
|
||
*
|
||
* Expects extracted $context vars via profile-vip.php / capture path.
|
||
*
|
||
* @package Jio
|
||
*/
|
||
|
||
defined('ABSPATH') || exit;
|
||
|
||
$vip_settings = is_array($vip_settings ?? null) ? $vip_settings : [];
|
||
if (empty($vip_settings['enabled']) && class_exists('\Jio\Settings\Settings')) {
|
||
$vip_settings = \Jio\Settings\Settings::get_payment_vip_settings();
|
||
}
|
||
if (empty($vip_settings['enabled'])) {
|
||
echo '<div class="jio-panel padding-20 muted-2-color">' . esc_html__('会员功能未启用。', 'jio') . '</div>';
|
||
return;
|
||
}
|
||
|
||
$user_id = (int) ($user_id ?? get_current_user_id());
|
||
$vip_state = function_exists('jio_get_user_vip_state') ? jio_get_user_vip_state($user_id) : [];
|
||
$level = (int) ($vip_state['level'] ?? 0);
|
||
$expires = max(0, (int) ($vip_state['current_expires'] ?? $vip_state['expires'] ?? 0));
|
||
$base_level = min(2, max(0, (int) ($vip_state['fallback_level'] ?? 0)));
|
||
$base_expires = max(0, (int) ($vip_state['fallback_expires'] ?? 0));
|
||
$expired_level = min(2, max(0, (int) ($vip_state['expired_level'] ?? 0)));
|
||
$vip_state_name = (string) ($vip_state['state'] ?? 'unopened');
|
||
$vip_state_source = (string) ($vip_state['source'] ?? 'none');
|
||
$levels = is_array($vip_settings['levels'] ?? null) ? $vip_settings['levels'] : [];
|
||
$desc_top = (string) ($vip_settings['desc'] ?? '');
|
||
$renew_desc = (string) ($vip_settings['renew']['desc'] ?? '');
|
||
$upgrade_desc = (string) ($vip_settings['upgrade']['desc'] ?? '');
|
||
|
||
// Membership summary: title → level → intro → expiry.
|
||
$vip_state = 'unopened';
|
||
$vip_state_label = __('未开通', 'jio');
|
||
$vip_level_number = 0;
|
||
$vip_level_name = __('未开通会员', 'jio');
|
||
$vip_description = $desc_top !== '' ? $desc_top : __('开通会员,尊享专属特权', 'jio');
|
||
// 未开通时不留到期文案:状态标签已显示「未开通」,参考主题对从未开通
|
||
// 用户同样不输出任何到期信息(仅生效中/永久/已过期才有)。
|
||
$vip_expiry_text = '';
|
||
$vip_is_permanent = false;
|
||
$btn_type = 'pay';
|
||
|
||
if ($level > 0) {
|
||
$vip_level_number = $level;
|
||
$vip_level_name = (string) ($levels[$level]['name_html'] ?? $levels[$level]['name'] ?? ('VIP' . $level));
|
||
$level_desc = (string) ($levels[$level]['desc'] ?? '');
|
||
$vip_description = $level_desc !== '' ? $level_desc : __('尊享专属特权', 'jio');
|
||
|
||
if ($expires <= 0 && $vip_state_source !== 'order') {
|
||
$vip_state = 'permanent';
|
||
$vip_state_label = __('永久有效', 'jio');
|
||
$vip_expiry_text = __('到期时间:永久会员', 'jio');
|
||
$vip_is_permanent = true;
|
||
if ($level < 2) {
|
||
$btn_type = 'upgrade';
|
||
}
|
||
} else {
|
||
$vip_state = 'active';
|
||
$vip_state_label = __('生效中', 'jio');
|
||
$vip_expiry_text = sprintf(__('到期时间:%s', 'jio'), wp_date('Y年m月d日', $expires));
|
||
if ($base_level > 0 && $base_level < $level) {
|
||
$base_name = wp_strip_all_tags((string) ($levels[$base_level]['name'] ?? ('VIP' . $base_level)));
|
||
$base_expiry_text = $base_expires > 0
|
||
? wp_date('Y年m月d日', $base_expires)
|
||
: __('永久', 'jio');
|
||
$vip_expiry_text .= ';' . sprintf(__('%s:%s', 'jio'), $base_name, $base_expiry_text);
|
||
}
|
||
$btn_type = 'renew_' . $level;
|
||
}
|
||
} elseif ($expired_level > 0) {
|
||
$vip_state = 'expired';
|
||
$vip_state_label = __('已过期', 'jio');
|
||
$vip_level_number = $expired_level;
|
||
$vip_level_name = (string) ($levels[$expired_level]['name_html'] ?? $levels[$expired_level]['name'] ?? ('VIP' . $expired_level));
|
||
$expired_desc = (string) ($levels[$expired_level]['desc'] ?? '');
|
||
$vip_description = $expired_desc !== ''
|
||
? $expired_desc
|
||
: ($desc_top !== '' ? $desc_top : __('会员已过期', 'jio'));
|
||
$vip_expiry_text = $expires > 0
|
||
? sprintf(__('到期时间:%s', 'jio'), wp_date('Y年m月d日', $expires))
|
||
: __('到期时间:已过期', 'jio');
|
||
}
|
||
|
||
$status_icon_url = esc_url((string) ($levels[$vip_level_number]['img_icon'] ?? ''));
|
||
$status_icon = $status_icon_url !== ''
|
||
? '<img' . jio_get_lazy_attr('lazy_other', $status_icon_url, 'jio-vip-level-icon') . ' alt="" decoding="async">'
|
||
: '<i class="fa fas fa-certificate"></i>';
|
||
$status_html = '<div class="uc-vip-status" role="status">'
|
||
. '<div class="uc-vip-status__heading">'
|
||
. '<h2 class="uc-vip-status__label">' . esc_html__('我的会员', 'jio') . '</h2>'
|
||
. '<span class="uc-vip-status__state">' . esc_html($vip_state_label) . '</span>'
|
||
. '</div>'
|
||
. '<div class="uc-vip-status__main uc-vip-status__main--level-' . (int) $vip_level_number . '">'
|
||
// 未开通(level 0)不输出图标位:名称前不放通用证书图标。
|
||
. ($vip_level_number > 0 ? '<span class="uc-vip-status__icon" aria-hidden="true">' . $status_icon . '</span>' : '')
|
||
. '<span class="uc-vip-status__level">' . wp_kses_post($vip_level_name) . '</span>'
|
||
. '</div>'
|
||
. '<div class="uc-vip-status__desc">' . wp_kses_post($vip_description) . '</div>'
|
||
. ($vip_expiry_text !== '' ? '<div class="uc-vip-status__expiry"><i class="fa fas fa-clock" aria-hidden="true"></i><span>' . esc_html($vip_expiry_text) . '</span></div>' : '')
|
||
. '</div>';
|
||
|
||
// Level cards.
|
||
$cards = '';
|
||
foreach ([1, 2] as $lv) {
|
||
if (empty($levels[$lv]['enabled'])) {
|
||
continue;
|
||
}
|
||
$lv_name = (string) ($levels[$lv]['name_html'] ?? $levels[$lv]['name'] ?? ('VIP' . $lv));
|
||
$lv_desc = (string) ($levels[$lv]['desc'] ?? '');
|
||
// Preserve admin equity HTML as-is (sanitize/wrap only; never re-split into items).
|
||
$equity_raw = (string) ($levels[$lv]['equity'] ?? '');
|
||
$equity = function_exists('jio_format_vip_equity_html')
|
||
? jio_format_vip_equity_html($equity_raw)
|
||
: '';
|
||
$cta = __('开通', 'jio') . wp_kses_post($lv_name);
|
||
$vip_attr = $lv;
|
||
// 续费/升级档位卡展示各自的一句话简介。
|
||
$card_action = 'pay';
|
||
$card_desc = $lv_desc;
|
||
$lv_icon_url = esc_url((string) ($levels[$lv]['img_icon'] ?? ''));
|
||
$lv_icon = $lv_icon_url !== ''
|
||
? '<img' . jio_get_lazy_attr('lazy_other', $lv_icon_url, 'jio-vip-level-icon') . ' alt="" decoding="async">'
|
||
: '<i class="fa fas fa-certificate" aria-hidden="true"></i>';
|
||
if (str_starts_with($btn_type, 'renew_')) {
|
||
$renew_lv = (int) substr($btn_type, 6);
|
||
if ($lv === $renew_lv) {
|
||
$cta = __('续费', 'jio') . wp_kses_post($lv_name);
|
||
$card_action = 'renew';
|
||
} elseif ($lv > $renew_lv) {
|
||
$cta = __('升级', 'jio') . wp_kses_post($lv_name);
|
||
$card_action = 'upgrade';
|
||
} else {
|
||
continue;
|
||
}
|
||
} elseif ($btn_type === 'upgrade') {
|
||
if ($lv <= $level) {
|
||
continue;
|
||
}
|
||
$cta = __('升级', 'jio') . wp_kses_post($lv_name);
|
||
$card_action = 'upgrade';
|
||
$vip_attr = 2;
|
||
} elseif ($level > 0 && $lv < $level) {
|
||
continue;
|
||
} elseif ($level > 0 && $lv === $level) {
|
||
$cta = __('续费', 'jio') . wp_kses_post($lv_name);
|
||
$card_action = 'renew';
|
||
}
|
||
if ($card_action === 'renew' && $renew_desc !== '') {
|
||
$card_desc = $renew_desc;
|
||
} elseif ($card_action === 'upgrade' && $upgrade_desc !== '') {
|
||
$card_desc = $upgrade_desc;
|
||
}
|
||
|
||
$cards .= '<div class="jio-panel text-center pay-vip-info flex1 level-' . $lv . ' uc-vip-level-card">';
|
||
$cards .= '<div class="relative uc-vip-level-card__inner">';
|
||
$cards .= '<div class="v-iconbox mb10">';
|
||
$cards .= '<div class="v-name font-bold"><span class="v-icon">' . $lv_icon . '</span>' . wp_kses_post($lv_name) . '</div>';
|
||
if ($card_desc !== '') {
|
||
$cards .= '<div class="v-desc em09 muted-2-color">' . wp_kses_post($card_desc) . '</div>';
|
||
}
|
||
$cards .= '</div>';
|
||
$cards .= $equity;
|
||
$cards .= '<a class="padding-lg but jb-vip' . $lv . ' radius pay-vip uc-vip-cta" href="javascript:;" vip-level="' . (int) $vip_attr . '">'
|
||
. '<span>' . $cta . '</span>'
|
||
. ' <i class="fa fas fa-chevron-circle-right" aria-hidden="true"></i></a>';
|
||
$cards .= '</div></div>';
|
||
}
|
||
|
||
?>
|
||
<div class="uc-vip-tab" data-jio-vip-tab>
|
||
<div class="uc-vip-summary" data-jio-vip-summary data-vip-state="<?php echo esc_attr($vip_state); ?>" data-vip-level="<?php echo (int) $vip_level_number; ?>" data-vip-permanent="<?php echo $vip_is_permanent ? 'true' : 'false'; ?>">
|
||
<div class="uc-vip-summary__watermark" aria-hidden="true"><i class="fa fas fa-certificate"></i></div>
|
||
<?php echo $status_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||
</div>
|
||
|
||
<div class="uc-vip-level-cards">
|
||
<?php echo $cards; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||
</div>
|
||
|
||
<?php
|
||
// 积分兑换会员入口(档位购买卡下方的全宽横条;
|
||
// 仅非会员 + 积分兑换开启 + 有可兑换套餐时输出)。
|
||
echo jio_get_vip_points_exchange_entry_html($user_id, $level); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- 各字段已在生成时转义。
|
||
?>
|
||
</div>
|