200 lines
11 KiB
PHP
200 lines
11 KiB
PHP
<?php
|
|
|
|
namespace AKSRT\WidgetSystem\Renderers;
|
|
|
|
use AKSRT\WidgetSystem\RendererHelpers;
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
/** Render login, author, ranking and user-list widgets. */
|
|
final class UserRenderer {
|
|
public static function render(string $slug, array $instance, array $context = []): string {
|
|
unset($context);
|
|
switch ($slug) {
|
|
case 'user_card': return self::user_card($instance);
|
|
case 'author_card': return self::author_card($instance);
|
|
case 'user_ranking': return self::ranking($instance);
|
|
case 'user_list': return self::user_list($instance);
|
|
}
|
|
return '';
|
|
}
|
|
|
|
private static function user_card(array $i): string {
|
|
$user_id = get_current_user_id();
|
|
if ($user_id <= 0) {
|
|
return self::guest_card($i);
|
|
}
|
|
$user = get_userdata($user_id);
|
|
return $user instanceof \WP_User ? self::profile_card($user, $i, true) : '';
|
|
}
|
|
|
|
/**
|
|
* 未登录卡片使用独立组件结构,避免嵌套全局 .widget 卡片外观。
|
|
*/
|
|
private static function guest_card(array $i): string {
|
|
$login = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url();
|
|
$register = function_exists('aksrt_get_register_url') ? aksrt_get_register_url() : wp_registration_url();
|
|
$title = trim((string) ($i['loged_title'] ?? ''));
|
|
if ($title === '') {
|
|
$title = __('Hi!请登录', 'aksrt');
|
|
}
|
|
|
|
$card_classes = 'aksrt-user-card is-guest';
|
|
$cover = '';
|
|
if (!empty($i['show_cover'])) {
|
|
$cover_url = function_exists('aksrt_get_user_cover_url') ? aksrt_get_user_cover_url(0) : get_theme_file_uri('assets/img/user_t.jpg');
|
|
$cover = '<div class="aksrt-user-card__cover"><img' . aksrt_get_lazy_attr('lazy_cover', $cover_url, 'lazyload fit-cover', aksrt_get_lazy_thumb('lg')) . ' alt=""></div>';
|
|
} else {
|
|
$card_classes .= ' no-cover';
|
|
}
|
|
|
|
$buttons = '<a class="signin-loader aksrt-widget-button is-primary" href="' . esc_url($login) . '"><i class="fa fas fa-fw fa-sign-in-alt" aria-hidden="true"></i>' . esc_html__('登录', 'aksrt') . '</a>';
|
|
if (get_option('users_can_register')) {
|
|
$buttons .= '<a class="signup-loader aksrt-widget-button is-secondary" href="' . esc_url($register) . '"><i class="fa fas fa-fw fa-user-plus" aria-hidden="true"></i>' . esc_html__('注册', 'aksrt') . '</a>';
|
|
}
|
|
|
|
$oauth_html = '';
|
|
if (class_exists('AKSRT\\Auth\\OAuth')) {
|
|
$oauth = \AKSRT\Auth\OAuth::get_instance();
|
|
if (is_callable([$oauth, 'render_social_buttons'])) {
|
|
$oauth_html = (string) $oauth->render_social_buttons(__('社交账号登录', 'aksrt'));
|
|
}
|
|
}
|
|
|
|
$avatar = '<span class="aksrt-user-card__avatar">' . aksrt_get_avatar_html(0, 80, ['class' => 'avatar fit-cover']) . '</span>';
|
|
|
|
return '<article class="' . esc_attr($card_classes) . '">' . $cover
|
|
. '<div class="aksrt-user-card__body">'
|
|
. $avatar
|
|
. '<p class="aksrt-user-card__guest-title">' . esc_html($title) . '</p>'
|
|
. '<div class="aksrt-user-card__guest-actions">' . $buttons . '</div>'
|
|
. $oauth_html
|
|
. '</div></article>';
|
|
}
|
|
|
|
private static function author_card(array $i): string {
|
|
$post = get_post();
|
|
if (!$post instanceof \WP_Post) {
|
|
return '';
|
|
}
|
|
$user = get_userdata((int) $post->post_author);
|
|
return $user instanceof \WP_User ? self::profile_card($user, $i, false) : '';
|
|
}
|
|
|
|
private static function profile_card(\WP_User $user, array $i, bool $self_card): string {
|
|
$user_id = (int) $user->ID;
|
|
$home = function_exists('aksrt_get_user_home_url') ? aksrt_get_user_home_url($user) : get_author_posts_url($user_id);
|
|
$cover = function_exists('aksrt_get_user_cover_url') ? aksrt_get_user_cover_url($user_id) : '';
|
|
$description = function_exists('aksrt_get_user_description') ? aksrt_get_user_description($user_id) : (string) $user->description;
|
|
$followers = class_exists('AKSRT\\User\\Follow') ? \AKSRT\User\Follow::get_instance()->get_follower_count($user_id) : 0;
|
|
$following = class_exists('AKSRT\\User\\Follow') ? \AKSRT\User\Follow::get_instance()->get_following_count($user_id) : 0;
|
|
$html = '<article class="aksrt-user-card' . (!$self_card ? ' is-author' : '') . (empty($i['show_cover']) ? ' no-cover' : '') . '">';
|
|
if (!empty($i['show_cover'])) {
|
|
$html .= '<div class="aksrt-user-card__cover"' . ($cover ? ' style="background-image:url(' . esc_url($cover) . ')"' : '') . '></div>';
|
|
}
|
|
$html .= '<div class="aksrt-user-card__body"><a class="aksrt-user-card__avatar" href="' . esc_url($home) . '">' . (function_exists('aksrt_get_avatar_html') ? aksrt_get_avatar_html($user_id, 96) : get_avatar($user_id, 96)) . '</a><h3><a href="' . esc_url($home) . '">' . esc_html($user->display_name) . '</a></h3>';
|
|
if (function_exists('aksrt_render_user_identity_chips')) {
|
|
$html .= '<div class="aksrt-user-card__identity">' . aksrt_render_user_identity_chips($user_id, 'widget') . '</div>';
|
|
}
|
|
$html .= '<p>' . esc_html(wp_trim_words($description, 24)) . '</p><div class="aksrt-user-card__stats"><span><b>' . number_format_i18n(count_user_posts($user_id, 'post', true)) . '</b>' . esc_html__('文章', 'aksrt') . '</span><span><b>' . number_format_i18n($followers) . '</b>' . esc_html__('粉丝', 'aksrt') . '</span><span><b>' . number_format_i18n($following) . '</b>' . esc_html__('关注', 'aksrt') . '</span></div>';
|
|
if (!empty($i['show_buttons'])) {
|
|
$html .= '<div class="aksrt-user-card__actions">' . self::action((string) $i['primary_action'], $user, true) . self::action((string) $i['secondary_action'], $user, false) . '</div>';
|
|
}
|
|
if (!$self_card && get_current_user_id() > 0 && get_current_user_id() !== $user_id) {
|
|
$active = class_exists('AKSRT\\User\\Follow') && \AKSRT\User\Follow::get_instance()->is_following(get_current_user_id(), $user_id);
|
|
$html .= '<button class="aksrt-user-card__follow' . ($active ? ' is-following' : '') . '" type="button" data-aksrt-follow="' . $user_id . '">' . esc_html($active ? __('已关注', 'aksrt') : __('关注', 'aksrt')) . '</button>';
|
|
}
|
|
$html .= '</div>';
|
|
if (!empty($i['show_posts']) && function_exists('aksrt_render_user_card_posts')) {
|
|
$html .= '<div class="aksrt-user-card__posts">' . aksrt_render_user_card_posts(['user_id' => $user_id, 'count' => 4, 'post_style' => 'mini', 'show_empty' => false]) . '</div>';
|
|
}
|
|
return $html . '</article>';
|
|
}
|
|
|
|
private static function action(string $action, \WP_User $user, bool $primary): string {
|
|
$labels = ['home' => __('个人主页', 'aksrt'), 'submit' => __('发布文章', 'aksrt'), 'vip' => __('会员中心', 'aksrt'), 'orders' => __('订单中心', 'aksrt'), 'recharge' => __('余额充值', 'aksrt'), 'signin' => __('签到', 'aksrt')];
|
|
$variant = $primary ? ' is-primary' : ' is-secondary';
|
|
if ($action === 'signin' && function_exists('aksrt_header_user_checkin_btn') && get_current_user_id() === (int) $user->ID) {
|
|
return '<span class="aksrt-user-card__checkin' . $variant . '">' . aksrt_header_user_checkin_btn((int) $user->ID, true) . '</span>';
|
|
}
|
|
if ($action === 'home') {
|
|
$url = function_exists('aksrt_get_user_home_url') ? aksrt_get_user_home_url($user) : get_author_posts_url((int) $user->ID);
|
|
} elseif ($action === 'submit') {
|
|
$url = function_exists('aksrt_get_new_post_url') ? aksrt_get_new_post_url() : home_url('/submit/');
|
|
} else {
|
|
$tab = $action === 'signin' ? 'credits' : $action;
|
|
$url = function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url($tab) : home_url('/user/');
|
|
}
|
|
if ($url === '') {
|
|
return '';
|
|
}
|
|
return '<a class="aksrt-widget-button' . $variant . '" href="' . esc_url($url) . '">' . esc_html($labels[$action] ?? $labels['home']) . '</a>';
|
|
}
|
|
|
|
private static function ranking(array $i): string {
|
|
$users = get_users(['number' => 200, 'orderby' => 'registered', 'order' => 'DESC']);
|
|
$metric = (string) $i['orderby'];
|
|
usort($users, static fn(\WP_User $a, \WP_User $b): int => self::metric($b, $metric) <=> self::metric($a, $metric));
|
|
$users = array_slice($users, 0, (int) $i['number']);
|
|
if (!$users) {
|
|
return RendererHelpers::empty_state(__('暂无用户数据', 'aksrt'));
|
|
}
|
|
$html = '<ol class="aksrt-user-ranking">';
|
|
foreach ($users as $index => $user) {
|
|
$html .= '<li><span class="aksrt-user-ranking__index' . (!empty($i['show_badge']) && $index < 3 ? ' is-top' : '') . '">' . ($index + 1) . '</span>' . self::user_tile($user, self::metric($user, $metric), self::metric_label($metric)) . '</li>';
|
|
}
|
|
return $html . '</ol>';
|
|
}
|
|
|
|
private static function user_list(array $i): string {
|
|
$args = ['number' => 200];
|
|
if (!empty($i['include'])) {
|
|
$args['include'] = RendererHelpers::ids((string) $i['include']);
|
|
}
|
|
if (!empty($i['exclude'])) {
|
|
$args['exclude'] = RendererHelpers::ids((string) $i['exclude']);
|
|
}
|
|
$users = get_users($args);
|
|
$orderby = (string) $i['orderby'];
|
|
usort($users, static function (\WP_User $a, \WP_User $b) use ($orderby): int {
|
|
if ($orderby === 'display_name') {
|
|
return strcasecmp($a->display_name, $b->display_name);
|
|
}
|
|
if ($orderby === 'registered') {
|
|
return strcmp($b->user_registered, $a->user_registered);
|
|
}
|
|
return self::metric($b, $orderby) <=> self::metric($a, $orderby);
|
|
});
|
|
$html = '<div class="aksrt-widget-grid aksrt-user-list">';
|
|
foreach (array_slice($users, 0, (int) $i['number']) as $user) {
|
|
$html .= '<article>' . self::user_tile($user, self::metric($user, $orderby), self::metric_label($orderby)) . '</article>';
|
|
}
|
|
return $html . '</div>';
|
|
}
|
|
|
|
private static function user_tile(\WP_User $user, int $value, string $label): string {
|
|
$url = function_exists('aksrt_get_user_home_url') ? aksrt_get_user_home_url($user) : get_author_posts_url((int) $user->ID);
|
|
return '<a class="aksrt-user-tile" href="' . esc_url($url) . '">' . (function_exists('aksrt_get_avatar_html') ? aksrt_get_avatar_html($user->ID, 64) : get_avatar($user->ID, 64)) . '<span><strong>' . esc_html($user->display_name) . '</strong><small>' . esc_html($label) . ' ' . number_format_i18n($value) . '</small></span></a>';
|
|
}
|
|
|
|
private static function metric(\WP_User $user, string $metric): int {
|
|
$id = (int) $user->ID;
|
|
if ($metric === 'points') {
|
|
return aksrt_user_points($id);
|
|
}
|
|
if ($metric === 'followers') {
|
|
return class_exists('AKSRT\\User\\Follow') ? (int) \AKSRT\User\Follow::get_instance()->get_follower_count($id) : 0;
|
|
}
|
|
if ($metric === 'post_count') {
|
|
return (int) count_user_posts($id, 'post', true);
|
|
}
|
|
$key = $metric === 'checkin_continuous_day' ? 'aksrt_checkin_continuous_day' : 'aksrt_checkin_all_day';
|
|
return (int) get_user_meta($id, $key, true);
|
|
}
|
|
|
|
private static function metric_label(string $metric): string {
|
|
$labels = ['points' => __('积分', 'aksrt'), 'followers' => __('粉丝', 'aksrt'), 'post_count' => __('文章', 'aksrt'), 'registered' => __('新加入', 'aksrt'), 'display_name' => __('用户', 'aksrt'), 'checkin_all_day' => __('累计签到', 'aksrt'), 'checkin_continuous_day' => __('连续签到', 'aksrt')];
|
|
return $labels[$metric] ?? $labels['points'];
|
|
}
|
|
}
|