From 7a91eb7321d49bc98f672f8c39b3a16348a06106 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Jul 2026 01:06:20 +0800 Subject: [PATCH 01/18] feat(widgets): user-card guest/login depth, main posts, term aggregation 1:1 zibll user widget guest shell + checkin/actions, main post list styles, term aggregation cards, and ranking by check-in days. --- assets/css/frontend/widget-batch5.css | 229 +++++++++++++++ assets/css/frontend/widgets.css | 1 + inc/modules/widgets-register.php | 2 + src/AKSRT/Widgets/WidgetMainPosts.php | 207 +++++++++++++ src/AKSRT/Widgets/WidgetTermAggregation.php | 197 +++++++++++++ src/AKSRT/Widgets/WidgetUserCard.php | 304 ++++++++++++-------- src/AKSRT/Widgets/WidgetUserRanking.php | 70 ++++- 7 files changed, 884 insertions(+), 126 deletions(-) create mode 100644 assets/css/frontend/widget-batch5.css create mode 100644 src/AKSRT/Widgets/WidgetMainPosts.php create mode 100644 src/AKSRT/Widgets/WidgetTermAggregation.php diff --git a/assets/css/frontend/widget-batch5.css b/assets/css/frontend/widget-batch5.css new file mode 100644 index 00000000..63f5d4e2 --- /dev/null +++ b/assets/css/frontend/widget-batch5.css @@ -0,0 +1,229 @@ +/** + * Batch5: user card guest/login depth, main posts, term aggregation. + */ + +.aksrt-user-card { + border-radius: 12px; + overflow: hidden; + border: 1px solid var(--color-line, #e5e7eb); + background: var(--surface-1, #fff); + text-align: center; + margin-bottom: 12px; +} +.aksrt-user-card__cover { + height: 90px; + background: linear-gradient(135deg, #93c5fd, #c4b5fd) center/cover no-repeat; +} +.aksrt-user-card__cover.is-empty { + background: linear-gradient(135deg, #e2e8f0, #f8fafc); +} +.aksrt-user-card__body { padding: 0 14px 16px; position: relative; } +.aksrt-user-card__checkin { + position: absolute; + right: 10px; + top: 8px; + z-index: 2; + max-width: 48%; +} +.aksrt-user-card__checkin .but { + padding: 4px 8px !important; + font-size: 12px !important; + line-height: 1.2; +} +.aksrt-user-card__checkin .aksrt-header-checkin-details { display: none; } +.aksrt-user-card__avatar { + display: inline-block; + margin-top: -36px; + width: 72px; + height: 72px; + border-radius: 50%; + overflow: hidden; + border: 3px solid var(--surface-1, #fff); + background: var(--surface-2, #eee); +} +.aksrt-user-card__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; } +.aksrt-user-card__name { + margin: 10px 0 0; + font-size: 16px; + font-weight: 700; +} +.aksrt-user-card__name a { color: inherit; text-decoration: none; } +.aksrt-user-card__bio, +.aksrt-user-card__guest-title { + margin: 8px 0 0; + font-size: 12px; + color: var(--muted-2-color, #888); + line-height: 1.5; +} +.aksrt-user-card__guest-title { font-size: 14px; font-weight: 600; color: inherit; } +.aksrt-user-card__stats { + display: flex; + justify-content: center; + gap: 18px; + margin-top: 12px; +} +.aksrt-user-card__stat-value { + display: block; + font-size: 16px; + font-weight: 700; +} +.aksrt-user-card__stat-label { + font-size: 11px; + color: var(--muted-2-color, #999); +} +.aksrt-user-card__actions { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 8px; + margin-top: 14px; +} +.aksrt-user-card__btn { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 96px; + padding: 7px 14px; + border-radius: 999px; + font-size: 13px; + text-decoration: none; + font-weight: 600; +} +.aksrt-user-card__btn--primary { + background: var(--color-primary, #3b82f6); + color: #fff !important; +} +.aksrt-user-card__btn--ghost { + background: var(--surface-2, #f3f4f6); + color: inherit !important; +} + +/* Main posts */ +.aksrt-main-posts { display: flex; flex-direction: column; gap: 10px; } +.aksrt-main-posts.style-card { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 12px; +} +@media (max-width: 575.98px) { + .aksrt-main-posts.style-card { grid-template-columns: 1fr; } +} +.aksrt-main-posts__card { + display: block; + border-radius: 12px; + overflow: hidden; + border: 1px solid var(--color-line, #e5e7eb); + background: var(--surface-1, #fff); + text-decoration: none; + color: inherit; +} +.aksrt-main-posts__thumb { + height: 110px; + background: var(--surface-2, #f3f4f6); + overflow: hidden; +} +.aksrt-main-posts__thumb.mini { + width: 56px; + height: 56px; + border-radius: 8px; + flex-shrink: 0; +} +.aksrt-main-posts__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; } +.aksrt-main-posts__thumb.is-empty { background: linear-gradient(135deg, #e2e8f0, #f8fafc); } +.aksrt-main-posts__body { padding: 10px 12px 12px; min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 4px; } +.aksrt-main-posts__title { + font-size: 13px; + font-weight: 600; + line-height: 1.4; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} +.aksrt-main-posts__meta { + display: flex; + gap: 10px; + font-size: 11px; + color: var(--muted-2-color, #999); +} +.aksrt-main-posts__row { + display: flex; + align-items: center; + gap: 10px; + text-decoration: none; + color: inherit; + padding: 4px 0; + border-bottom: 1px dashed var(--color-line, #e5e7eb); +} +.aksrt-main-posts__row:last-child { border-bottom: 0; } +.aksrt-main-posts__num { + width: 20px; + flex-shrink: 0; + font-size: 12px; + font-weight: 700; + color: var(--color-primary, #3b82f6); + text-align: center; +} + +/* Term aggregation */ +.aksrt-term-agg { + display: grid; + grid-template-columns: repeat(var(--aksrt-ta-cols, 1), minmax(0, 1fr)); + gap: 12px; +} +.aksrt-term-agg__card { + border: 1px solid var(--color-line, #e5e7eb); + border-radius: 12px; + overflow: hidden; + background: var(--surface-1, #fff); +} +.aksrt-term-agg__head { + display: block; + text-decoration: none; + color: inherit; + position: relative; +} +.aksrt-term-agg__cover { + height: 96px; + background: var(--surface-2, #f3f4f6) center/cover no-repeat; +} +.aksrt-term-agg__cover.is-empty { + background: linear-gradient(135deg, #dbeafe, #eff6ff); +} +.aksrt-term-agg__name { + position: absolute; + left: 12px; + bottom: 10px; + font-weight: 700; + color: #fff; + text-shadow: 0 1px 3px rgba(0,0,0,.45); +} +.aksrt-term-agg__count { + position: absolute; + right: 10px; + top: 10px; + font-size: 11px; + padding: 2px 8px; + border-radius: 999px; + background: rgba(0,0,0,.45); + color: #fff; +} +.aksrt-term-agg__posts { + list-style: none; + margin: 0; + padding: 8px 12px 10px; +} +.aksrt-term-agg__posts li { + padding: 6px 0; + border-bottom: 1px dashed var(--color-line, #eee); +} +.aksrt-term-agg__posts li:last-child { border-bottom: 0; } +.aksrt-term-agg__posts a { + color: inherit; + text-decoration: none; + font-size: 13px; + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/assets/css/frontend/widgets.css b/assets/css/frontend/widgets.css index 69e0c933..69820df2 100644 --- a/assets/css/frontend/widgets.css +++ b/assets/css/frontend/widgets.css @@ -8,3 +8,4 @@ @import url("widget-batch3d.css"); @import url("widget-batch3e.css"); @import url("widget-batch3f.css"); +@import url("widget-batch5.css"); diff --git a/inc/modules/widgets-register.php b/inc/modules/widgets-register.php index 8ba39126..b0390149 100644 --- a/inc/modules/widgets-register.php +++ b/inc/modules/widgets-register.php @@ -74,6 +74,8 @@ function aksrt_register_widgets() { register_widget('\AKSRT\Widgets\WidgetAuthorCard'); register_widget('\AKSRT\Widgets\WidgetOnelinePosts'); register_widget('\AKSRT\Widgets\WidgetTiltCases'); + register_widget('\AKSRT\Widgets\WidgetMainPosts'); + register_widget('\AKSRT\Widgets\WidgetTermAggregation'); // Forum widgets diff --git a/src/AKSRT/Widgets/WidgetMainPosts.php b/src/AKSRT/Widgets/WidgetMainPosts.php new file mode 100644 index 00000000..f2ce4ff8 --- /dev/null +++ b/src/AKSRT/Widgets/WidgetMainPosts.php @@ -0,0 +1,207 @@ + esc_html__('卡片/迷你/列表样式的文章模块。', 'aksrt'), + 'classname' => 'widget_aksrt_main_posts', + ] + ); + } + + public function widget($args, $instance): void { + $count = max(1, min(30, (int) ($instance['count'] ?? 6))); + $style = sanitize_key((string) ($instance['style'] ?? 'list')); + if (!in_array($style, ['list', 'card', 'mini'], true)) { + $style = 'list'; + } + $orderby = sanitize_key((string) ($instance['orderby'] ?? 'date')); + $cat = (int) ($instance['cat'] ?? 0); + $limit_day = max(0, (int) ($instance['limit_day'] ?? 0)); + $show_thumb = !isset($instance['show_thumb']) || !empty($instance['show_thumb']); + $show_meta = !isset($instance['show_meta']) || !empty($instance['show_meta']); + $show_number = !empty($instance['show_number']); + + $query = [ + 'post_type' => 'post', + 'post_status' => 'publish', + 'posts_per_page' => $count, + 'ignore_sticky_posts' => true, + 'no_found_rows' => true, + ]; + if ($cat > 0) { + $query['cat'] = $cat; + } + if ($limit_day > 0) { + $query['date_query'] = [['after' => $limit_day . ' days ago']]; + } + switch ($orderby) { + case 'views': + $query['meta_key'] = 'aksrt_post_views'; + $query['orderby'] = 'meta_value_num'; + $query['order'] = 'DESC'; + break; + case 'comments': + $query['orderby'] = 'comment_count'; + $query['order'] = 'DESC'; + break; + case 'rand': + $query['orderby'] = 'rand'; + break; + case 'modified': + $query['orderby'] = 'modified'; + $query['order'] = 'DESC'; + break; + default: + $query['orderby'] = 'date'; + $query['order'] = 'DESC'; + } + + $q = new \WP_Query($query); + if (!$q->have_posts()) { + wp_reset_postdata(); + return; + } + + echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + $title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base); + if ($title !== '') { + echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + echo '
'; + $i = 0; + while ($q->have_posts()) { + $q->the_post(); + $i++; + $thumb = $show_thumb ? get_the_post_thumbnail_url(get_the_ID(), $style === 'card' ? 'medium' : 'thumbnail') : ''; + $views = (int) get_post_meta(get_the_ID(), 'aksrt_post_views', true); + + if ($style === 'card') { + echo ''; + echo '
'; + if ($thumb) { + echo ''; + } + echo '
'; + echo '
'; + echo '
' . esc_html(get_the_title()) . '
'; + if ($show_meta) { + echo '
' . esc_html(get_the_date()) . ''; + if ($views > 0) { + echo ' ' . esc_html((string) $views) . ''; + } + echo '
'; + } + echo '
'; + } else { + echo ''; + if ($show_number) { + echo '' . esc_html((string) $i) . ''; + } + if ($show_thumb) { + echo ''; + if ($thumb) { + echo ''; + } + echo ''; + } + echo ''; + echo '' . esc_html(get_the_title()) . ''; + if ($show_meta) { + echo '' . esc_html(get_the_date()) . ''; + } + echo ''; + } + } + echo '
'; + wp_reset_postdata(); + + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + public function form($instance): void { + ?> +

+ +

+

+ +

+

+ +

+

+ +

+

+ +

+

+ +

+

+
+
+ +

+ sanitize_text_field((string) ($new_instance['title'] ?? '')), + 'count' => max(1, min(30, (int) ($new_instance['count'] ?? 6))), + 'style' => $style, + 'orderby' => $orderby, + 'cat' => max(0, (int) ($new_instance['cat'] ?? 0)), + 'limit_day' => max(0, (int) ($new_instance['limit_day'] ?? 0)), + 'show_thumb' => !empty($new_instance['show_thumb']) ? 1 : 0, + 'show_meta' => !empty($new_instance['show_meta']) ? 1 : 0, + 'show_number' => !empty($new_instance['show_number']) ? 1 : 0, + ]; + } +} diff --git a/src/AKSRT/Widgets/WidgetTermAggregation.php b/src/AKSRT/Widgets/WidgetTermAggregation.php new file mode 100644 index 00000000..be75dcff --- /dev/null +++ b/src/AKSRT/Widgets/WidgetTermAggregation.php @@ -0,0 +1,197 @@ + esc_html__('分类封面 + 最新文章列表聚合卡。', 'aksrt'), + 'classname' => 'widget_aksrt_term_aggregation', + ] + ); + } + + public function widget($args, $instance): void { + $taxonomy = sanitize_key((string) ($instance['taxonomy'] ?? 'category')); + if (!taxonomy_exists($taxonomy)) { + $taxonomy = 'category'; + } + $term_ids = $this->parse_ids((string) ($instance['term_ids'] ?? '')); + $count = max(1, min(12, (int) ($instance['count'] ?? 4))); + $orderby = sanitize_key((string) ($instance['orderby'] ?? 'date')); + $columns = max(1, min(3, (int) ($instance['columns'] ?? 1))); + + if (!$term_ids) { + // Fallback: top terms by count. + $terms = get_terms([ + 'taxonomy' => $taxonomy, + 'number' => max(1, min(4, (int) ($instance['auto_terms'] ?? 2))), + 'orderby' => 'count', + 'order' => 'DESC', + 'hide_empty' => true, + ]); + if (is_wp_error($terms) || !$terms) { + return; + } + $term_ids = array_map(static fn($t) => (int) $t->term_id, $terms); + } + + echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + $title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base); + if ($title !== '') { + echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + echo '
'; + foreach ($term_ids as $term_id) { + $term = get_term($term_id, $taxonomy); + if (!$term || is_wp_error($term)) { + continue; + } + $link = get_term_link($term); + if (is_wp_error($link)) { + continue; + } + $cover = ''; + $img_id = (int) get_term_meta($term_id, 'thumbnail_id', true); + if (!$img_id) { + $img_id = (int) get_term_meta($term_id, '_aksrt_cover', true); + } + if ($img_id) { + $cover = wp_get_attachment_image_url($img_id, 'medium') ?: ''; + } + if ($cover === '') { + $cover = (string) get_term_meta($term_id, '_aksrt_cover_url', true); + } + + $posts_q = [ + 'post_type' => 'post', + 'post_status' => 'publish', + 'posts_per_page' => $count, + 'ignore_sticky_posts' => true, + 'no_found_rows' => true, + 'tax_query' => [[ + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $term_id, + ]], + ]; + if ($orderby === 'views') { + $posts_q['meta_key'] = 'aksrt_post_views'; + $posts_q['orderby'] = 'meta_value_num'; + $posts_q['order'] = 'DESC'; + } elseif ($orderby === 'modified') { + $posts_q['orderby'] = 'modified'; + $posts_q['order'] = 'DESC'; + } else { + $posts_q['orderby'] = 'date'; + $posts_q['order'] = 'DESC'; + } + $q = new \WP_Query($posts_q); + + echo '
'; + echo ''; + echo '
'; + echo '
' . esc_html($term->name) . '
'; + echo '
' . esc_html(sprintf(_n('%d 篇', '%d 篇', (int) $term->count, 'aksrt'), (int) $term->count)) . '
'; + echo '
'; + if ($q->have_posts()) { + echo ''; + wp_reset_postdata(); + } + echo '
'; + } + echo '
'; + + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + /** @return array */ + private function parse_ids(string $raw): array { + if ($raw === '') { + return []; + } + $ids = []; + foreach (preg_split('/[\s,]+/', $raw) ?: [] as $p) { + $id = (int) $p; + if ($id > 0) { + $ids[] = $id; + } + } + return array_values(array_unique($ids)); + } + + public function form($instance): void { + $taxs = get_taxonomies(['public' => true], 'objects'); + ?> +

+ +

+

+ +

+

+ +

+

+ + +

+

+ +

+ sanitize_text_field((string) ($new_instance['title'] ?? '')), + 'taxonomy' => sanitize_key((string) ($new_instance['taxonomy'] ?? 'category')), + 'term_ids' => sanitize_text_field((string) ($new_instance['term_ids'] ?? '')), + 'count' => max(1, min(12, (int) ($new_instance['count'] ?? 4))), + 'columns' => max(1, min(3, (int) ($new_instance['columns'] ?? 1))), + 'orderby' => $orderby, + 'auto_terms' => max(1, min(4, (int) ($new_instance['auto_terms'] ?? 2))), + ]; + } +} diff --git a/src/AKSRT/Widgets/WidgetUserCard.php b/src/AKSRT/Widgets/WidgetUserCard.php index 4810a259..5be7120f 100644 --- a/src/AKSRT/Widgets/WidgetUserCard.php +++ b/src/AKSRT/Widgets/WidgetUserCard.php @@ -1,5 +1,7 @@ __('在侧栏显示当前登录用户或指定用户的信息卡片。', 'aksrt')] - ); - } + public function __construct() { + parent::__construct( + 'aksrt_user_card', + __('用户卡片', 'aksrt'), + ['description' => __('未登录显示登录入口;登录后显示当前用户卡片、签到与快捷按钮。', 'aksrt')] + ); + } - public function widget($args, $instance): void { - $title = !empty($instance['title']) ? $instance['title'] : ''; - $show_stats = !empty($instance['show_stats']); - $show_actions = !empty($instance['show_actions']); + public function widget($args, $instance): void { + $show_cover = !isset($instance['show_img_bg']) || !empty($instance['show_img_bg']); + $show_stats = !empty($instance['show_stats']) || !isset($instance['show_stats']); + $show_actions = !empty($instance['show_button']) || !isset($instance['show_button']); + $show_checkin = !empty($instance['show_checkin']) || !isset($instance['show_checkin']); + $loged_title = (string) ($instance['loged_title'] ?? __('Hi!请登录', 'aksrt')); + $btn1_text = (string) ($instance['button_1_text'] ?? __('发布文章', 'aksrt')); + $btn2_text = (string) ($instance['button_2_text'] ?? __('用户中心', 'aksrt')); - // 获取目标用户 - $user_id = !empty($instance['user_id']) ? (int) $instance['user_id'] : 0; - if ($user_id <= 0 && is_user_logged_in()) { - $user_id = get_current_user_id(); - } + // Fixed user id wins; else current user. + $user_id = !empty($instance['user_id']) ? (int) $instance['user_id'] : 0; + if ($user_id <= 0 && is_user_logged_in()) { + $user_id = get_current_user_id(); + } - if ($user_id <= 0) return; + echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + $title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base); + if ($title !== '') { + echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } - $user = get_userdata($user_id); - if (!$user) return; + if ($user_id <= 0) { + $this->render_guest($show_cover, $loged_title); + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + return; + } - // 获取用户统计 - $post_count = count_user_posts($user_id, 'post', true); - $comment_count = get_comments(['user_id' => $user_id, 'count' => true]); - $follower_count = 0; - $following_count = 0; - if (class_exists('\AKSRT\User\Follow')) { - $follower_count = \AKSRT\User\Follow::get_instance()->get_follower_count($user_id); - $following_count = \AKSRT\User\Follow::get_instance()->get_following_count($user_id); - } + $user = get_userdata($user_id); + if (!$user) { + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + return; + } - // 头像 - $avatar_url = function_exists('aksrt_get_avatar_url') - ? aksrt_get_avatar_url($user_id, ['size' => 144]) - : get_avatar_url($user_id, ['size' => 144]); + $is_self = is_user_logged_in() && (int) get_current_user_id() === $user_id; + $avatar_url = function_exists('aksrt_get_avatar_url') + ? aksrt_get_avatar_url($user_id, ['size' => 144]) + : get_avatar_url($user_id, ['size' => 144]); + $profile_url = function_exists('aksrt_get_user_home_url') + ? aksrt_get_user_home_url($user_id) + : get_author_posts_url($user_id); + $center_url = function_exists('aksrt_get_user_center_url') + ? aksrt_get_user_center_url() + : $profile_url; + $compose_url = home_url('/'); + // Prefer front submit / write page when available. + if (function_exists('get_pages')) { + $pages = get_pages(['meta_key' => '_wp_page_template', 'meta_value' => 'templates/pages/page-submit.php', 'number' => 1]); + if (!empty($pages[0])) { + $compose_url = get_permalink($pages[0]); + } + } + if ($compose_url === home_url('/') && function_exists('aksrt_get_user_center_url')) { + $compose_url = aksrt_get_user_center_url('posts'); + } + $bio = get_user_meta($user_id, 'description', true); + if (!is_string($bio) || $bio === '') { + $bio = (string) $user->description; + } + $cover = (string) get_user_meta($user_id, 'aksrt_cover', true); + if ($cover === '') { + $cover = (string) get_user_meta($user_id, 'custom_avatar_cover', true); + } - // 用户主页链接 - $profile_url = function_exists('aksrt_get_user_home_url') - ? aksrt_get_user_home_url($user_id) - : get_author_posts_url($user_id); + $post_count = count_user_posts($user_id, 'post', true); + $follower_count = 0; + $following_count = 0; + if (class_exists('\AKSRT\User\Follow')) { + $follower_count = \AKSRT\User\Follow::get_instance()->get_follower_count($user_id); + $following_count = \AKSRT\User\Follow::get_instance()->get_following_count($user_id); + } - // 简介 - $bio = get_user_meta($user_id, 'description', true); - if (!$bio) $bio = $user->description ?: ''; + echo '
'; + if ($show_cover) { + $bg = $cover !== '' ? ' style="background-image:url(' . esc_url($cover) . ')"' : ''; + echo '
'; + } + echo '
'; + if ($show_checkin && $is_self && function_exists('aksrt_header_user_checkin_btn')) { + // Reuse compact check-in button markup (without details if already long). + $btn = aksrt_header_user_checkin_btn($user_id); + if ($btn !== '') { + echo '
' . $btn . '
'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } + echo '
'; + echo '' . esc_attr($user->display_name) . ''; + echo '
'; + echo '

' . esc_html($user->display_name) . '

'; + if ($bio !== '') { + echo '

' . esc_html(wp_trim_words($bio, 24)) . '

'; + } + if ($show_stats) { + echo '
'; + echo '
' . esc_html(number_format_i18n($post_count)) . '' . esc_html__('文章', 'aksrt') . '
'; + echo '
' . esc_html(number_format_i18n($follower_count)) . '' . esc_html__('粉丝', 'aksrt') . '
'; + echo '
' . esc_html(number_format_i18n($following_count)) . '' . esc_html__('关注', 'aksrt') . '
'; + echo '
'; + } + if ($show_actions && $is_self) { + echo ''; + } elseif ($show_actions) { + echo ''; + } + echo '
'; - echo $args['before_widget']; + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } - if ($title) { - echo $args['before_title'] . esc_html($title) . $args['after_title']; - } + private function render_guest(bool $show_cover, string $loged_title): void { + $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(); + $default_avatar = function_exists('get_avatar_url') + ? get_avatar_url(0, ['size' => 144, 'force_default' => true]) + : includes_url('images/blank.gif'); - echo '
'; + echo '
'; + if ($show_cover) { + echo '
'; + } + echo '
'; + echo '
'; + echo '
' . esc_html($loged_title) . '
'; + echo '
'; + echo ''; + if ($register) { + echo '' . esc_html__('注册', 'aksrt') . ''; + } + echo '
'; + } - // 头像 - echo '
'; - echo ''; - echo '' . esc_attr($user->display_name) . ''; - echo ''; - echo '
'; + public function form($instance): void { + ?> +

+ +

+

+ +

+

+ +

+

+ +

+

+ +

+

+
+
+
+ +

+ '; - echo '' . esc_html($user->display_name) . ''; - echo ''; - - // 简介 - if ($bio) { - echo '

' . esc_html(wp_trim_words($bio, 20)) . '

'; - } - - // 统计 - if ($show_stats) { - echo '
'; - echo '
' . number_format_i18n($post_count) . '' . esc_html__('文章', 'aksrt') . '
'; - echo '
' . number_format_i18n($follower_count) . '' . esc_html__('粉丝', 'aksrt') . '
'; - echo '
' . number_format_i18n($following_count) . '' . esc_html__('关注', 'aksrt') . '
'; - echo '
'; - } - - // 操作按钮 - if ($show_actions) { - echo '
'; - if (is_user_logged_in() && (int) get_current_user_id() === $user_id) { - echo '' . esc_html__('个人主页', 'aksrt') . ''; - if (function_exists('aksrt_get_user_center_url')) { - echo '' . esc_html__('设置', 'aksrt') . ''; - } - } else { - echo '' . esc_html__('查看主页', 'aksrt') . ''; - } - echo '
'; - } - - echo '
'; - - echo $args['after_widget']; - } - - public function form($instance): void { - $title = !empty($instance['title']) ? $instance['title'] : ''; - $user_id = !empty($instance['user_id']) ? (int) $instance['user_id'] : 0; - $show_stats = !empty($instance['show_stats']); - $show_actions = !empty($instance['show_actions']); - ?> -

- - -

-

- - -

-

- -

-

- -

- sanitize_text_field((string) ($new_instance['title'] ?? '')), + 'user_id' => max(0, (int) ($new_instance['user_id'] ?? 0)), + 'loged_title' => sanitize_text_field((string) ($new_instance['loged_title'] ?? '')), + 'button_1_text' => sanitize_text_field((string) ($new_instance['button_1_text'] ?? '')), + 'button_2_text' => sanitize_text_field((string) ($new_instance['button_2_text'] ?? '')), + 'show_img_bg' => !empty($new_instance['show_img_bg']) ? 1 : 0, + 'show_stats' => !empty($new_instance['show_stats']) ? 1 : 0, + 'show_button' => !empty($new_instance['show_button']) ? 1 : 0, + 'show_checkin' => !empty($new_instance['show_checkin']) ? 1 : 0, + ]; + } } diff --git a/src/AKSRT/Widgets/WidgetUserRanking.php b/src/AKSRT/Widgets/WidgetUserRanking.php index 4094f7a5..c64dd3c2 100644 --- a/src/AKSRT/Widgets/WidgetUserRanking.php +++ b/src/AKSRT/Widgets/WidgetUserRanking.php @@ -29,6 +29,13 @@ class WidgetUserRanking extends \WP_Widget { echo $args['before_widget']; echo $args['before_title'] . esc_html($title) . $args['after_title']; + 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 + } + } + echo '