Files
wordpress-theme-aksrt/inc/helpers/jio-header-userbox.php
T
kate522andClaude Opus 5 35bb96e82f refactor: rename the theme brand and every identifier from AKSRT to Jio
Full-project rename. `git grep -i aksrt` is now empty apart from the
DBMigrator 3.3.0 changelog note that documents the rename itself.

Code identifiers
- PHP namespace AKSRT\ -> Jio\ (composer PSR-4 + 378 declarations)
- global constants AKSRT_* -> JIO_* (VERSION/DIR/URI, PAY_TYPE_*, CAPTCHA_*)
- procedural functions, hooks, options, meta keys, table names,
  cookies, query vars, ajax actions and nonces: aksrt_ -> jio_
- text domain aksrt -> jio; Theme Name -> Jio
- JS globals: aksrtData/aksrtAdminData/... -> jioData/jioAdminData/...,
  window.AKSRTCaptcha & friends -> window.JioCaptcha, Aksrt* -> Jio*
- Vue components Aks*.vue -> Jio*.vue (15 files renamed + imports)
- CSS classes/data-attrs/custom properties: aksrt- -> jio-
- REST namespace aksrt/v1 -> jio/v1 (incl. payment gateway callbacks)

Storage layer
- DB tables {prefix}aksrt_* -> {prefix}jio_*; SCHEMA_VERSION 3.2.0 -> 3.3.0
  so dbDelta creates the new names on install
- widget id_base aksrt_widget_* -> jio_widget_*
- uninstall.php drop list rebuilt from the actual migrator tables
  (dropped 3 stale entries, added the 17 missing ones)

Removed
- hardcoded https://api.aksrt.com/version.json default update endpoint;
  get_endpoint() now reads the 「更新端点」 setting and do_check() no-ops
  when it is empty

Files renamed: inc/helpers/aksrt-*.php -> jio-*.php (54),
assets/admin/src/components/form/Aks*.vue -> Jio*.vue (15).
Build artifacts regenerated: assets/css/build, assets/js/runtime,
assets/admin/build.

Verified: audit-psr4-paths errors=0, audit-admin-contracts errors=0
(warnings=56, unchanged baseline), 813/813 widget-system tests,
44/44 phpunit, php -l clean across all PHP.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-01 20:05:04 +08:00

271 lines
10 KiB
PHP

<?php
/**
* Header user-box density helpers (legacy subset).
*
* @package Jio
*/
defined('ABSPATH') || exit;
if (!function_exists('jio_get_user_checkin_details_link')) :
/**
* 已签到详情弹窗触发链接(参考主题 zib_get_user_checkin_details_link 1:1):
* 打开刷新式 mini 弹窗(高 240,移动端底部弹出,每次都重新拉取)。
*
* @param string $class 沿用入口按钮的类。
* @param string $text 链接内文(含图标)。
*/
function jio_get_user_checkin_details_link(string $class = '', string $text = ''): string {
$class = trim($class . ' checkin-details-link');
return '<a class="' . esc_attr($class) . '" href="javascript:;"'
. ' data-jio-modal="remote"'
. ' data-jio-modal-url="' . esc_url(rest_url('jio/v1/signin/details')) . '"'
. ' data-jio-modal-class="jio-checkin-details-modal modal-mini"'
. ' data-jio-modal-height="240"'
. ' data-jio-modal-mobile-bottom="true"'
. ' data-jio-modal-cache="false">'
. $text
. '</a>';
}
endif;
if (!function_exists('jio_header_user_checkin_btn')) :
/**
* Check-in CTA for header dropdown and compact card placements.
*
* @param int $user_id Current user ID.
* @param string|null $class Override the classes and render the reference-parity
* <a> badge (user-card 签到书签); null keeps the header
* dropdown <a> runtime.
*/
function jio_header_user_checkin_btn(int $user_id = 0, ?string $class = null): string {
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
if ($user_id <= 0 || !class_exists('\Jio\Credits\Signin')) {
return '';
}
$cfg = class_exists('\Jio\Settings\Settings')
? \Jio\Settings\Settings::get_signin_reward_settings()
: ['enabled' => false];
if (empty($cfg['enabled'])) {
return '';
}
$signed = \Jio\Credits\Signin::get_instance()->is_signed_today($user_id);
// 已签到:与参考主题一致,入口按钮变为签到详情弹窗触发链接(可点击)。
if ($signed) {
if ($class !== null) {
// 用户卡片签到书签:与参考主题一致,已签到态仅切换为详情弹窗触发链接,书签类名与文本不变。
return jio_get_user_checkin_details_link(
$class,
'<i class="fa far fa-calendar-check ml3 mr6" aria-hidden="true"></i>'
. esc_html__('已签到', 'jio')
);
}
return jio_get_user_checkin_details_link(
'but block c-yellow',
'<i class="fa far fa-calendar-check" aria-hidden="true"></i> '
. esc_html__('今日已签到', 'jio')
);
}
// Card badge variant (explicit $class, e.g. the user-card 签到 badge):
// reference parity renders an <a> so the badge inherits the card font
// instead of the UA button stylesheet (font/UI 1:1 with the reference).
if ($class !== null) {
return '<a class="' . esc_attr($class) . '" href="javascript:;" data-signin-btn'
. ' data-signin-done-label="' . esc_attr__('已签到', 'jio') . '">'
. '<i class="fa far fa-calendar-check ml3 mr6" aria-hidden="true"></i>'
. '<span data-signin-label>' . esc_html__('签到', 'jio') . '</span>'
. '</a>';
}
return '<a class="but block c-yellow" href="javascript:;" data-signin-btn'
. ' data-signin-done-label="' . esc_attr__('今日已签到', 'jio') . '">'
. '<i class="fa far fa-calendar-check" aria-hidden="true"></i> '
. '<span data-signin-label>' . esc_html__('签到领取今日奖励', 'jio') . '</span>'
. '</a>';
}
endif;
if (!function_exists('jio_render_signin_captcha')) :
/**
* Render the single global captcha mount used by every sign-in button.
*/
function jio_render_signin_captcha(): void {
if (
!is_user_logged_in()
|| !class_exists('\Jio\Credits\Signin')
|| !class_exists('\Jio\Settings\Settings')
|| empty(\Jio\Settings\Settings::get_signin_reward_settings()['enabled'])
|| !function_exists('jio_is_captcha_enabled_for')
|| !function_exists('jio_render_captcha')
|| !jio_is_captcha_enabled_for('signin')
) {
return;
}
?>
<div class="jio-signin-captcha" data-signin-captcha>
<?php jio_render_captcha('signin'); ?>
</div>
<?php
}
endif;
add_action('wp_footer', 'jio_render_signin_captcha');
if (!function_exists('jio_header_user_wallet_mini')) :
/**
* Mini wallet tiles: cash balance + credits (reference parity).
*
* Each tile is gated by its payment switch; an all-off configuration
* renders nothing at all.
*/
function jio_header_user_wallet_mini(int $user_id = 0): string {
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
if ($user_id <= 0 || !class_exists('\Jio\Settings\Settings')) {
return '';
}
$balance_on = !empty(\Jio\Settings\Settings::get_payment_recharge_settings()['enabled']);
$points_on = \Jio\Settings\Settings::credits_enabled();
if (!$balance_on && !$points_on) {
return '';
}
$center = function_exists('jio_get_user_center_url') ? jio_get_user_center_url('credits') : '#';
$box = '';
$balance_icon = jio_icon_markup('zibsvg-money-color-2', 'em14');
$points_icon = jio_icon_markup('zibsvg-points-color', 'em14');
if ($balance_on) {
$box .= '<a rel="nofollow" style="flex: 1;" class="muted-box padding-6 flex1 radius4" href="' . esc_url($center) . '">'
. '<div class="muted-2-color px12">' . esc_html__('余额', 'jio')
. '<i class="ml6 fa fas fa-angle-right em12" aria-hidden="true"></i></div>'
. '<div class="flex jsb"><span class="font-bold c-blue-2" data-jio-wallet-value data-jio-count-format="cut-count">'
. esc_html(jio_cut_count((float) jio_user_balance_decimal($user_id)))
. '</span>' . $balance_icon . '</div></a>';
}
if ($points_on) {
$currency = \Jio\Settings\Settings::get_currency_name();
$box .= '<a rel="nofollow" style="flex: 1;" class="muted-box padding-6 flex1 radius4" href="' . esc_url($center) . '">'
. '<div class="muted-2-color px12">' . esc_html($currency)
. '<i class="ml6 fa fas fa-angle-right em12" aria-hidden="true"></i></div>'
. '<div class="flex jsb"><span class="font-bold c-yellow" data-jio-points-value data-jio-count-format="cut-count">'
. esc_html(jio_cut_count(jio_user_points($user_id)))
. '</span>' . $points_icon . '</div></a>';
}
return '<div class="flex ab jsb col-ml6">' . $box . '</div>';
}
endif;
if (!function_exists('jio_header_user_badges_row')) :
/**
* Interaction stats row under the wallet (reference parity).
*/
function jio_header_user_badges_row(int $user_id = 0): string {
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
if ($user_id <= 0 || !function_exists('jio_get_user_badges')) {
return '';
}
$items = jio_get_user_badges($user_id);
if ($items === '') {
return '';
}
return '<div class="em09 author-tag mb10 mt6 flex jc">' . $items . '</div>';
}
endif;
if (!function_exists('jio_header_payvip_bar')) :
/**
* VIP status / open CTA bar (legacy parity).
*/
function jio_header_payvip_bar(int $user_id = 0): string {
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
if ($user_id <= 0) {
return '';
}
$vip = class_exists('\Jio\Settings\Settings')
? \Jio\Settings\Settings::get_payment_vip_settings()
: ['enabled' => false, 'levels' => []];
if (empty($vip['enabled'])) {
return '';
}
$level = function_exists('jio_get_user_vip_level') ? (int) jio_get_user_vip_level($user_id) : 0;
if ($level > 0) {
$levels = is_array($vip['levels'] ?? null) ? $vip['levels'] : [];
$name = (string) ($levels[$level]['name_html'] ?? $levels[$level]['name'] ?? ($level === 2 ? __('二级会员', 'jio') : __('一级会员', 'jio')));
// 到期徽章语义对齐参考主题 zib_get_user_vip_exp_date_text():只有真的拿到
// 到期时间才渲染这枚徽章,已过期显示「会员已过期」否则显示裸日期;显式永久
// 会员显示「永久会员」;拿不到到期数据时参考主题返回 false,整枚徽章不渲染。
$exp_label = '';
if (function_exists('jio_get_user_vip_state')) {
$state = jio_get_user_vip_state($user_id);
$expires = max(0, (int) ($state['expires'] ?? 0));
if ($expires > 0) {
$exp_label = $expires <= time()
? __('会员已过期', 'jio')
: wp_date('Y年m月d日', $expires);
} elseif (!empty($state['is_permanent'])) {
$exp_label = __('永久会员', 'jio');
}
}
$html = '<div class="mt10 em09" style="padding:2px;">';
$html .= '<span class="radius4 payvip-icon btn-block text-center">';
$html .= function_exists('jio_get_vip_icon') ? jio_get_vip_icon($user_id, 'em12 mr6', false) : '';
$html .= '<span>' . wp_kses_post($name) . '</span>';
if ($exp_label !== '') {
$html .= '<span class="ml10 badg jb-yellow vip-expdate-tag">'
. '<i class="fa fas fa-clock mr3" aria-hidden="true"></i>'
. esc_html($exp_label) . '</span>';
}
$html .= '</span></div>';
return $html;
}
if (empty($vip['nav_user_pay_vip'])) {
return '';
}
// 1:1 对齐参考主题 zib_get_header_payvip_icon():通栏、radius4、vip_1 SVG 图标、裸文案。
return '<div class="mt10 em09" style="padding:2px;">'
. '<a class="pay-vip but radius4 payvip-icon btn-block" href="javascript:;">'
. '<svg class="em12 mr6" aria-hidden="true"><use xlink:href="#icon-vip_1"></use></svg>'
. esc_html__('开通会员 尊享会员权益', 'jio')
. '</a></div>';
}
endif;
if (!function_exists('jio_render_signout_modal')) :
/**
* Confirm logout modal markup (once per page).
*/
function jio_render_signout_modal(): void {
static $done = false;
if ($done || !is_user_logged_in()) {
return;
}
$done = true;
$logout = wp_logout_url(home_url('/'));
?>
<div class="modal fade" id="modal_signout" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-mini" role="document">
<div class="modal-content">
<div class="modal-body text-center" style="padding:24px;">
<div class="em2x mb10"><i class="fa fas fa-sign-out-alt" aria-hidden="true"></i></div>
<div class="mb15"><?php esc_html_e('确认退出当前账号?', 'jio'); ?></div>
<div class="but-average flex jc" style="gap:10px;">
<button type="button" class="but" data-dismiss="modal"><?php esc_html_e('取消', 'jio'); ?></button>
<a class="but c-red" href="<?php echo esc_url($logout); ?>"><?php esc_html_e('确认退出', 'jio'); ?></a>
</div>
</div>
</div>
</div>
</div>
<?php
}
endif;