The top-nav publish chip and open-membership chip carried an AKSRT-only class layer (navbar-cta / navbar-cta-text / navbar-newposts / navbar-vip-hover) plus a matching set of CSS overrides that replaced the legacy .but geometry: margin 0.4em -> 0, an extra min-height and flex gap, an FA5 pencil glyph that is not the reference pencil, and label text wrapped in a span. The VIP hover card also had its own positioning override instead of the reference static position. Drop that layer and emit the reference class combination verbatim so the already byte-identical legacy stylesheet owns the geometry again: - publish chip renders newadd-btns but nowave <skin> [radius] btn-newadd with the label echoed as saved (no injected icon, no span) - VIP chip renders pay-vip|signin-loader but jb-red radius payvip-icon with the vip_1 SVG at em12 mr3, inside span.hover-show.inline-block - user-card CTA uses the vip_1 SVG (em12 mr6) instead of fa-gem and drops vip-level, matching zib_get_header_payvip_icon() - both buttons now honour Settings::close_sign(), matching the reference zib_is_close_sign() gate and the floating publish button - header-userbox.css keeps one rule that restores the hover wrapper to a plain block container so .sub-vip-card takes its reference static position; every other override is gone - nav_newposts_text default drops the duplicated fas and uses the FA5 spelling of the reference pencil (fa-pencil-alt, not fa-pen) Dead code removed: aksrt_normalize_header_cta_label(), the unreachable multi-type dropdown branch of aksrt_render_new_add_btns() (only 'post' is supported and only ['post'] is ever passed), and the newadd-btns__toggle / newadd-btns__item / drop-newadd markup it emitted. ml10 is no longer set on the VIP anchor: .aksrt-navbar-actions already supplies the 10px gap the reference gets from ml10, and keeping both would double it to 20px. No migration for sites that already stored the old nav_newposts_text. Verified: node --test across tests/ (603 passing), php -l on the changed PHP files, and a stubbed render of every publish/VIP branch.
271 lines
10 KiB
PHP
271 lines
10 KiB
PHP
<?php
|
|
/**
|
|
* Header user-box density helpers (legacy subset).
|
|
*
|
|
* @package AKSRT
|
|
*/
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
if (!function_exists('aksrt_get_user_checkin_details_link')) :
|
|
/**
|
|
* 已签到详情弹窗触发链接(参考主题 zib_get_user_checkin_details_link 1:1):
|
|
* 打开刷新式 mini 弹窗(高 240,移动端底部弹出,每次都重新拉取)。
|
|
*
|
|
* @param string $class 沿用入口按钮的类。
|
|
* @param string $text 链接内文(含图标)。
|
|
*/
|
|
function aksrt_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-aksrt-modal="remote"'
|
|
. ' data-aksrt-modal-url="' . esc_url(rest_url('aksrt/v1/signin/details')) . '"'
|
|
. ' data-aksrt-modal-class="aksrt-checkin-details-modal modal-mini"'
|
|
. ' data-aksrt-modal-height="240"'
|
|
. ' data-aksrt-modal-mobile-bottom="true"'
|
|
. ' data-aksrt-modal-cache="false">'
|
|
. $text
|
|
. '</a>';
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_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 aksrt_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('\AKSRT\Credits\Signin')) {
|
|
return '';
|
|
}
|
|
$cfg = class_exists('\AKSRT\Settings\Settings')
|
|
? \AKSRT\Settings\Settings::get_signin_reward_settings()
|
|
: ['enabled' => false];
|
|
if (empty($cfg['enabled'])) {
|
|
return '';
|
|
}
|
|
|
|
$signed = \AKSRT\Credits\Signin::get_instance()->is_signed_today($user_id);
|
|
|
|
// 已签到:与参考主题一致,入口按钮变为签到详情弹窗触发链接(可点击)。
|
|
if ($signed) {
|
|
if ($class !== null) {
|
|
// 用户卡片签到书签:保留书签类与 is-done 视觉,仅将行为切换为打开详情弹窗。
|
|
return aksrt_get_user_checkin_details_link(
|
|
$class . ' is-done',
|
|
'<i class="fa far fa-calendar-check ml3 mr6" aria-hidden="true"></i>'
|
|
. '<span>' . esc_html__('已签到', 'aksrt') . '</span>'
|
|
);
|
|
}
|
|
return aksrt_get_user_checkin_details_link(
|
|
'but block c-yellow is-done',
|
|
'<i class="fa far fa-calendar-check" aria-hidden="true"></i> '
|
|
. esc_html__('今日已签到', 'aksrt')
|
|
);
|
|
}
|
|
|
|
// 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-idle-label="' . esc_attr__('签到', 'aksrt') . '"'
|
|
. ' data-signin-done-label="' . esc_attr__('已签到', 'aksrt') . '">'
|
|
. '<i class="fa far fa-calendar-check ml3 mr6" aria-hidden="true"></i>'
|
|
. '<span data-signin-label>' . esc_html__('签到', 'aksrt') . '</span>'
|
|
. '</a>';
|
|
}
|
|
|
|
return '<a class="but block c-yellow" href="javascript:;" data-signin-btn'
|
|
. ' data-signin-idle-label="' . esc_attr__('签到', 'aksrt') . '"'
|
|
. ' data-signin-done-label="' . esc_attr__('今日已签到', 'aksrt') . '">'
|
|
. '<i class="fa far fa-calendar-check" aria-hidden="true"></i> '
|
|
. '<span data-signin-label>' . esc_html__('签到领取今日奖励', 'aksrt') . '</span>'
|
|
. '</a>';
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_render_signin_captcha')) :
|
|
/**
|
|
* Render the single global captcha mount used by every sign-in button.
|
|
*/
|
|
function aksrt_render_signin_captcha(): void {
|
|
if (
|
|
!is_user_logged_in()
|
|
|| !class_exists('\AKSRT\Credits\Signin')
|
|
|| !class_exists('\AKSRT\Settings\Settings')
|
|
|| empty(\AKSRT\Settings\Settings::get_signin_reward_settings()['enabled'])
|
|
|| !function_exists('aksrt_is_captcha_enabled_for')
|
|
|| !function_exists('aksrt_render_captcha')
|
|
|| !aksrt_is_captcha_enabled_for('signin')
|
|
) {
|
|
return;
|
|
}
|
|
?>
|
|
<div class="aksrt-signin-captcha" data-signin-captcha>
|
|
<?php aksrt_render_captcha('signin'); ?>
|
|
</div>
|
|
<?php
|
|
}
|
|
endif;
|
|
add_action('wp_footer', 'aksrt_render_signin_captcha');
|
|
|
|
if (!function_exists('aksrt_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 aksrt_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('\AKSRT\Settings\Settings')) {
|
|
return '';
|
|
}
|
|
|
|
$balance_on = !empty(\AKSRT\Settings\Settings::get_payment_recharge_settings()['enabled']);
|
|
$points_on = \AKSRT\Settings\Settings::credits_enabled();
|
|
if (!$balance_on && !$points_on) {
|
|
return '';
|
|
}
|
|
|
|
$center = function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url('credits') : '#';
|
|
$box = '';
|
|
|
|
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__('余额', 'aksrt')
|
|
. '<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-aksrt-wallet-value data-aksrt-count-format="cut-count">'
|
|
. esc_html(aksrt_cut_count((float) aksrt_user_balance_decimal($user_id)))
|
|
. '</span><i class="fa fas fa-money-bill-wave em14 c-blue-2" aria-hidden="true"></i></div></a>';
|
|
}
|
|
|
|
if ($points_on) {
|
|
$currency = \AKSRT\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-aksrt-points-value data-aksrt-count-format="cut-count">'
|
|
. esc_html(aksrt_cut_count(aksrt_user_points($user_id)))
|
|
. '</span><i class="fa fas fa-coins em14 c-yellow" aria-hidden="true"></i></div></a>';
|
|
}
|
|
|
|
return '<div class="flex ab jsb col-ml6">' . $box . '</div>';
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_header_user_badges_row')) :
|
|
/**
|
|
* Interaction stats row under the wallet (reference parity).
|
|
*/
|
|
function aksrt_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('aksrt_get_user_badges')) {
|
|
return '';
|
|
}
|
|
$items = aksrt_get_user_badges($user_id);
|
|
if ($items === '') {
|
|
return '';
|
|
}
|
|
return '<div class="em09 author-tag mb10 mt6 flex jc">' . $items . '</div>';
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_header_payvip_bar')) :
|
|
/**
|
|
* VIP status / open CTA bar (legacy parity).
|
|
*/
|
|
function aksrt_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('\AKSRT\Settings\Settings')
|
|
? \AKSRT\Settings\Settings::get_payment_vip_settings()
|
|
: ['enabled' => false, 'levels' => []];
|
|
if (empty($vip['enabled'])) {
|
|
return '';
|
|
}
|
|
|
|
$level = function_exists('aksrt_get_user_vip_level') ? (int) aksrt_get_user_vip_level($user_id) : 0;
|
|
if ($level > 0) {
|
|
$levels = is_array($vip['levels'] ?? null) ? $vip['levels'] : [];
|
|
$name = (string) ($levels[$level]['name'] ?? ($level === 2 ? __('二级会员', 'aksrt') : __('一级会员', 'aksrt')));
|
|
// 到期徽章语义对齐参考主题 zib_get_user_vip_exp_date_text():只有真的拿到
|
|
// 到期时间才渲染这枚徽章,已过期显示「会员已过期」否则显示裸日期;显式永久
|
|
// 会员显示「永久会员」;拿不到到期数据时参考主题返回 false,整枚徽章不渲染。
|
|
$exp_label = '';
|
|
if (function_exists('aksrt_get_user_vip_state')) {
|
|
$state = aksrt_get_user_vip_state($user_id);
|
|
$expires = max(0, (int) ($state['expires'] ?? 0));
|
|
if ($expires > 0) {
|
|
$exp_label = $expires <= time()
|
|
? __('会员已过期', 'aksrt')
|
|
: wp_date('Y年m月d日', $expires);
|
|
} elseif (!empty($state['is_permanent'])) {
|
|
$exp_label = __('永久会员', 'aksrt');
|
|
}
|
|
}
|
|
$html = '<div class="mt10 em09" style="padding:2px;">';
|
|
$html .= '<span class="radius4 payvip-icon btn-block text-center">';
|
|
$html .= function_exists('aksrt_get_vip_icon') ? aksrt_get_vip_icon($user_id, 'em12 mr6', false) : '';
|
|
$html .= '<span>' . esc_html($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__('开通会员 尊享会员权益', 'aksrt')
|
|
. '</a></div>';
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_render_signout_modal')) :
|
|
/**
|
|
* Confirm logout modal markup (once per page).
|
|
*/
|
|
function aksrt_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('确认退出当前账号?', 'aksrt'); ?></div>
|
|
<div class="but-average flex jc" style="gap:10px;">
|
|
<button type="button" class="but" data-dismiss="modal"><?php esc_html_e('取消', 'aksrt'); ?></button>
|
|
<a class="but c-red" href="<?php echo esc_url($logout); ?>"><?php esc_html_e('确认退出', 'aksrt'); ?></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
endif;
|