- 通用 fa fa-X 前缀改为 fa fas fa-X(12 个生产文件) - 重命名图标映射:fa-sign-in→fa-sign-in-alt、fa-envelope-o→far fa-envelope、 fa-trash-o→far fa-trash-alt、fa-file-image-o→far fa-file-image、 fa-dot-circle-o→far fa-dot-circle、fa-play-circle-o→far fa-play-circle、 fa-pencil→fas fa-pencil-alt - 修复 FA5 中不存在的 fa-pencil-square→fas fa-edit
311 lines
12 KiB
PHP
311 lines
12 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 {
|
||
if (class_exists('AKSRT\\Settings\\Settings') && \AKSRT\Settings\Settings::close_sign()) {
|
||
return '';
|
||
}
|
||
|
||
$user_id = get_current_user_id();
|
||
if ($user_id <= 0) {
|
||
return self::guest_card($i);
|
||
}
|
||
$user = get_userdata($user_id);
|
||
if (!$user instanceof \WP_User) {
|
||
return '';
|
||
}
|
||
|
||
return '<div class="mb20">' . self::card_box($user_id, [
|
||
'show_posts' => false,
|
||
'show_checkin' => true,
|
||
'show_img_bg' => !isset($i['show_img_bg']) || !empty($i['show_img_bg']),
|
||
] + self::card_button_args($i)) . '</div>';
|
||
}
|
||
|
||
private static function author_card(array $i): string {
|
||
$post = get_post();
|
||
if (!$post instanceof \WP_Post) {
|
||
return '';
|
||
}
|
||
$user = get_userdata((int) $post->post_author);
|
||
if (!$user instanceof \WP_User) {
|
||
return '';
|
||
}
|
||
$post_style = sanitize_key((string) ($i['post_style'] ?? 'mini'));
|
||
|
||
return '<div class="mb20">' . self::card_box((int) $user->ID, [
|
||
'show_img_bg' => !isset($i['show_img_bg']) || !empty($i['show_img_bg']),
|
||
'show_posts' => !isset($i['show_posts']) || !empty($i['show_posts']),
|
||
'limit' => max(0, min(12, (int) ($i['limit'] ?? 6))),
|
||
'orderby' => sanitize_key((string) ($i['orderby'] ?? 'date')),
|
||
'post_type' => 'post',
|
||
'post_style' => $post_style === 'card' ? 'card' : 'mini',
|
||
] + self::card_button_args($i)) . '</div>';
|
||
}
|
||
|
||
private static function card_button_args(array $i): array {
|
||
return [
|
||
'show_button' => !isset($i['show_button']) || !empty($i['show_button']),
|
||
'button_1' => (string) ($i['button_1'] ?? 'post'),
|
||
'button_1_class' => (string) ($i['button_1_class'] ?? 'jb-pink'),
|
||
'button_1_text' => (string) ($i['button_1_text'] ?? ''),
|
||
'button_2' => (string) ($i['button_2'] ?? 'center'),
|
||
'button_2_class' => (string) ($i['button_2_class'] ?? 'jb-blue'),
|
||
'button_2_text' => (string) ($i['button_2_text'] ?? ''),
|
||
];
|
||
}
|
||
|
||
/**
|
||
* 未登录卡片(legacy zib_get_user_singin_page_box parity)。
|
||
*/
|
||
private static function guest_card(array $i): string {
|
||
$title = trim((string) ($i['loged_title'] ?? ''));
|
||
if ($title === '') {
|
||
$title = __('Hi!请登录', 'aksrt');
|
||
}
|
||
|
||
$cover = !isset($i['show_img_bg']) || !empty($i['show_img_bg'])
|
||
? self::cover(0, 'lazy_other')
|
||
: '';
|
||
$avatar = '<span class="avatar-img avatar-lg"><img alt="' . esc_attr__('默认头像', 'aksrt') . '" class="fit-cover avatar" src="' . esc_url(aksrt_get_default_avatar_url()) . '"></span>';
|
||
|
||
$buttons = '<a href="javascript:;" class="signin-loader but jb-blue padding-lg"><i class="fa fas fa-fw fa-sign-in-alt" aria-hidden="true"></i>' . esc_html__('登录', 'aksrt') . '</a>';
|
||
$registration_enabled = class_exists('AKSRT\\Settings\\Settings')
|
||
? \AKSRT\Settings\Settings::registration_enabled()
|
||
: (bool) get_option('users_can_register');
|
||
if ($registration_enabled) {
|
||
$buttons .= '<a href="javascript:;" class="signup-loader ml10 but jb-yellow padding-lg">' . aksrt_renderer_svg_icon('signup') . esc_html__('注册', 'aksrt') . '</a>';
|
||
}
|
||
|
||
return '<div class="mb20"><div class="user-card zib-widget widget">' . $cover
|
||
. '<div class="card-content mt10">'
|
||
. '<div class="user-content">'
|
||
. '<div class="user-avatar">' . $avatar . '</div>'
|
||
. '<div class="user-info mt10">'
|
||
. '<div class="text-center">'
|
||
. '<p class="muted-color box-body em12">' . esc_html($title) . '</p>'
|
||
. '<p>' . $buttons . '</p>'
|
||
. self::social_login()
|
||
. '</div></div></div></div></div></div>';
|
||
}
|
||
|
||
private static function social_login(): string {
|
||
if (!class_exists('AKSRT\\Auth\\OAuth')) {
|
||
return '';
|
||
}
|
||
$items = \AKSRT\Auth\OAuth::get_instance()->get_auth_providers_data();
|
||
if ($items === []) {
|
||
return '';
|
||
}
|
||
|
||
$html = '<div class="social-separator separator muted-3-color em09 mt20 mb20">' . esc_html__('社交账号登录', 'aksrt') . '</div><div class="social_loginbar">';
|
||
foreach ($items as $item) {
|
||
$name = sanitize_html_class((string) ($item['name'] ?? ''));
|
||
$style_name = str_starts_with($name, 'clogin_') ? substr($name, 7) : $name;
|
||
$label = trim((string) ($item['label'] ?? ''));
|
||
$url = (string) ($item['url'] ?? '');
|
||
if ($name === '' || $style_name === '' || $label === '' || $url === '') {
|
||
continue;
|
||
}
|
||
$html .= '<a rel="nofollow" href="' . esc_url($url) . '" class="social-login-item ' . esc_attr($style_name) . '" data-provider="' . esc_attr($name) . '" aria-label="' . esc_attr(sprintf(__('%s登录', 'aksrt'), $label)) . '" title="' . esc_attr($label) . '">' . (string) ($item['icon'] ?? '') . '</a>';
|
||
}
|
||
return $html . '</div>';
|
||
}
|
||
|
||
private static function cover(int $user_id, string $lazy_type): string {
|
||
$cover_url = aksrt_get_user_cover_url($user_id);
|
||
if ($cover_url === '') {
|
||
return '';
|
||
}
|
||
return '<div class="user-cover graphic" style="padding-bottom: 50%;"><img' . aksrt_get_lazy_attr($lazy_type, $cover_url, 'fit-cover', aksrt_get_lazy_thumb()) . ' alt="' . esc_attr__('用户封面', 'aksrt') . '"></div>';
|
||
}
|
||
|
||
/**
|
||
* 登录卡片(legacy zib_get_user_card_box parity)。
|
||
*
|
||
* @param int $user_id 卡片用户。
|
||
* @param array $args show_posts/show_checkin/show_img_bg/show_button/button_1,2 与文章模块参数。
|
||
*/
|
||
private static function card_box(int $user_id, array $args = []): string {
|
||
$args = wp_parse_args($args, [
|
||
'show_posts' => true,
|
||
'show_checkin' => false,
|
||
'show_img_bg' => false,
|
||
'show_button' => true,
|
||
'button_1' => 'post',
|
||
'button_1_class' => 'jb-pink',
|
||
'button_1_text' => __('发布文章', 'aksrt'),
|
||
'button_2' => 'center',
|
||
'button_2_class' => 'jb-blue',
|
||
'button_2_text' => __('用户中心', 'aksrt'),
|
||
'limit' => 6,
|
||
'orderby' => 'views',
|
||
'post_type' => 'post',
|
||
'post_style' => 'card',
|
||
]);
|
||
|
||
$avatar = aksrt_get_avatar_box($user_id, 'avatar-img avatar-lg');
|
||
$name = aksrt_get_user_name([
|
||
'id' => $user_id,
|
||
'class' => 'flex1 flex ac',
|
||
'vip' => false,
|
||
'medal' => true,
|
||
'auth' => true,
|
||
'level' => true,
|
||
'follow' => true,
|
||
]);
|
||
$tag_metas = aksrt_get_user_badges($user_id);
|
||
$desc = aksrt_get_user_description($user_id);
|
||
$btns = '';
|
||
$posts = '';
|
||
$checkin = '';
|
||
$cuid = get_current_user_id();
|
||
|
||
if (!$cuid || $cuid !== $user_id) {
|
||
$args['show_button'] = false;
|
||
}
|
||
if ($args['show_posts'] && (int) $args['limit'] > 0) {
|
||
$posts = aksrt_render_user_card_posts([
|
||
'user_id' => $user_id,
|
||
'limit' => (int) $args['limit'],
|
||
'orderby' => (string) $args['orderby'],
|
||
'post_type' => (string) $args['post_type'],
|
||
'post_style' => (string) $args['post_style'],
|
||
]);
|
||
}
|
||
if ($args['show_checkin'] && $cuid === $user_id) {
|
||
$checkin = aksrt_header_user_checkin_btn($user_id, true, 'img-badge jb-yellow');
|
||
}
|
||
|
||
if ($args['show_button']) {
|
||
$btns .= self::new_add_btn((string) $args['button_1'], 'but pw-1em mr6 ' . (string) $args['button_1_class'], (string) $args['button_1_text']);
|
||
if ('home' === $args['button_2']) {
|
||
$btns .= self::card_link(aksrt_get_user_home_url($user_id), (string) $args['button_2_class'], (string) $args['button_2_text']);
|
||
} else {
|
||
$btns .= self::card_link(aksrt_get_user_center_url(), (string) $args['button_2_class'], (string) $args['button_2_text'], true);
|
||
}
|
||
$btns = $btns !== '' ? '<div class="user-btns mt20">' . $btns . '</div>' : '';
|
||
}
|
||
|
||
$cover = !empty($args['show_img_bg']) ? self::cover($user_id, 'lazy_cover') : '';
|
||
|
||
return '<div class="user-card zib-widget widget">' . $cover
|
||
. '<div class="card-content mt10 relative">'
|
||
. '<div class="user-content">' . $checkin
|
||
. '<div class="user-avatar">' . $avatar . '</div>'
|
||
. '<div class="user-info mt20 mb10">'
|
||
. '<div class="user-name flex jc">' . $name . '</div>'
|
||
. '<div class="author-tag mt10 mini-scrollbar">' . $tag_metas . '</div>'
|
||
. '<div class="user-desc mt10 muted-2-color em09">' . esc_html($desc) . '</div>'
|
||
. $btns
|
||
. '</div></div>'
|
||
. $posts
|
||
. '</div></div>';
|
||
}
|
||
|
||
/**
|
||
* 卡片按钮1(legacy zib_get_new_add_btns 的 post 类型 parity)。
|
||
*/
|
||
private static function new_add_btn(string $type, string $class, string $text): string {
|
||
if ($type !== 'post') {
|
||
return '';
|
||
}
|
||
$url = aksrt_get_new_post_url();
|
||
if ($url === '') {
|
||
return '';
|
||
}
|
||
return '<a rel="nofollow" class="newadd-btns ' . esc_attr($class) . '" href="' . esc_url($url) . '"><icon class="jb-green"><i class="fa fas fa-edit" aria-hidden="true"></i></icon><text>' . esc_html($text) . '</text></a>';
|
||
}
|
||
|
||
private static function card_link(string $url, string $class, string $text, bool $nofollow = false): string {
|
||
if ($url === '') {
|
||
return '';
|
||
}
|
||
return '<a' . ($nofollow ? ' rel="nofollow"' : '') . ' href="' . esc_url($url) . '" class="but pw-1em ml6 ' . esc_attr($class) . '">' . esc_html($text) . '</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'];
|
||
}
|
||
}
|