Files
wordpress-theme-aksrt/src/AKSRT/Widgets/AboutWidget.php
T
kate522 5f398dd9d0 feat(widgets): unregister core WP widgets; About guest signin-loader
Align widget area with zibll by removing default RSS/search/calendar
widgets, and make About guest login buttons open auth modal classes.
2026-07-19 01:28:13 +08:00

379 lines
12 KiB
PHP
Raw 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
/**
* @package AKSRT
*/
namespace AKSRT\Widgets;
defined('ABSPATH') || exit;
class AboutWidget extends \WP_Widget {
public function __construct() {
parent::__construct(
'aksrt_about',
esc_html__('AKSRT 用户中心', 'aksrt'),
[
'description' => esc_html__('登录状态面板:未登录显示登录/注册按钮,已登录显示用户信息与快捷入口', 'aksrt'),
'customize_selective_refresh' => true,
]
);
}
/**
* 前端渲染
*/
public function widget($args, $instance): void {
echo $args['before_widget'];
$title = apply_filters('widget_title', $instance['title'] ?? '', $instance, $this->id_base);
if ($title) {
echo $args['before_title'] . esc_html($title) . $args['after_title'];
}
// 判断登录状态
if (is_user_logged_in()) {
$this->render_logged_in();
} else {
$this->render_logged_out($instance);
}
// 输出内联样式 & JS(仅在本 widget 实例加载时注入一次)
$this->inline_assets();
echo $args['after_widget'];
}
// ==========================================
// 已登录状态渲染(Zibll 风格用户卡片)
// ==========================================
private function render_logged_in(): void {
$u = wp_get_current_user();
$avatar = get_avatar_url($u->ID, ['size' => 160]);
$profile = aksrt_get_user_center_url();
$logout = aksrt_get_logout_url(home_url('/'));
// 封面图:用户在用户中心上传的背景图 > 默认背景图
$cover = get_user_meta($u->ID, 'aksrt_background_image', true);
if (! $cover) {
$cover = get_theme_file_uri('assets/img/person_background.png');
}
?>
<div class="aksrt-user-card">
<div class="aksrt-user-card__cover" style="padding-bottom: 50%;">
<img class="aksrt-user-card__cover-img" src="<?php echo esc_url($cover); ?>" alt=""<?php echo function_exists('aksrt_lazy_loading') ? aksrt_lazy_loading('widget') : ' loading="lazy"'; ?>>
</div>
<div class="aksrt-user-card__content">
<div class="aksrt-user-card__avatar">
<img src="<?php echo esc_url($avatar); ?>" alt="" width="80" height="80"<?php echo function_exists('aksrt_lazy_loading') ? aksrt_lazy_loading('avatar') : ' loading="lazy"'; ?>>
</div>
<div class="aksrt-user-card__info">
<div class="aksrt-user-card__name"><?php echo esc_html($u->display_name); ?></div>
<div class="aksrt-user-card__desc"><?php echo esc_html($u->user_email); ?></div>
</div>
<div class="aksrt-user-card__btns">
<a class="aksrt-user-card__btn aksrt-user-card__btn--primary" href="<?php echo esc_url($profile); ?>">
<i class="fas fa-user" aria-hidden="true"></i> <?php esc_html_e('个人主页', 'aksrt'); ?>
</a>
<a class="aksrt-user-card__btn aksrt-user-card__btn--outline" href="<?php echo esc_url($logout); ?>">
<i class="fas fa-sign-out-alt" aria-hidden="true"></i> <?php esc_html_e('退出', 'aksrt'); ?>
</a>
</div>
</div>
</div>
<?php
}
// ==========================================
// 未登录状态渲染(Zibll 风格用户卡片)
// ==========================================
private function render_logged_out(array $instance = []): void {
$login_url = aksrt_get_login_url();
$register_url = aksrt_get_register_url();
// 封面图:后台配置 > 默认
$cover = ! empty($instance['cover']) ? $instance['cover'] : get_theme_file_uri('assets/img/widgets-original.png');
$avatar = get_avatar_url(0, ['size' => 160, 'default' => 'mystery']);
$oauth_html = '';
if (class_exists('\AKSRT\Auth\OAuth')) {
$oauth = \AKSRT\Auth\OAuth::get_instance();
if (method_exists($oauth, 'render_social_buttons')) {
$oauth_html = (string) $oauth->render_social_buttons(__('社交账号登录', 'aksrt'));
} elseif (method_exists($oauth, 'get_login_buttons')) {
$oauth_html = (string) $oauth->get_login_buttons();
}
}
?>
<div class="aksrt-user-card">
<div class="aksrt-user-card__cover" style="padding-bottom: 50%;">
<?php if ($cover) : ?>
<img class="aksrt-user-card__cover-img" src="<?php echo esc_url($cover); ?>" alt=""<?php echo function_exists('aksrt_lazy_loading') ? aksrt_lazy_loading('widget') : ' loading="lazy"'; ?>>
<?php endif; ?>
</div>
<div class="aksrt-user-card__content">
<div class="aksrt-user-card__avatar">
<img src="<?php echo esc_url($avatar); ?>" alt="" width="80" height="80"<?php echo function_exists('aksrt_lazy_loading') ? aksrt_lazy_loading('avatar') : ' loading="lazy"'; ?>>
</div>
<div class="aksrt-user-card__info">
<div class="aksrt-user-card__desc"><?php esc_html_e('Hi! 请登录', 'aksrt'); ?></div>
</div>
<div class="aksrt-user-card__btns">
<a class="aksrt-user-card__btn aksrt-user-card__btn--primary signin-loader" href="<?php echo esc_url($login_url); ?>"><?php esc_html_e('登 录', 'aksrt'); ?></a>
<?php if (get_option('users_can_register')) : ?>
<a class="aksrt-user-card__btn aksrt-user-card__btn--outline signup-loader" href="<?php echo esc_url($register_url); ?>"><?php esc_html_e('注 册', 'aksrt'); ?></a>
<?php endif; ?>
</div>
<?php if ($oauth_html) : ?>
<div class="aksrt-user-card__oauth">
<div class="aksrt-user-card__divider"><?php esc_html_e('社交账号登录', 'aksrt'); ?></div>
<div class="aksrt-user-card__social-icons">
<?php echo $oauth_html; ?>
</div>
</div>
<?php endif; ?>
</div>
</div>
<?php
}
// ==========================================
// 内联样式(Zibll 风格用户卡片,只输出一次)
// ==========================================
private function inline_assets(): void {
if (did_action('aksrt_user_card_assets')) {
return;
}
do_action('aksrt_user_card_assets');
?>
<style>
/* ========== AKSRT 用户卡片(Zibll 风格) ========== */
/*
* 消除"卡片套卡片":
* 外层 .widget-card 提供 background/shadow/border-radius/padding:15px
* 内层 .aksrt-user-card 用负 margin 把封面图扩展到外层边缘,
* 使封面图与外层卡片融为一体,不再有 15px 间距。
*/
.widget-card > .aksrt-user-card {
margin: -15px -15px 0;
overflow: hidden;
border-radius: var(--radius-card, 8px) var(--radius-card, 8px) 0 0;
}
/* 有标题时:取消标题下方的 margin-bottom,因为卡片已无额外间距 */
.widget.aksrt_about.widget-card > .widget-title + .aksrt-user-card {
margin-top: -5px;
}
/* ---- 封面图 ---- */
.aksrt-user-card__cover {
position: relative;
overflow: hidden;
background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark, #4f46e5));
}
.aksrt-user-card__cover-img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
/* ---- 内容区 — 悬浮在封面上方 ---- */
.aksrt-user-card__content {
padding: 15px;
margin-top: -55px;
position: relative;
text-align: center;
}
/* ---- 头像(绝对居中) ---- */
.aksrt-user-card__avatar {
text-align: center;
line-height: 0;
}
.aksrt-user-card__avatar img {
display: block;
width: 80px;
height: 80px;
margin: 0 auto;
border-radius: 50%;
border: 3px solid var(--color-primary);
object-fit: cover;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
/* ---- 用户信息 ---- */
.aksrt-user-card__info {
margin-top: 12px;
text-align: center;
}
.aksrt-user-card__name {
font-size: 1.1em;
font-weight: bold;
color: var(--color-ink, var(--color-text));
}
.aksrt-user-card__desc {
font-size: 13px;
color: var(--color-text-muted, #9ca3af);
margin-top: 4px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* ---- 按钮组 ---- */
.aksrt-user-card__btns {
display: flex;
gap: 10px;
justify-content: center;
margin-top: 16px;
}
.aksrt-user-card__btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 8px 20px;
border-radius: 20px;
font-size: 13px;
font-weight: 600;
text-decoration: none;
transition: opacity 0.2s ease, transform 0.15s ease;
flex: 1;
max-width: 140px;
}
.aksrt-user-card__btn:hover {
opacity: 0.88;
transform: translateY(-1px);
}
.aksrt-user-card__btn:active {
transform: translateY(0);
}
.aksrt-user-card__btn--primary {
background: var(--color-primary);
color: #fff;
}
.aksrt-user-card__btn--outline {
background: var(--color-primary-softer, rgba(136,171,218,0.05));
color: var(--color-primary);
border: 1px solid var(--color-primary-50, rgba(136,171,218,0.12));
}
/* ---- OAuth 社交登录 ---- */
.aksrt-user-card__oauth {
margin-top: 12px;
}
.aksrt-user-card__divider {
font-size: 12px;
color: var(--color-text-muted, #9ca3af);
margin-bottom: 10px;
position: relative;
}
.aksrt-user-card__divider::before,
.aksrt-user-card__divider::after {
content: '';
position: absolute;
top: 50%;
width: 28%;
height: 1px;
background: var(--color-border, #e5e7eb);
}
.aksrt-user-card__divider::before { left: 0; }
.aksrt-user-card__divider::after { right: 0; }
.aksrt-user-card__social-icons {
display: flex;
flex-wrap: wrap;
gap: 8px;
justify-content: center;
}
.aksrt-user-card__social-icons a {
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
border-radius: 50%;
font-size: 15px;
color: var(--color-text-muted, #6b7280);
background: var(--color-bg-tertiary, #f3f4f6);
text-decoration: none;
transition: background 0.18s ease, color 0.18s ease;
}
.aksrt-user-card__social-icons a:hover {
background: var(--color-primary);
color: #fff;
}
/* ---- 暗色适配 ---- */
html.dark .aksrt-user-card__avatar img,
body.theme-dark .aksrt-user-card__avatar img {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}
html.dark .aksrt-user-card__social-icons a,
body.theme-dark .aksrt-user-card__social-icons a {
background: rgba(255, 255, 255, 0.08);
}
html.dark .aksrt-user-card__social-icons a:hover,
body.theme-dark .aksrt-user-card__social-icons a:hover {
background: var(--color-primary);
}
/* ---- 移动端 ---- */
@media screen and (max-width: 480px) {
.aksrt-user-card__content {
margin-top: -45px;
}
.aksrt-user-card__avatar img {
width: 68px;
height: 68px;
}
}
</style>
<?php
}
// ==========================================
// 后台表单
// ==========================================
public function form($instance): void {
$title = $instance['title'] ?? '';
$cover = $instance['cover'] ?? '';
$default_cover = get_theme_file_uri('assets/img/widgets-original.png');
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>"><?php esc_html_e('标题(可选):', 'aksrt'); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>"
name="<?php echo $this->get_field_name('title'); ?>"
type="text" value="<?php echo esc_attr($title); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id('cover'); ?>"><?php esc_html_e('未登录背景图 URL:', 'aksrt'); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id('cover'); ?>"
name="<?php echo $this->get_field_name('cover'); ?>"
type="url" value="<?php echo esc_attr($cover); ?>"
placeholder="<?php echo esc_attr($default_cover); ?>">
</p>
<p style="font-size:12px;color:#666;">
<?php esc_html_e('留空则使用默认背景图。已登录用户可使用个人封面图。', 'aksrt'); ?>
</p>
<?php
}
public function update($new_instance, $old_instance): array {
return [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
'cover' => esc_url_raw($new_instance['cover'] ?? ''),
];
}
}