diff --git a/assets/css/frontend/widget-batch5.css b/assets/css/frontend/widget-batch5.css index 027d6884..20d5c359 100644 --- a/assets/css/frontend/widget-batch5.css +++ b/assets/css/frontend/widget-batch5.css @@ -2296,3 +2296,86 @@ a.main-color > .icon-cover-card:hover, } .tag-cloud.aksrt-tag-cloud a { transition: transform .15s ease; } .tag-cloud.aksrt-tag-cloud a:hover { transform: translateY(-1px); } + + +/* batch22-24 forum/user residual */ +.forum-posts.mini.aksrt-ftopic-mini, +.forum-posts.detail.aksrt-ftopic-detail { + display: block; + position: relative; + padding: 12px 0; + border-bottom: 1px solid var(--color-line-soft, #f0f1f3); +} +.forum-posts.mini.aksrt-ftopic-mini:last-child, +.forum-posts.detail.aksrt-ftopic-detail:last-child { border-bottom: 0; } +.forum-posts .forum-posts-header .avatar-img img, +.forum-posts .avatar-img img { + width: 28px; height: 28px; border-radius: 50%; object-fit: cover; display: block; +} +.forum-posts.detail .avatar-img img { width: 40px; height: 40px; } +.forum-posts .forum-title { margin: 0; font-size: 14px; font-weight: 600; line-height: 1.4; } +.forum-posts .forum-title a { color: inherit; text-decoration: none; } +.forum-posts .forum-title a:hover { color: var(--theme-color, #f04494); } +.forum-posts .item-meta { gap: 2px; } +.forum-posts .forum-excerpt { line-height: 1.5; } +.forum-posts badge.img-badge { z-index: 2; } + +.plate-lists .plate-item, +.aksrt-plate-lists .plate-item { + display: flex; + gap: 12px; + align-items: flex-start; + padding: 10px 0; + border-bottom: 1px solid var(--color-line-soft, #f0f1f3); + color: inherit; + text-decoration: none; +} +.plate-lists .plate-item:last-child { border-bottom: 0; } +.plate-thumb, +.aksrt-plate-item__thumb { + width: 48px; height: 48px; border-radius: 10px; overflow: hidden; + flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; + background: var(--surface-2, #f3f4f6); color: #999; +} +.plate-thumb img, .aksrt-plate-item__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; } +.panel-plate.scroll-plate, +.aksrt-plate-cards { + display: flex; gap: 12px; overflow-x: auto; padding-bottom: 4px; scrollbar-width: thin; +} +.plate-card, .aksrt-plate-card { + flex: 0 0 160px; width: 160px; text-decoration: none; color: inherit; +} +.plate-card .plate-thumb, .aksrt-plate-card__cover { + width: 100%; aspect-ratio: 1; border-radius: 12px; overflow: hidden; + background: var(--surface-2, #f3f4f6); display: flex; align-items: center; justify-content: center; +} +.plate-card .plate-thumb img, .aksrt-plate-card__cover img { width: 100%; height: 100%; object-fit: cover; } + +.moderator-box.aksrt-plate-mods__list, +.aksrt-plate-mods__list { display: flex; flex-direction: column; gap: 12px; } +.aksrt-plate-mods.style-grid .aksrt-plate-mods__list { + display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 12px; +} +.aksrt-plate-mods__item { gap: 4px; } +.aksrt-plate-mods__avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; display: block; } +.aksrt-plate-mods.style-grid .aksrt-plate-mods__item { text-align: center; } +.aksrt-plate-mods.style-grid .aksrt-plate-mods__avatar { width: 48px; height: 48px; margin: 0 auto 6px; } + +.user-ranking-box .user-ranking-item, +.aksrt-user-ranking-box .user-ranking-item { position: relative; } +.user-ranking-item .avatar-img img { width: 36px; height: 36px; border-radius: 50%; object-fit: cover; display: block; } +.user-ranking-item .badg { white-space: nowrap; } + +.aksrt-category-recommend__card[data-aksrt-animate] { will-change: transform, opacity; } +.aksrt-category-recommend__posts.posts-mini-wrap { margin-top: 8px; } + +.aksrt-plate-info.plate-info-sidebar { overflow: hidden; } +.aksrt-plate-info__cover.plate-thumb { + width: 100%; height: 110px; border-radius: 12px; overflow: hidden; + background: var(--surface-2, #f3f4f6); display: flex; align-items: center; justify-content: center; +} +.aksrt-plate-info__cover.plate-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; } +.aksrt-plate-info__stats.count-mates { gap: 8px; flex-wrap: wrap; } + +.aksrt-ftag-list { display: flex; flex-wrap: wrap; gap: 8px; } +.aksrt-ftag-item.is-card { min-width: 120px; justify-content: space-between; } diff --git a/inc/bootstrap.php b/inc/bootstrap.php index e8ec4665..2828ee90 100644 --- a/inc/bootstrap.php +++ b/inc/bootstrap.php @@ -32,6 +32,7 @@ require_once AKSRT_DIR . '/inc/helpers/aksrt-archive.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-archive-filters.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-comments.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-forum.php'; +require_once AKSRT_DIR . '/inc/helpers/aksrt-forum-widgets.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-slider.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-vip.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-auth-ui.php'; diff --git a/inc/helpers/aksrt-forum-widgets.php b/inc/helpers/aksrt-forum-widgets.php new file mode 100644 index 00000000..49ff9e22 --- /dev/null +++ b/inc/helpers/aksrt-forum-widgets.php @@ -0,0 +1,363 @@ + (string) get_post_meta($post_id, '_aksrt_topping', true) === '1' + || (string) get_post_meta($post_id, '_aksrt_is_top', true) === '1', + 'essence' => (string) get_post_meta($post_id, '_aksrt_essence', true) === '1', + 'views' => (int) get_post_meta($post_id, '_aksrt_views', true), + 'replies' => (int) get_comments_number($post_id), + 'plate_id' => (int) get_post_meta($post_id, '_aksrt_plate_id', true), + ]; + } +endif; + +if (!function_exists('aksrt_forum_topic_badges_html')) : + /** + * Topping / essence badges for forum topic rows. + */ + function aksrt_forum_topic_badges_html(int $post_id, bool $show_topping = true): string { + $flags = aksrt_forum_topic_meta_flags($post_id); + $html = ''; + if ($show_topping && !empty($flags['topping'])) { + $html .= '' . esc_html__('置顶', 'aksrt') . ''; + } + if (!empty($flags['essence'])) { + $html .= '' . esc_html__('精华', 'aksrt') . ''; + } + return $html; + } +endif; + +if (!function_exists('aksrt_render_forum_topic_mini')) : + /** + * Mini forum topic row (zibll zib_bbs_get_posts_mini_list parity). + * + * @param int|null $post_id Null = current post in loop. + * @param string $class Extra classes on outer element. + * @param bool $show_topping Whether to show topping badge. + */ + function aksrt_render_forum_topic_mini(?int $post_id = null, string $class = 'ajax-item', bool $show_topping = true): string { + $post_id = $post_id ?: (int) get_the_ID(); + if ($post_id <= 0) { + return ''; + } + $post = get_post($post_id); + if (!$post || $post->post_status !== 'publish') { + return ''; + } + + $author_id = (int) $post->post_author; + $flags = aksrt_forum_topic_meta_flags($post_id); + $permalink = get_permalink($post_id); + $title = get_the_title($post_id); + + $avatar_url = function_exists('aksrt_get_avatar_url') + ? aksrt_get_avatar_url($author_id, ['size' => 48]) + : get_avatar_url($author_id, ['size' => 48]); + $home = function_exists('aksrt_get_user_home_url') + ? aksrt_get_user_home_url($author_id) + : get_author_posts_url($author_id); + + $name = function_exists('aksrt_get_user_name') + ? aksrt_get_user_name([ + 'id' => $author_id, + 'class' => 'flex ac flex1', + 'follow' => false, + 'medal' => false, + 'level' => false, + ]) + : '' . esc_html(get_the_author_meta('display_name', $author_id)) . ''; + + // Prefer last reply time when available. + $time_raw = (string) get_post_meta($post_id, '_aksrt_last_reply_time', true); + if ($time_raw === '' || !strtotime($time_raw)) { + $time_raw = (string) $post->post_date; + } + $time_txt = function_exists('aksrt_time_ago') + ? aksrt_time_ago($time_raw) + : human_time_diff(strtotime($time_raw), current_time('timestamp')) . __('前', 'aksrt'); + + $views_txt = function_exists('aksrt_format_number') + ? aksrt_format_number($flags['views']) + : (string) $flags['views']; + + $cls = trim('forum-posts mini aksrt-ftopic-mini relative ' . $class); + $html = ''; + $html .= aksrt_forum_topic_badges_html($post_id, $show_topping); + $html .= '
'; + $html .= ''; + $html .= '
'; + $html .= ''; + $html .= '
'; + $html .= '' . $name . ''; + $html .= '' . esc_html($time_txt) . ''; + $html .= ' ' . esc_html((string) $views_txt) . ''; + if ($flags['replies'] > 0) { + $html .= ' ' . esc_html((string) $flags['replies']) . ''; + } + $html .= '
'; + + return $html; + } +endif; + +if (!function_exists('aksrt_render_forum_topic_detail')) : + /** + * Detail forum topic row (richer entry meta). + * + * @param int|null $post_id + * @param string $class + * @param bool $show_topping + */ + function aksrt_render_forum_topic_detail(?int $post_id = null, string $class = 'ajax-item', bool $show_topping = true): string { + $post_id = $post_id ?: (int) get_the_ID(); + if ($post_id <= 0) { + return ''; + } + $post = get_post($post_id); + if (!$post || $post->post_status !== 'publish') { + return ''; + } + + $author_id = (int) $post->post_author; + $flags = aksrt_forum_topic_meta_flags($post_id); + $permalink = get_permalink($post_id); + $title = get_the_title($post_id); + $excerpt = wp_trim_words(wp_strip_all_tags((string) $post->post_content), 36, '…'); + + $avatar_url = function_exists('aksrt_get_avatar_url') + ? aksrt_get_avatar_url($author_id, ['size' => 64]) + : get_avatar_url($author_id, ['size' => 64]); + $home = function_exists('aksrt_get_user_home_url') + ? aksrt_get_user_home_url($author_id) + : get_author_posts_url($author_id); + + $name = function_exists('aksrt_get_user_name') + ? aksrt_get_user_name([ + 'id' => $author_id, + 'class' => 'flex ac', + 'follow' => false, + 'medal' => true, + 'level' => true, + ]) + : '' . esc_html(get_the_author_meta('display_name', $author_id)) . ''; + + $time_raw = (string) get_post_meta($post_id, '_aksrt_last_reply_time', true); + if ($time_raw === '' || !strtotime($time_raw)) { + $time_raw = (string) $post->post_date; + } + $time_txt = function_exists('aksrt_time_ago') + ? aksrt_time_ago($time_raw) + : human_time_diff(strtotime($time_raw), current_time('timestamp')) . __('前', 'aksrt'); + + $views_txt = function_exists('aksrt_format_number') + ? aksrt_format_number($flags['views']) + : (string) $flags['views']; + + // Optional plate name chip. + $plate_chip = ''; + if ($flags['plate_id'] > 0) { + $plate = get_post($flags['plate_id']); + if ($plate instanceof WP_Post) { + $plate_chip = '' . esc_html(get_the_title($plate)) . ''; + } + } + + $cls = trim('forum-posts detail aksrt-ftopic-detail relative ' . $class); + $html = ''; + $html .= aksrt_forum_topic_badges_html($post_id, $show_topping); + $html .= '
'; + $html .= ''; + $html .= '
' . $name . '
' . esc_html($time_txt) . '
'; + $html .= '
'; + $html .= '

' . esc_html($title) . '

'; + if ($excerpt !== '') { + $html .= '
' . esc_html($excerpt) . '
'; + } + $html .= '
'; + $html .= $plate_chip; + $html .= ' ' . esc_html((string) $views_txt) . ''; + $html .= ' ' . esc_html((string) $flags['replies']) . ''; + $html .= '
'; + + return $html; + } +endif; + +if (!function_exists('aksrt_render_plate_thumb_html')) : + /** + * Shared plate thumb with lazy pattern. + */ + function aksrt_render_plate_thumb_html(int $plate_id, string $size = 'thumbnail'): string { + $thumb = get_the_post_thumbnail_url($plate_id, $size); + $icon = (string) get_post_meta($plate_id, '_aksrt_icon', true); + $ph = get_template_directory_uri() . '/assets/img/placeholder.svg'; + if ($thumb) { + return ''; + } + if ($icon !== '') { + return ''; + } + return ''; + } +endif; + +if (!function_exists('aksrt_render_plate_row')) : + /** + * Plate list row (zibll plate-item flex). + * + * @param WP_Post|int $plate + */ + function aksrt_render_plate_row($plate): string { + $post = $plate instanceof WP_Post ? $plate : get_post((int) $plate); + if (!$post instanceof WP_Post) { + return ''; + } + $id = (int) $post->ID; + $url = get_permalink($id); + $count = (int) get_post_meta($id, '_aksrt_posts_count', true); + $follow = (int) get_post_meta($id, '_aksrt_follow_count', true); + $desc = $post->post_excerpt !== '' ? $post->post_excerpt : wp_trim_words(wp_strip_all_tags((string) $post->post_content), 18); + + $html = ''; + $html .= aksrt_render_plate_thumb_html($id, 'thumbnail'); + $html .= '
'; + $html .= '

' . esc_html(get_the_title($post)) . '

'; + if ($desc !== '') { + $html .= '
' . esc_html($desc) . '
'; + } + $html .= '
'; + $html .= '' . esc_html(sprintf(/* translators: %d topic count */ __('%d 帖', 'aksrt'), $count)) . ''; + if ($follow > 0) { + $html .= '' . esc_html(sprintf(/* translators: %d follow count */ __('%d 关注', 'aksrt'), $follow)) . ''; + } + $html .= '
'; + return $html; + } +endif; + +if (!function_exists('aksrt_render_plate_card')) : + /** + * Plate card slide item. + * + * @param WP_Post|int $plate + */ + function aksrt_render_plate_card($plate): string { + $post = $plate instanceof WP_Post ? $plate : get_post((int) $plate); + if (!$post instanceof WP_Post) { + return ''; + } + $id = (int) $post->ID; + $url = get_permalink($id); + $thumb = get_the_post_thumbnail_url($id, 'medium'); + $count = (int) get_post_meta($id, '_aksrt_posts_count', true); + $follow = (int) get_post_meta($id, '_aksrt_follow_count', true); + $ph = get_template_directory_uri() . '/assets/img/placeholder.svg'; + + $html = ''; + $html .= '
'; + if ($thumb) { + $html .= ''; + } else { + $html .= ''; + } + $html .= '
'; + $html .= '
' . esc_html(get_the_title($post)) . '
'; + $html .= '
'; + $html .= '' . esc_html(sprintf(__('%d 帖', 'aksrt'), $count)) . ''; + $html .= '' . esc_html(sprintf(__('%d 关注', 'aksrt'), $follow)) . ''; + $html .= '
'; + return $html; + } +endif; + +if (!function_exists('aksrt_render_moderator_row')) : + /** + * Moderator identity row with optional follow. + * + * @param int $user_id + * @param string $role author|super|moderator + * @param bool $show_avatar + * @param string $style list|grid + */ + function aksrt_render_moderator_row(int $user_id, string $role = 'moderator', bool $show_avatar = true, string $style = 'list'): string { + if ($user_id <= 0) { + return ''; + } + $user = get_userdata($user_id); + if (!$user) { + return ''; + } + $avatar = function_exists('aksrt_get_avatar_url') + ? aksrt_get_avatar_url($user_id, ['size' => 64]) + : get_avatar_url($user_id, ['size' => 64]); + $home = function_exists('aksrt_get_user_home_url') + ? aksrt_get_user_home_url($user_id) + : get_author_posts_url($user_id); + $ph = get_template_directory_uri() . '/assets/img/placeholder.svg'; + + if ($role === 'author' || $role === 'super') { + $role_label = __('超级版主', 'aksrt'); + } else { + $role_label = __('版主', 'aksrt'); + } + + $name = function_exists('aksrt_get_user_name') + ? aksrt_get_user_name([ + 'id' => $user_id, + 'class' => 'flex ac flex1', + 'follow' => false, + 'medal' => true, + 'level' => true, + ]) + : '' . esc_html($user->display_name) . ''; + + // Follow control (not for self). + $follow_html = ''; + $cuid = get_current_user_id(); + if ($cuid > 0 && $cuid !== $user_id && class_exists('\AKSRT\User\Follow')) { + $following = \AKSRT\User\Follow::get_instance()->is_following($cuid, $user_id); + $label = $following ? __('已关注', 'aksrt') : __('关注', 'aksrt'); + $follow_html = ''; + } + + if ($style === 'grid') { + $html = '
'; + if ($show_avatar) { + $html .= ''; + } + $html .= '
' . $name . '
'; + $html .= '
' . esc_html($role_label) . '
'; + $html .= $follow_html; + $html .= '
'; + return $html; + } + + $html = '
'; + if ($show_avatar) { + $html .= ''; + } + $html .= '
'; + $html .= '
' . $name . '
'; + $html .= '
' . esc_html($role_label) . '
'; + $html .= '
'; + $html .= $follow_html; + $html .= '
'; + return $html; + } +endif; diff --git a/src/AKSRT/Widgets/CategoryBlockWidget.php b/src/AKSRT/Widgets/CategoryBlockWidget.php index 767328f9..80f72769 100644 --- a/src/AKSRT/Widgets/CategoryBlockWidget.php +++ b/src/AKSRT/Widgets/CategoryBlockWidget.php @@ -215,25 +215,26 @@ if (!function_exists('aksrt_home_widget_render_post_grid')) { return; } - // Fallback: simple sidebar list + // Fallback: shared mini list (lazy thumbs + meta). + if (function_exists('aksrt_render_mini_list')) { + echo '
'; + aksrt_render_mini_list($query, ['context' => 'sidebar', 'show_thumb' => true]); + echo '
'; + return; + } echo ''; wp_reset_postdata(); diff --git a/src/AKSRT/Widgets/CategoryRecommendWidget.php b/src/AKSRT/Widgets/CategoryRecommendWidget.php index 7d002742..32720184 100644 --- a/src/AKSRT/Widgets/CategoryRecommendWidget.php +++ b/src/AKSRT/Widgets/CategoryRecommendWidget.php @@ -48,56 +48,82 @@ class CategoryRecommendWidget extends \WP_Widget { ob_start(); printf('
', (int) $columns); foreach ($cards as $card) { - ?> -
-
- - - - <?php echo esc_attr($card['name']); ?> - - <?php echo esc_attr($card['name']); ?> - - - - 0) : ?> - - - - - -
-
-
-

- -

- -

- -
- - - - -
-
- 0) { + $v = function_exists('aksrt_format_number') ? aksrt_format_number((int) $card['views']) : number_format_i18n((int) $card['views']); + $more = ' ' . esc_html((string) $v) . ''; + } + echo '
'; + if (function_exists('aksrt_graphic_card') && $cover !== '') { + echo aksrt_graphic_card([ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + 'type' => 'style-2', + 'class' => 'aksrt-category-recommend__hero mb10', + 'img' => $cover, + 'alt' => $name, + 'link' => ['url' => $link], + 'text1' => $name, + 'text2' => $show_description ? (string) $card['description'] : '', + 'text3' => $badge, + 'more' => $more, + 'lazy' => true, + ]); + } else { + echo '
'; + echo ''; + if ($lazy['enabled']) { + echo ''; + echo '' . esc_attr($name) . ''; + } else { + echo '' . esc_attr($name) . ''; + } + echo ''; + echo '' . esc_html($badge) . ''; + echo $more; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo '
'; + echo '
'; + echo '

' . esc_html($name) . '

'; + if ($show_description && $card['description'] !== '') { + echo '

' . esc_html((string) $card['description']) . '

'; + } + echo '
'; + } + echo '
'; + // Prefer shared mini list when post IDs available. + if (!empty($card['post_ids']) && function_exists('aksrt_render_mini_list')) { + $q = new \WP_Query([ + 'post_type' => 'any', + 'post__in' => array_map('intval', (array) $card['post_ids']), + 'orderby' => 'post__in', + 'posts_per_page' => count((array) $card['post_ids']), + 'ignore_sticky_posts' => true, + 'no_found_rows' => true, + ]); + echo '
'; + aksrt_render_mini_list($q, ['context' => 'widget', 'show_thumb' => true, 'show_meta' => $show_dates]); + echo '
'; + wp_reset_postdata(); + } else { + echo '
    '; + foreach ($card['posts'] as $post_item) { + echo '
  • '; + echo '' . esc_html($post_item['title']) . ''; + if ($show_dates && $post_item['date'] !== '') { + echo '' . esc_html($post_item['date']) . ''; + } + echo '
  • '; + } + echo '
'; + } + if ($show_more) { + echo ''; + } + echo '
'; } echo '
'; return (string) ob_get_clean(); diff --git a/src/AKSRT/Widgets/CategoryTabsWidget.php b/src/AKSRT/Widgets/CategoryTabsWidget.php index aa738b19..6552eacc 100644 --- a/src/AKSRT/Widgets/CategoryTabsWidget.php +++ b/src/AKSRT/Widgets/CategoryTabsWidget.php @@ -130,7 +130,7 @@ class CategoryTabsWidget extends \WP_Widget { if(showMore&&more){ html+=''; } - panel.innerHTML=html||'

暂无文章

'; + panel.innerHTML=html||'
暂无文章
'; panel.setAttribute('data-loaded','1'); panel.classList.remove('is-ajax-loading'); }).catch(function(){panel.classList.remove('is-ajax-loading');}); diff --git a/src/AKSRT/Widgets/WidgetForumBoardList.php b/src/AKSRT/Widgets/WidgetForumBoardList.php index 6127f973..c66869fa 100644 --- a/src/AKSRT/Widgets/WidgetForumBoardList.php +++ b/src/AKSRT/Widgets/WidgetForumBoardList.php @@ -57,27 +57,44 @@ class WidgetForumBoardList extends \WP_Widget { $plates = get_posts($query_args); if ($plates) { ob_start(); - echo ''; return (string) ob_get_clean(); } } + // Taxonomy fallback. $term_args = [ 'taxonomy' => 'aksrt_forum_board', diff --git a/src/AKSRT/Widgets/WidgetForumPlateInfo.php b/src/AKSRT/Widgets/WidgetForumPlateInfo.php index 0a1a2957..f8f78952 100644 --- a/src/AKSRT/Widgets/WidgetForumPlateInfo.php +++ b/src/AKSRT/Widgets/WidgetForumPlateInfo.php @@ -54,11 +54,12 @@ class WidgetForumPlateInfo extends \WP_Widget { : home_url('/'); ob_start(); - echo '
'; + echo '
'; if ($thumb) { - echo '
'; + $ph = get_template_directory_uri() . '/assets/img/placeholder.svg'; + echo '
'; } elseif ($icon !== '') { - echo '
'; + echo '
'; } echo '
'; echo '' . esc_html(get_the_title($plate)) . ''; @@ -66,7 +67,7 @@ class WidgetForumPlateInfo extends \WP_Widget { echo '
' . esc_html($desc) . '
'; } if ($show_stats) { - echo '
'; + echo '
'; echo ' ' . esc_html((string) $posts) . ''; echo ' ' . esc_html((string) $reply) . ''; if ($views > 0) { diff --git a/src/AKSRT/Widgets/WidgetForumPlateLists.php b/src/AKSRT/Widgets/WidgetForumPlateLists.php index 89d0e256..93bb6184 100644 --- a/src/AKSRT/Widgets/WidgetForumPlateLists.php +++ b/src/AKSRT/Widgets/WidgetForumPlateLists.php @@ -88,20 +88,27 @@ class WidgetForumPlateLists extends \WP_Widget { return ''; } ob_start(); - $self = new self(); if ($style === 'card') { - echo '
'; + echo '
'; foreach ($plates as $post) { if ($post instanceof \WP_Post) { - $self->render_card($post); + if (function_exists('aksrt_render_plate_card')) { + echo aksrt_render_plate_card($post); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } else { + (new self())->render_card($post); + } } } echo '
'; } else { - echo '
'; + echo '
'; foreach ($plates as $post) { if ($post instanceof \WP_Post) { - $self->render_row($post); + if (function_exists('aksrt_render_plate_row')) { + echo aksrt_render_plate_row($post); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } else { + (new self())->render_row($post); + } } } echo '
'; @@ -154,42 +161,56 @@ class WidgetForumPlateLists extends \WP_Widget { } public function render_row(\WP_Post $post): void { + if (function_exists('aksrt_render_plate_row')) { + echo aksrt_render_plate_row($post); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + return; + } $id = (int) $post->ID; $url = get_permalink($id); $thumb = get_the_post_thumbnail_url($id, 'thumbnail'); $icon = (string) get_post_meta($id, '_aksrt_icon', true); $count = (int) get_post_meta($id, '_aksrt_posts_count', true); $desc = $post->post_excerpt !== '' ? $post->post_excerpt : wp_trim_words(wp_strip_all_tags($post->post_content), 18); + $ph = get_template_directory_uri() . '/assets/img/placeholder.svg'; - echo ''; - echo '
'; + echo ''; + echo '
'; if ($thumb) { - echo ''; + echo ''; } elseif ($icon !== '') { echo ''; } else { echo ''; } echo '
'; - echo '
'; - echo '
' . esc_html(get_the_title($post)) . '
'; + echo '
'; + echo '
' . esc_html(get_the_title($post)) . '
'; if ($desc !== '') { - echo '
' . esc_html($desc) . '
'; + echo '
' . esc_html($desc) . '
'; } echo '
' . esc_html(sprintf(/* translators: %d topic count */ __('%d 帖', 'aksrt'), $count)) . '
'; echo '
'; } public function render_card(\WP_Post $post): void { + if (function_exists('aksrt_render_plate_card')) { + echo aksrt_render_plate_card($post); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + return; + } $id = (int) $post->ID; $url = get_permalink($id); $thumb = get_the_post_thumbnail_url($id, 'medium'); $count = (int) get_post_meta($id, '_aksrt_posts_count', true); $follow = (int) get_post_meta($id, '_aksrt_follow_count', true); + $ph = get_template_directory_uri() . '/assets/img/placeholder.svg'; - echo ''; - echo '
'; - echo '
' . esc_html(get_the_title($post)) . '
'; + echo '
'; + echo '
'; + if ($thumb) { + echo ''; + } + echo '
'; + echo '
' . esc_html(get_the_title($post)) . '
'; echo '
'; echo '' . esc_html(sprintf(__('%d 帖', 'aksrt'), $count)) . ''; echo '' . esc_html(sprintf(__('%d 关注', 'aksrt'), $follow)) . ''; diff --git a/src/AKSRT/Widgets/WidgetForumPlateModerator.php b/src/AKSRT/Widgets/WidgetForumPlateModerator.php index 5ad4a27f..c0f6c3d2 100644 --- a/src/AKSRT/Widgets/WidgetForumPlateModerator.php +++ b/src/AKSRT/Widgets/WidgetForumPlateModerator.php @@ -74,13 +74,17 @@ class WidgetForumPlateModerator extends \WP_Widget { } ob_start(); - echo '
'; + echo ''; - return ['html' => (string) ob_get_clean()]; + return ['html' => (string) ob_get_clean()]; } public function widget($args, $instance): void { diff --git a/src/AKSRT/Widgets/WidgetForumTabTopics.php b/src/AKSRT/Widgets/WidgetForumTabTopics.php index c96212b6..f1ef2d76 100644 --- a/src/AKSRT/Widgets/WidgetForumTabTopics.php +++ b/src/AKSRT/Widgets/WidgetForumTabTopics.php @@ -88,7 +88,7 @@ class WidgetForumTabTopics extends \WP_Widget { .then(function(r){return r.json()}).then(function(j){ var d=(j&&j.data)||j||{}; var html=d.html||''; - panel.innerHTML=html||'

暂无内容

'; + panel.innerHTML=html||'
暂无内容
'; panel.setAttribute('data-loaded','1'); panel.classList.remove('is-ajax-loading'); }).catch(function(){panel.classList.remove('is-ajax-loading');}); diff --git a/src/AKSRT/Widgets/WidgetForumTopicLists.php b/src/AKSRT/Widgets/WidgetForumTopicLists.php index b12ae482..d8fe5691 100644 --- a/src/AKSRT/Widgets/WidgetForumTopicLists.php +++ b/src/AKSRT/Widgets/WidgetForumTopicLists.php @@ -79,26 +79,25 @@ class WidgetForumTopicLists extends \WP_Widget { if (!$q->have_posts()) { return ''; } - $list_class = $style === 'detail' ? 'aksrt-ftopic-list is-detail' : 'aksrt-ftopic-list is-mini'; ob_start(); - echo '
    '; + echo $style === 'detail' + ? '
    ' + : '
    '; while ($q->have_posts()) { $q->the_post(); - $views = (int) get_post_meta(get_the_ID(), '_aksrt_views', true); - echo '
  • '; - echo '' . esc_html(get_the_title()) . ''; - if ($style === 'detail') { - echo '
    '; - echo '' . esc_html(get_the_author()) . ''; - echo '' . esc_html(get_the_date()) . ''; - echo ' ' . esc_html((string) $views) . ''; - echo '
    '; + if ($style === 'detail' && function_exists('aksrt_render_forum_topic_detail')) { + echo aksrt_render_forum_topic_detail(null, 'ajax-item', true); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } elseif (function_exists('aksrt_render_forum_topic_mini')) { + echo aksrt_render_forum_topic_mini(null, 'ajax-item', true); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } else { + $views = (int) get_post_meta(get_the_ID(), '_aksrt_views', true); + echo '
    '; + echo '' . esc_html(get_the_title()) . ''; echo '' . esc_html((string) $views) . ''; + echo '
    '; } - echo '
  • '; } - echo '
'; + echo '
'; wp_reset_postdata(); return (string) ob_get_clean(); } diff --git a/src/AKSRT/Widgets/WidgetForumTopicTerms.php b/src/AKSRT/Widgets/WidgetForumTopicTerms.php index 14da9c03..b4a37aff 100644 --- a/src/AKSRT/Widgets/WidgetForumTopicTerms.php +++ b/src/AKSRT/Widgets/WidgetForumTopicTerms.php @@ -83,7 +83,7 @@ class WidgetForumTopicTerms extends \WP_Widget { continue; } $icon = (string) get_term_meta($term->term_id, '_aksrt_icon', true); - echo ''; + echo ''; if ($icon !== '') { echo ' '; } @@ -106,7 +106,7 @@ class WidgetForumTopicTerms extends \WP_Widget { echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } // IAS-style wrap for remote refresh. - echo '
'; + echo '
'; echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo '
'; echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped diff --git a/src/AKSRT/Widgets/WidgetProductTab.php b/src/AKSRT/Widgets/WidgetProductTab.php index 8bece9e6..12fb5cf9 100644 --- a/src/AKSRT/Widgets/WidgetProductTab.php +++ b/src/AKSRT/Widgets/WidgetProductTab.php @@ -49,6 +49,13 @@ class WidgetProductTab extends \WP_Widget { $paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax')); $tabs = self::parse_tabs($tabs_raw); if (!$tabs) { + if (current_user_can('manage_options')) { + echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo function_exists('aksrt_get_widget_null') + ? aksrt_get_widget_null(__('请至少配置一个 TAB', 'aksrt')) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + : '

' . esc_html__('请至少配置一个 TAB', 'aksrt') . '

'; + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } return; } diff --git a/src/AKSRT/Widgets/WidgetUserRanking.php b/src/AKSRT/Widgets/WidgetUserRanking.php index 4cf6eada..1bb5dd5a 100644 --- a/src/AKSRT/Widgets/WidgetUserRanking.php +++ b/src/AKSRT/Widgets/WidgetUserRanking.php @@ -1,5 +1,7 @@ __('按积分、文章数或粉丝数排行的用户列表。', 'aksrt')] - ); - } + public function __construct() { + parent::__construct( + 'aksrt_user_ranking', + __('用户排行榜', 'aksrt'), + [ + 'description' => __('按积分、文章数或粉丝数排行的用户列表。', 'aksrt'), + 'classname' => 'widget_aksrt_user_ranking', + ] + ); + } - public function widget($args, $instance): void { - $title = !empty($instance['title']) ? $instance['title'] : __('排行榜', 'aksrt'); - $rank_by = !empty($instance['rank_by']) ? $instance['rank_by'] : 'credits'; - $count = max(1, min(20, (int) ($instance['count'] ?? 5))); - $show_avatar = !empty($instance['show_avatar']); + public function widget($args, $instance): void { + $title = !empty($instance['title']) ? (string) $instance['title'] : __('排行榜', 'aksrt'); + $rank_by = !empty($instance['rank_by']) ? (string) $instance['rank_by'] : 'credits'; + $count = max(1, min(20, (int) ($instance['count'] ?? 5))); + $show_avatar = !isset($instance['show_avatar']) || !empty($instance['show_avatar']); + $desc_mode = sanitize_key((string) ($instance['desc'] ?? 'desc')); + $top_badge = !empty($instance['top_badge']); + $users = $this->get_ranking($rank_by, $count, $desc_mode); - $desc_mode = sanitize_key((string) ($instance['desc'] ?? 'desc')); - $users = $this->get_ranking($rank_by, $count, $desc_mode); + echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo '
'; + if (!empty($instance['checkin_btn']) && is_user_logged_in() && function_exists('aksrt_header_user_checkin_btn')) { + $cbtn = aksrt_header_user_checkin_btn(get_current_user_id()); + if ($cbtn !== '') { + echo '
' . $cbtn . '
'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } - if (!empty($instance['checkin_btn']) && is_user_logged_in() && function_exists('aksrt_header_user_checkin_btn')) { - $cbtn = aksrt_header_user_checkin_btn(get_current_user_id()); - if ($cbtn !== '') { - echo '
' . $cbtn . '
'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - } - } + if (empty($users)) { + echo function_exists('aksrt_get_widget_null') + ? aksrt_get_widget_null(__('暂无排行数据', 'aksrt')) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + : '

' . esc_html__('暂无排行数据', 'aksrt') . '

'; + echo '
'; + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + return; + } - if (empty($users)) { - echo '

' . esc_html__('暂无排行数据', 'aksrt') . '

'; - echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - return; - } + $ph = get_template_directory_uri() . '/assets/img/placeholder.svg'; + $rank = 0; + foreach ($users as $user) { + $rank++; + $uid = (int) $user['id']; + $user_url = function_exists('aksrt_get_user_home_url') + ? aksrt_get_user_home_url($uid) + : get_author_posts_url($uid); - $top_badge = !empty($instance['top_badge']); + $top_bagd = ''; + if ($top_badge && $rank <= 3) { + $tone = $rank === 1 ? 'jb-red' : ($rank === 2 ? 'jb-yellow' : 'b-gray'); + $top_bagd = 'TOP' . (int) $rank . ''; + } - echo '
'; - // 头像 - if ($show_avatar) { - $avatar_url = function_exists('aksrt_get_avatar_url') - ? aksrt_get_avatar_url($user['id'], ['size' => 36]) - : get_avatar_url($user['id'], ['size' => 36]); - echo ''; - echo ''; - echo ''; - } + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } - // 昵称 + 可选签名/附加信息 - echo '
'; - echo '' . esc_html($user['name']) . ''; - if (!empty($user['desc'])) { - echo '
' . esc_html((string) $user['desc']) . '
'; - } - echo '
'; + /** + * @return list + */ + private function get_ranking(string $rank_by, int $count, string $desc_mode = 'desc'): array { + $users = []; - // 数值 - echo '' . esc_html($user['value']) . ''; + switch ($rank_by) { + case 'credits': + global $wpdb; + $rows = $wpdb->get_results($wpdb->prepare( + "SELECT user_id, meta_value as credits FROM {$wpdb->usermeta} + WHERE meta_key = 'aksrt_credits' + ORDER BY CAST(meta_value AS UNSIGNED) DESC + LIMIT %d", + $count + ), ARRAY_A); + foreach ((array) $rows as $row) { + $user = get_userdata((int) $row['user_id']); + if ($user) { + $num = (int) $row['credits']; + $users[] = [ + 'id' => (int) $row['user_id'], + 'name' => $user->display_name, + 'value' => number_format_i18n($num) . ' 积分', + 'value_num' => (string) number_format_i18n($num), + 'value_label' => sprintf(__('积分:%s', 'aksrt'), number_format_i18n($num)), + 'value_icon' => 'fa-diamond', + 'desc' => $this->user_extra_desc((int) $row['user_id'], $user, $desc_mode), + ]; + } + } + break; - echo ''; - } - echo ''; + case 'posts': + $blog_users = get_users([ + 'number' => $count, + 'orderby' => 'post_count', + 'order' => 'DESC', + 'who' => 'authors', + ]); + foreach ($blog_users as $user) { + $post_count = count_user_posts($user->ID, 'post', true); + if ($post_count > 0) { + $users[] = [ + 'id' => $user->ID, + 'name' => $user->display_name, + 'value' => number_format_i18n($post_count) . ' 篇', + 'value_num' => (string) number_format_i18n($post_count), + 'value_label' => sprintf(__('共%d篇文章', 'aksrt'), $post_count), + 'value_icon' => 'fa-file-text-o', + 'desc' => $this->user_extra_desc($user->ID, $user, $desc_mode), + ]; + } + } + break; - echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - } + case 'checkin_all_day': + $users = $this->meta_rank('aksrt_checkin_all_day', ['checkin_all_day'], $count, $desc_mode, 'fa-calendar-check-o', __('累计签到%d天', 'aksrt'), ' 天'); + break; - private function get_ranking(string $rank_by, int $count, string $desc_mode = 'desc'): array { - $users = []; + case 'checkin_continuous_day': + $users = $this->meta_rank('aksrt_checkin_continuous_day', ['checkin_continuous_day'], $count, $desc_mode, 'fa-calendar-check-o', __('连续签到%d天', 'aksrt'), ' 天'); + break; - switch ($rank_by) { - case 'credits': - global $wpdb; - $rows = $wpdb->get_results($wpdb->prepare( - "SELECT user_id, meta_value as credits FROM {$wpdb->usermeta} - WHERE meta_key = 'aksrt_credits' - ORDER BY CAST(meta_value AS UNSIGNED) DESC - LIMIT %d", - $count - ), ARRAY_A); - foreach ((array) $rows as $row) { - $user = get_userdata((int) $row['user_id']); - if ($user) { - $users[] = [ - 'id' => (int) $row['user_id'], - 'name' => $user->display_name, - 'value' => number_format_i18n((int) $row['credits']) . ' 积分', - 'desc' => $this->user_extra_desc((int) $row['user_id'], $user, $desc_mode), - ]; - } - } - break; + case 'followers': + if (class_exists('\AKSRT\User\Follow')) { + global $wpdb; + $follow_table = \AKSRT\Core\DBMigrator::table('follow'); + if ($follow_table) { + $rows = $wpdb->get_results($wpdb->prepare( + "SELECT following_id, COUNT(*) as cnt + FROM {$follow_table} + GROUP BY following_id + ORDER BY cnt DESC + LIMIT %d", + $count + ), ARRAY_A); + foreach ((array) $rows as $row) { + $user = get_userdata((int) $row['following_id']); + if ($user) { + $num = (int) $row['cnt']; + $users[] = [ + 'id' => (int) $row['following_id'], + 'name' => $user->display_name, + 'value' => number_format_i18n($num) . ' 粉丝', + 'value_num' => (string) number_format_i18n($num), + 'value_label' => sprintf(__('共%d个粉丝', 'aksrt'), $num), + 'value_icon' => 'fa-heart', + 'desc' => $this->user_extra_desc((int) $row['following_id'], $user, $desc_mode), + ]; + } + } + } + } + break; + } - case 'posts': - $blog_users = get_users([ - 'number' => $count, - 'orderby' => 'post_count', - 'order' => 'DESC', - 'who' => 'authors', - ]); - foreach ($blog_users as $user) { - $post_count = count_user_posts($user->ID, 'post', true); - if ($post_count > 0) { - $users[] = [ - 'id' => $user->ID, - 'name' => $user->display_name, - 'value' => number_format_i18n($post_count) . ' 篇', - 'desc' => $this->user_extra_desc($user->ID, $user, $desc_mode), - ]; - } - } - break; + return $users; + } - case 'checkin_all_day': - global $wpdb; - $rows = $wpdb->get_results($wpdb->prepare( - "SELECT user_id, meta_value as val FROM {$wpdb->usermeta} - WHERE meta_key IN ('aksrt_checkin_all_day','checkin_all_day') - ORDER BY CAST(meta_value AS UNSIGNED) DESC - LIMIT %d", - $count * 2 - ), ARRAY_A); - $seen = []; - foreach ((array) $rows as $row) { - $uid = (int) $row['user_id']; - if (isset($seen[$uid])) continue; - $seen[$uid] = true; - $user = get_userdata($uid); - if ($user) { - $users[] = [ - 'id' => $uid, - 'name' => $user->display_name, - 'value' => number_format_i18n((int) $row['val']) . ' 天', - 'desc' => $this->user_extra_desc($uid, $user, $desc_mode), - ]; - } - if (count($users) >= $count) break; - } - break; + /** + * @param list $alt_keys + * @return list + */ + private function meta_rank(string $primary_key, array $alt_keys, int $count, string $desc_mode, string $icon, string $label_tpl, string $suffix): array { + global $wpdb; + $keys = array_merge([$primary_key], $alt_keys); + $in = implode(',', array_fill(0, count($keys), '%s')); + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared + $sql = $wpdb->prepare( + "SELECT user_id, meta_value as val FROM {$wpdb->usermeta} + WHERE meta_key IN ($in) + ORDER BY CAST(meta_value AS UNSIGNED) DESC + LIMIT %d", + ...array_merge($keys, [$count * 2]) + ); + $rows = $wpdb->get_results($sql, ARRAY_A); + $seen = []; + $users = []; + foreach ((array) $rows as $row) { + $uid = (int) $row['user_id']; + if (isset($seen[$uid])) { + continue; + } + $seen[$uid] = true; + $user = get_userdata($uid); + if (!$user) { + continue; + } + $num = (int) $row['val']; + $users[] = [ + 'id' => $uid, + 'name' => $user->display_name, + 'value' => number_format_i18n($num) . $suffix, + 'value_num' => (string) number_format_i18n($num), + 'value_label' => sprintf($label_tpl, $num), + 'value_icon' => $icon, + 'desc' => $this->user_extra_desc($uid, $user, $desc_mode), + ]; + if (count($users) >= $count) { + break; + } + } + return $users; + } - case 'checkin_continuous_day': - global $wpdb; - $rows = $wpdb->get_results($wpdb->prepare( - "SELECT user_id, meta_value as val FROM {$wpdb->usermeta} - WHERE meta_key IN ('aksrt_checkin_continuous_day','checkin_continuous_day') - ORDER BY CAST(meta_value AS UNSIGNED) DESC - LIMIT %d", - $count * 2 - ), ARRAY_A); - $seen = []; - foreach ((array) $rows as $row) { - $uid = (int) $row['user_id']; - if (isset($seen[$uid])) continue; - $seen[$uid] = true; - $user = get_userdata($uid); - if ($user) { - $users[] = [ - 'id' => $uid, - 'name' => $user->display_name, - 'value' => number_format_i18n((int) $row['val']) . ' 天', - 'desc' => $this->user_extra_desc($uid, $user, $desc_mode), - ]; - } - if (count($users) >= $count) break; - } - break; + private function user_extra_desc(int $user_id, $user, string $mode): string { + switch ($mode) { + case 'user_registered': + if ($user && !empty($user->user_registered)) { + $days = max(0, (int) floor((time() - strtotime($user->user_registered)) / DAY_IN_SECONDS)); + return sprintf(__('加入 %d 天', 'aksrt'), $days); + } + return ''; + case 'last_login': + $t = (string) get_user_meta($user_id, 'aksrt_last_login', true); + if ($t === '') { + $t = (string) get_user_meta($user_id, 'last_login', true); + } + return $t !== '' ? sprintf(__('最近登录 %s', 'aksrt'), $t) : ''; + case 'last_checkin': + $t = (string) get_user_meta($user_id, 'aksrt_last_checkin', true); + if ($t === '') { + $t = (string) get_user_meta($user_id, 'last_checkin', true); + } + return $t !== '' ? sprintf(__('最近签到 %s', 'aksrt'), $t) : ''; + case 'desc': + default: + $bio = get_user_meta($user_id, 'description', true); + if (!is_string($bio) || $bio === '') { + $bio = $user ? (string) $user->description : ''; + } + return $bio !== '' ? wp_trim_words($bio, 12) : ''; + } + } - case 'followers': - if (class_exists('\AKSRT\User\Follow')) { - global $wpdb; - $follow_table = \AKSRT\Core\DBMigrator::table('follow'); - if ($follow_table) { - $rows = $wpdb->get_results($wpdb->prepare( - "SELECT following_id, COUNT(*) as cnt - FROM {$follow_table} - GROUP BY following_id - ORDER BY cnt DESC - LIMIT %d", - $count - ), ARRAY_A); - foreach ((array) $rows as $row) { - $user = get_userdata((int) $row['following_id']); - if ($user) { - $users[] = [ - 'id' => (int) $row['following_id'], - 'name' => $user->display_name, - 'value' => number_format_i18n((int) $row['cnt']) . ' 粉丝', - 'desc' => $this->user_extra_desc((int) $row['following_id'], $user, $desc_mode), - ]; - } - } - } - } - break; - } + public function form($instance): void { + $title = !empty($instance['title']) ? $instance['title'] : __('排行榜', 'aksrt'); + $rank_by = !empty($instance['rank_by']) ? $instance['rank_by'] : 'credits'; + $count = !empty($instance['count']) ? (int) $instance['count'] : 5; + $show_avatar = !isset($instance['show_avatar']) || !empty($instance['show_avatar']); + ?> +

+ + +

+

+ + +

+

+ + +

+

+ +

+

+ + +

+

+ +

+

+ +

+ user_registered)) { - $days = max(0, (int) floor((time() - strtotime($user->user_registered)) / DAY_IN_SECONDS)); - return sprintf(__('加入 %d 天', 'aksrt'), $days); - } - return ''; - case 'last_login': - $t = (string) get_user_meta($user_id, 'aksrt_last_login', true); - if ($t === '') { - $t = (string) get_user_meta($user_id, 'last_login', true); - } - return $t !== '' ? sprintf(__('最近登录 %s', 'aksrt'), $t) : ''; - case 'last_checkin': - $t = (string) get_user_meta($user_id, 'aksrt_last_checkin', true); - if ($t === '') { - $t = (string) get_user_meta($user_id, 'last_checkin', true); - } - return $t !== '' ? sprintf(__('最近签到 %s', 'aksrt'), $t) : ''; - case 'desc': - default: - $bio = get_user_meta($user_id, 'description', true); - if (!is_string($bio) || $bio === '') { - $bio = $user ? (string) $user->description : ''; - } - return $bio !== '' ? wp_trim_words($bio, 12) : ''; - } - } - - public function form($instance): void { - $title = !empty($instance['title']) ? $instance['title'] : __('排行榜', 'aksrt'); - $rank_by = !empty($instance['rank_by']) ? $instance['rank_by'] : 'credits'; - $count = !empty($instance['count']) ? (int) $instance['count'] : 5; - $show_avatar = !empty($instance['show_avatar']); - ?> -

- - -

-

- - -

-

- - -

-

- -

-

- - -

-

- -

-

- -

-