Files
kate522andClaude Opus 5 427968a721 chore(branding): remove leftover upstream theme identifiers
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>
2026-11-02 00:06:54 +08:00

190 lines
8.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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>