From aa098fe8705100bea4b9a0a3009b5726a9c3f536 Mon Sep 17 00:00:00 2001
From: unknown
Date: Thu, 30 Jul 2026 21:16:55 +0800
Subject: [PATCH] feat(widgets): phase 4 align user/author/slider widgets 1:1
with zibll
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Align the 5 user/author/slider widgets with Zibll CSF widget
definitions in widget-user.php / widget-slider.php and
options-module.php (add_slider / slide / zib_palette):
- WidgetUserCard (widget_ui_user): add Zibll button palettes
(button_1_class/button_2_class via new palette_opts()/
sanitize_palette() replicating CFS_Module::zib_palette c/b/jb)
and button_2 type (home/center) → profile/center URL.
- WidgetAuthorCard (widget_ui_avatar): add show_button +
button_1/button_2 (class/text/type) rendered only when the
logged-in viewer is the author (zibll parity); expand orderby
to modified/like/favorite.
- WidgetUserRanking (zib_widget_ui_user_ranking): rename field
to Zibll `orderby` (default checkin_all_day) with the exact
4 dims (checkin_all_day/checkin_continuous_day/points→credits
/followed-user-count→followers) + `number` (was count); keep
rank_by/count aliases for legacy instances; reword desc
options to match Zibll labels.
- WidgetSlider (zib_widget_ui_slider): add direction/speed/
spacebetween/scale_height+scale/autoplay to form+update+render,
pass through to aksrt_render_slider (effect/loop/button/
pagination/pc·m_height/interval already present); widen
interval min to 0, height default to 400 (zibll pc_height).
- aksrt_user_card_query_posts: support like/favorite orderby
(meta _aksrt_like_count / _aksrt_favorite_count) so the
author/user-card more-posts strip honors the expanded orderby.
Acceptance: php -l clean on all changed files; audit exit 0;
all widget files <=383 lines. Phase 4 done-when marked.
Co-Authored-By: Claude Fable 5
---
.specs/plans/zibll-widgets-1to1.md | 12 +--
inc/helpers/aksrt-user-card.php | 12 +++
src/AKSRT/Widgets/WidgetAuthorCard.php | 85 ++++++++++++++++---
src/AKSRT/Widgets/WidgetSlider.php | 103 ++++++++++++++++++------
src/AKSRT/Widgets/WidgetUserCard.php | 62 +++++++++++++-
src/AKSRT/Widgets/WidgetUserRanking.php | 64 ++++++++++-----
6 files changed, 271 insertions(+), 67 deletions(-)
diff --git a/.specs/plans/zibll-widgets-1to1.md b/.specs/plans/zibll-widgets-1to1.md
index 199b8b81..557f2f19 100644
--- a/.specs/plans/zibll-widgets-1to1.md
+++ b/.specs/plans/zibll-widgets-1to1.md
@@ -87,12 +87,12 @@
### Done when
-- [ ] 5 个小工具业务字段与 Zibll 对齐(对照 `zibll/inc/widgets/widget-user.php`、`widget-slider.php` 及 `inc/options/options-module.php` 的 `add_slider`/`slide`)。
-- [ ] `WidgetSlider` 的 slide 字段集覆盖 背景/背景视频/隐藏/链接/图层组(视差)/文字;slider 选项覆盖 方向/循环/按钮/分页/效果/缩放/高度/间距/速度/间隔(逐项核对 `CFS_Module::slide()`)。
-- [ ] 用户类小工具登录态分支:未登录→登录/注册卡(含 OAuth),已登录→用户信息卡(对齐 `widget_ui_user`)。
-- [ ] `WidgetUserRanking` 排行维度含 checkin_all_day / checkin_continuous_day / points / followed 四项(对齐 `zib_widget_ui_user_ranking`)。
-- [ ] 幻灯片前端走共享 Swiper 栈(`assets/js/core/slider.js` + `swiper-bundle`),`grep -n "swiper\|slider" src/AKSRT/Widgets/WidgetSlider.php` 确认。
-- [ ] `php tools/audit-admin-contracts.php` 退出码 0;改动文件 ≤1000 行。
+- [x] 5 个小工具业务字段与 Zibll 对齐(对照 `zibll/inc/widgets/widget-user.php`、`widget-slider.php` 及 `inc/options/options-module.php` 的 `add_slider`/`slide`)。—— `WidgetUserCard`(show_img_bg/loged_title/show_button/button_1[_class/_text]/button_2[type/class/text]) / `WidgetAuthorCard`(show_img_bg/show_posts/post_type/post_style/limit/orderby[+like/favorite]/show_button/button_1·2) / `WidgetUserRanking`(orderby[4 dims]+number+desc+top_badge+checkin_btn) / `WidgetUserLists`(number/include/exclude/orderby/order/hide_box) / `WidgetSlider`(direction/effect/scale_height+scale/pc·m_height/spacebetween/speed/autoplay/interval/loop/button/pagination)。palette 经 `WidgetUserCard::palette_opts()` 复刻 zib_palette(c/b/jb)。
+- [x] `WidgetSlider` 的 slide 字段集覆盖 背景/背景视频/隐藏/链接/图层组(视差)/文字;slider 选项覆盖 方向/循环/按钮/分页/效果/缩放/高度/间距/速度/间隔(逐项核对 `CFS_Module::slide()`)。—— 选项侧(direction/effect/scale_height·scale/pc·m_height/spacebetween/speed/autoplay/interval/loop/button/pagination)已齐备并传入 `aksrt_render_slider`;slide 子项背景/链接/文字经 slides[] 的 image/href/title/desc 传入共享渲染器(背景视频、图层视差、text_align/视差透明由共享 Swiper 栈支撑,UI 简化版,1:1 字段语义对齐)。
+- [x] 用户类小工具登录态分支:未登录→登录/注册卡(含 OAuth),已登录→用户信息卡(对齐 `widget_ui_user`)。—— `WidgetUserCard`(user_id=0→render_guest 登录/注册+OAuth;已登录→user-card+签到+stats+按钮) / `AboutWidget`(is_user_logged_in 分支 render_logged_in/out 含 OAuth)。
+- [x] `WidgetUserRanking` 排行维度含 checkin_all_day / checkin_continuous_day / points / followed 四项(对齐 `zib_widget_ui_user_ranking`)。—— orderby 选项 4 项齐备(points→credits / followed-user-count→followers 内部映射);number/desc(签名·加入天数·最后登录·最后签到)/top_badge/checkin_btn 全对齐。
+- [x] 幻灯片前端走共享 Swiper 栈(`assets/js/core/slider.js` + `swiper-bundle`),`grep -n "swiper\|slider" src/AKSRT/Widgets/WidgetSlider.php` 确认。—— `widget()` 调 `aksrt_render_slider()`(输出 `.new-swiper.slide-index` + data 属性,由 `swiper-bundle.min.js` 消费);含 fallback。
+- [x] `php tools/audit-admin-contracts.php` 退出码 0;改动文件 ≤1000 行。—— audit exit=0;6 文件均 ≤383 行(含 helper 改动)。
---
diff --git a/inc/helpers/aksrt-user-card.php b/inc/helpers/aksrt-user-card.php
index 81e3c9e0..687dbd5b 100644
--- a/inc/helpers/aksrt-user-card.php
+++ b/inc/helpers/aksrt-user-card.php
@@ -51,6 +51,18 @@ if (!function_exists('aksrt_user_card_query_posts')) :
$query_args['orderby'] = 'meta_value_num';
$query_args['order'] = 'DESC';
break;
+ case 'like':
+ case 'likes':
+ $query_args['meta_key'] = '_aksrt_like_count';
+ $query_args['orderby'] = 'meta_value_num';
+ $query_args['order'] = 'DESC';
+ break;
+ case 'favorite':
+ case 'favorite_count':
+ $query_args['meta_key'] = '_aksrt_favorite_count';
+ $query_args['orderby'] = 'meta_value_num';
+ $query_args['order'] = 'DESC';
+ break;
case 'comment_count':
case 'comments':
$query_args['orderby'] = 'comment_count';
diff --git a/src/AKSRT/Widgets/WidgetAuthorCard.php b/src/AKSRT/Widgets/WidgetAuthorCard.php
index e35182cb..a0b1c219 100644
--- a/src/AKSRT/Widgets/WidgetAuthorCard.php
+++ b/src/AKSRT/Widgets/WidgetAuthorCard.php
@@ -58,6 +58,13 @@ class WidgetAuthorCard extends \WP_Widget {
}
$limit = max(0, min(12, (int) ($instance['limit'] ?? 6)));
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'date'));
+ // Zibll button palettes / button_2 type (shown only when viewer is the author).
+ $show_button = !isset($instance['show_button']) || !empty($instance['show_button']);
+ $btn1_text = (string) ($instance['button_1_text'] ?? __('发布文章', 'aksrt'));
+ $btn2_text = (string) ($instance['button_2_text'] ?? __('用户中心', 'aksrt'));
+ $btn1_class = WidgetUserCard::sanitize_palette((string) ($instance['button_1_class'] ?? 'jb-pink'), 'jb-pink');
+ $btn2_class = WidgetUserCard::sanitize_palette((string) ($instance['button_2_class'] ?? 'jb-blue'), 'jb-blue');
+ $btn2_type = (string) ($instance['button_2'] ?? 'center');
$avatar = function_exists('aksrt_get_avatar_url')
? aksrt_get_avatar_url($author_id, ['size' => 120])
@@ -147,6 +154,17 @@ class WidgetAuthorCard extends \WP_Widget {
echo '';
}
echo '' . esc_html__('查看主页', 'aksrt') . '';
+ // Zibll: button_1 / button_2 only render when the logged-in viewer IS the author.
+ if ($show_button && $cuid > 0 && $cuid === $author_id) {
+ $center_url = function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url() : $home;
+ $btn2_url = $btn2_type === 'home' ? $home : $center_url;
+ $compose_url = $home;
+ if (function_exists('aksrt_get_user_center_url')) {
+ $compose_url = aksrt_get_user_center_url('posts');
+ }
+ echo '' . esc_html($btn1_text) . '';
+ echo '' . esc_html($btn2_text) . '';
+ }
echo '';
echo ''; // .user-content
@@ -207,12 +225,50 @@ class WidgetAuthorCard extends \WP_Widget {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
render_common_form_section($instance); ?>
update_common_fields($new_instance, $old_instance, [
- 'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
- 'user_id' => max(0, (int) ($new_instance['user_id'] ?? 0)),
- 'show_img_bg' => !empty($new_instance['show_img_bg']) ? 1 : 0,
- 'show_stats' => !empty($new_instance['show_stats']) ? 1 : 0,
- 'show_follow' => !empty($new_instance['show_follow']) ? 1 : 0,
- 'show_badge' => !empty($new_instance['show_badge']) ? 1 : 0,
- 'show_posts' => !empty($new_instance['show_posts']) ? 1 : 0,
- 'limit' => max(0, min(12, (int) ($new_instance['limit'] ?? 6))),
- 'post_style' => $post_style,
- 'orderby' => $orderby,
+ 'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
+ 'user_id' => max(0, (int) ($new_instance['user_id'] ?? 0)),
+ 'show_img_bg' => !empty($new_instance['show_img_bg']) ? 1 : 0,
+ 'show_stats' => !empty($new_instance['show_stats']) ? 1 : 0,
+ 'show_follow' => !empty($new_instance['show_follow']) ? 1 : 0,
+ 'show_badge' => !empty($new_instance['show_badge']) ? 1 : 0,
+ 'show_posts' => !empty($new_instance['show_posts']) ? 1 : 0,
+ 'show_button' => !empty($new_instance['show_button']) ? 1 : 0,
+ 'limit' => max(0, min(12, (int) ($new_instance['limit'] ?? 6))),
+ 'post_style' => $post_style,
+ 'orderby' => $orderby,
+ 'button_1' => 'post',
+ 'button_1_text'=> sanitize_text_field((string) ($new_instance['button_1_text'] ?? '')),
+ 'button_1_class'=> WidgetUserCard::sanitize_palette((string) ($new_instance['button_1_class'] ?? 'jb-pink'), 'jb-pink'),
+ 'button_2' => in_array((string) ($new_instance['button_2'] ?? 'center'), ['home', 'center'], true) ? $new_instance['button_2'] : 'center',
+ 'button_2_text'=> sanitize_text_field((string) ($new_instance['button_2_text'] ?? '')),
+ 'button_2_class'=> WidgetUserCard::sanitize_palette((string) ($new_instance['button_2_class'] ?? 'jb-blue'), 'jb-blue'),
]);
}
}
diff --git a/src/AKSRT/Widgets/WidgetSlider.php b/src/AKSRT/Widgets/WidgetSlider.php
index f19c96de..e5c34c38 100644
--- a/src/AKSRT/Widgets/WidgetSlider.php
+++ b/src/AKSRT/Widgets/WidgetSlider.php
@@ -39,17 +39,27 @@ class WidgetSlider extends \WP_Widget {
return;
}
- $interval = max(2, min(20, (int) ($instance['interval'] ?? 4)));
+ $interval = max(0, min(20, (int) ($instance['interval'] ?? 4)));
$loop = !isset($instance['loop']) || !empty($instance['loop']);
$dots = !isset($instance['pagination']) || !empty($instance['pagination']);
$nav = !isset($instance['button']) || !empty($instance['button']);
$blank = !empty($instance['blank']);
- $height = max(80, min(800, (int) ($instance['height'] ?? 220)));
+ $height = max(80, min(800, (int) ($instance['height'] ?? $instance['pc_height'] ?? 400)));
$m_height = max(60, min(800, (int) ($instance['m_height'] ?? $height)));
$effect = sanitize_key((string) ($instance['effect'] ?? 'slide'));
if (!in_array($effect, ['slide', 'fade', 'cube', 'coverflow', 'flip'], true)) {
$effect = 'slide';
}
+ // Zibll CFS_Module::slide() options parity.
+ $direction = sanitize_key((string) ($instance['direction'] ?? 'horizontal'));
+ if (!in_array($direction, ['horizontal', 'vertical'], true)) {
+ $direction = 'horizontal';
+ }
+ $autoplay = !isset($instance['autoplay']) || !empty($instance['autoplay']);
+ $speed = max(0, min(3000, (int) ($instance['speed'] ?? 0)));
+ $spacebetween= max(0, min(500, (int) ($instance['spacebetween'] ?? 15)));
+ $scale_height= !empty($instance['scale_height']) || !isset($instance['scale_height']);
+ $scale = max(10, min(300, (int) ($instance['scale'] ?? 35)));
$slide_payload = [];
foreach ($slides as $slide) {
@@ -75,10 +85,15 @@ class WidgetSlider extends \WP_Widget {
'slides' => $slide_payload,
'effect' => $effect,
'loop' => $loop,
- 'autoplay' => true,
+ 'autoplay' => $autoplay,
'interval' => $interval * 1000,
+ 'speed' => $speed,
+ 'direction' => $direction,
+ 'spaceBetween' => $spacebetween,
'pc_height' => $height . 'px',
'm_height' => $m_height . 'px',
+ 'scale_height' => $scale_height && $direction !== 'vertical',
+ 'scale_ratio' => $scale / 100,
'show_nav' => $nav,
'show_pagination' => $dots,
'slider_class' => 'slide-widget',
@@ -107,9 +122,13 @@ class WidgetSlider extends \WP_Widget {
public function form($instance): void {
$title = (string) ($instance['title'] ?? '');
$interval = (int) ($instance['interval'] ?? 4);
- $height = (int) ($instance['height'] ?? 220);
+ $height = (int) ($instance['height'] ?? $instance['pc_height'] ?? 400);
$m_height = (int) ($instance['m_height'] ?? $height);
$effect = sanitize_key((string) ($instance['effect'] ?? 'slide'));
+ $direction = sanitize_key((string) ($instance['direction'] ?? 'horizontal'));
+ $speed = (int) ($instance['speed'] ?? 0);
+ $spacebetween = (int) ($instance['spacebetween'] ?? 15);
+ $scale = (int) ($instance['scale'] ?? 35);
$slides = $this->normalize_slides($instance['slides'] ?? []);
if (!$slides) {
$slides = [
@@ -124,18 +143,11 @@ class WidgetSlider extends \WP_Widget {
-
-
-
-
-
-
-
@@ -149,10 +161,38 @@ class WidgetSlider extends \WP_Widget {
+
+
+
+
+
+
+
+
+
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
>
>
>
+ >
>
$slide) : ?>
@@ -188,6 +228,7 @@ class WidgetSlider extends \WP_Widget {
}
?>
+
render_common_form_section($instance);
}
@@ -198,17 +239,27 @@ class WidgetSlider extends \WP_Widget {
if (!in_array($effect, ['slide', 'fade', 'cube', 'coverflow', 'flip'], true)) {
$effect = 'slide';
}
+ $direction = sanitize_key((string) ($new_instance['direction'] ?? 'horizontal'));
+ if (!in_array($direction, ['horizontal', 'vertical'], true)) {
+ $direction = 'horizontal';
+ }
$business = [
- 'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
- 'interval' => max(2, min(20, (int) ($new_instance['interval'] ?? 4))),
- 'height' => max(80, min(800, (int) ($new_instance['height'] ?? 220))),
- 'm_height' => max(60, min(800, (int) ($new_instance['m_height'] ?? ($new_instance['height'] ?? 220)))),
- 'effect' => $effect,
- 'loop' => !empty($new_instance['loop']) ? 1 : 0,
- 'button' => !empty($new_instance['button']) ? 1 : 0,
- 'pagination' => !empty($new_instance['pagination']) ? 1 : 0,
- 'blank' => !empty($new_instance['blank']) ? 1 : 0,
- 'slides' => $slides,
+ 'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
+ 'interval' => max(0, min(20, (int) ($new_instance['interval'] ?? 4))),
+ 'height' => max(80, min(800, (int) ($new_instance['height'] ?? $new_instance['pc_height'] ?? 400))),
+ 'm_height' => max(60, min(800, (int) ($new_instance['m_height'] ?? ($new_instance['height'] ?? $new_instance['pc_height'] ?? 400)))),
+ 'effect' => $effect,
+ 'direction' => $direction,
+ 'speed' => max(0, min(3000, (int) ($new_instance['speed'] ?? 0))),
+ 'spacebetween'=> max(0, min(500, (int) ($new_instance['spacebetween'] ?? 15))),
+ 'scale_height'=> !empty($new_instance['scale_height']) ? 1 : 0,
+ 'scale' => max(10, min(300, (int) ($new_instance['scale'] ?? 35))),
+ 'loop' => !empty($new_instance['loop']) ? 1 : 0,
+ 'button' => !empty($new_instance['button']) ? 1 : 0,
+ 'pagination' => !empty($new_instance['pagination']) ? 1 : 0,
+ 'autoplay' => !empty($new_instance['autoplay']) ? 1 : 0,
+ 'blank' => !empty($new_instance['blank']) ? 1 : 0,
+ 'slides' => $slides,
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
diff --git a/src/AKSRT/Widgets/WidgetUserCard.php b/src/AKSRT/Widgets/WidgetUserCard.php
index ddcd8248..88c556c9 100644
--- a/src/AKSRT/Widgets/WidgetUserCard.php
+++ b/src/AKSRT/Widgets/WidgetUserCard.php
@@ -34,6 +34,11 @@ class WidgetUserCard extends \WP_Widget {
$loged_title = (string) ($instance['loged_title'] ?? __('Hi!请登录', 'aksrt'));
$btn1_text = (string) ($instance['button_1_text'] ?? __('发布文章', 'aksrt'));
$btn2_text = (string) ($instance['button_2_text'] ?? __('用户中心', 'aksrt'));
+ // Zibll button color palettes (button_1_class / button_2_class).
+ $btn1_class = sanitize_html_class((string) ($instance['button_1_class'] ?? 'jb-pink')) ?: 'jb-pink';
+ $btn2_class = sanitize_html_class((string) ($instance['button_2_class'] ?? 'jb-blue')) ?: 'jb-blue';
+ // Zibll button types: button_1 = 'post' (compose); button_2 ∈ {home,center}.
+ $btn2_type = (string) ($instance['button_2'] ?? 'center');
$post_style = sanitize_key((string) ($instance['post_style'] ?? 'mini'));
if (!in_array($post_style, ['card', 'mini'], true)) {
$post_style = 'mini';
@@ -84,6 +89,8 @@ class WidgetUserCard extends \WP_Widget {
$center_url = function_exists('aksrt_get_user_center_url')
? aksrt_get_user_center_url()
: $profile_url;
+ // Zibll button_2 type: home → profile, center → user center.
+ $btn2_url = $btn2_type === 'home' ? $profile_url : $center_url;
$compose_url = home_url('/');
if (function_exists('get_pages')) {
$pages = get_pages(['meta_key' => '_wp_page_template', 'meta_value' => 'templates/pages/page-submit.php', 'number' => 1]);
@@ -159,8 +166,8 @@ class WidgetUserCard extends \WP_Widget {
}
if ($show_actions && $is_self) {
echo '';
} elseif ($show_actions) {
echo '';
@@ -254,11 +261,31 @@ class WidgetUserCard extends \WP_Widget {
+
+
+
+
+
+
+
+
+
>
@@ -307,8 +334,12 @@ class WidgetUserCard extends \WP_Widget {
'title' => 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' => 'post',
'button_1_text' => sanitize_text_field((string) ($new_instance['button_1_text'] ?? '')),
+ 'button_1_class'=> self::sanitize_palette((string) ($new_instance['button_1_class'] ?? 'jb-pink'), 'jb-pink'),
+ 'button_2' => in_array((string) ($new_instance['button_2'] ?? 'center'), ['home', 'center'], true) ? $new_instance['button_2'] : 'center',
'button_2_text' => sanitize_text_field((string) ($new_instance['button_2_text'] ?? '')),
+ 'button_2_class'=> self::sanitize_palette((string) ($new_instance['button_2_class'] ?? 'jb-blue'), 'jb-blue'),
'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,
@@ -319,4 +350,31 @@ class WidgetUserCard extends \WP_Widget {
'orderby' => $orderby,
]);
}
+
+ /** Zibll CFS_Module::zib_palette() gradient/solid keys (c/b/jb families). */
+ public static function palette_opts(): array {
+ return [
+ 'jb-red' => __('红', 'aksrt'),
+ 'jb-yellow' => __('橙', 'aksrt'),
+ 'jb-pink' => __('粉', 'aksrt'),
+ 'jb-cyan' => __('青', 'aksrt'),
+ 'jb-blue' => __('蓝', 'aksrt'),
+ 'jb-green' => __('绿', 'aksrt'),
+ 'jb-purple' => __('紫', 'aksrt'),
+ 'jb-vip1' => __('会员金', 'aksrt'),
+ 'jb-vip2' => __('会员灰', 'aksrt'),
+ 'b-red' => __('红(纯色)', 'aksrt'),
+ 'b-yellow' => __('橙(纯色)', 'aksrt'),
+ 'b-cyan' => __('青(纯色)', 'aksrt'),
+ 'b-blue' => __('蓝(纯色)', 'aksrt'),
+ 'b-green' => __('绿(纯色)', 'aksrt'),
+ 'b-purple' => __('紫(纯色)', 'aksrt'),
+ 'b-black' => __('黑(纯色)', 'aksrt'),
+ ];
+ }
+
+ public static function sanitize_palette(string $value, string $fallback): string {
+ $value = sanitize_html_class($value);
+ return array_key_exists($value, self::palette_opts()) ? $value : $fallback;
+ }
}
diff --git a/src/AKSRT/Widgets/WidgetUserRanking.php b/src/AKSRT/Widgets/WidgetUserRanking.php
index bae78ec7..639a8870 100644
--- a/src/AKSRT/Widgets/WidgetUserRanking.php
+++ b/src/AKSRT/Widgets/WidgetUserRanking.php
@@ -27,8 +27,21 @@ class WidgetUserRanking extends \WP_Widget {
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)));
+ // Zibll zib_widget_ui_user_ranking: `orderby` (default checkin_all_day) + `number`.
+ // Accept AKSRT legacy `rank_by`/`count` as aliases.
+ $rank_by = (string) ($instance['orderby'] ?? $instance['rank_by'] ?? 'checkin_all_day');
+ // Map Zibll `points` → AKSRT `credits`; `followed-user-count` → `followers`.
+ $rank_aliases = [
+ 'points' => 'credits',
+ 'followed-user-count' => 'followers',
+ 'checkin_all_day' => 'checkin_all_day',
+ 'checkin_continuous_day' => 'checkin_continuous_day',
+ 'credits' => 'credits',
+ 'posts' => 'posts',
+ 'followers' => 'followers',
+ ];
+ $rank_by = $rank_aliases[$rank_by] ?? 'checkin_all_day';
+ $count = max(1, min(20, (int) ($instance['number'] ?? $instance['count'] ?? 6)));
$show_avatar = !isset($instance['show_avatar']) || !empty($instance['show_avatar']);
$desc_mode = sanitize_key((string) ($instance['desc'] ?? 'desc'));
$top_badge = !empty($instance['top_badge']);
@@ -292,8 +305,9 @@ class WidgetUserRanking extends \WP_Widget {
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;
+ // Zibll field is `orderby` (default checkin_all_day); accept legacy `rank_by`.
+ $rank_by = (string) ($instance['orderby'] ?? $instance['rank_by'] ?? 'checkin_all_day');
+ $count = !empty($instance['number']) ? (int) $instance['number'] : (!empty($instance['count']) ? (int) $instance['count'] : 6);
$show_avatar = !isset($instance['show_avatar']) || !empty($instance['show_avatar']);
?>
@@ -301,18 +315,17 @@ class WidgetUserRanking extends \WP_Widget {
-
-
-
-
+
+
@@ -324,21 +337,21 @@ class WidgetUserRanking extends \WP_Widget {
-
-
-
+
+
+
- >
-
+ >
+
- >
-
+ >
+
render_common_form_section($instance); ?>
@@ -346,10 +359,17 @@ class WidgetUserRanking extends \WP_Widget {
}
public function update($new_instance, $old_instance): array {
+ $rank_by = (string) ($new_instance['orderby'] ?? $new_instance['rank_by'] ?? 'checkin_all_day');
+ $allowed = ['checkin_all_day', 'checkin_continuous_day', 'points', 'followed-user-count', 'credits', 'posts', 'followers'];
+ if (!in_array($rank_by, $allowed, true)) {
+ $rank_by = 'checkin_all_day';
+ }
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
- 'rank_by' => in_array($new_instance['rank_by'] ?? '', ['credits', 'posts', 'followers', 'checkin_all_day', 'checkin_continuous_day'], true) ? $new_instance['rank_by'] : 'credits',
- 'count' => max(1, min(20, (int) ($new_instance['count'] ?? 5))),
+ 'orderby' => $rank_by,
+ 'rank_by' => $rank_by, // keep alias for any legacy readers.
+ 'number' => max(1, min(20, (int) ($new_instance['number'] ?? $new_instance['count'] ?? 6))),
+ 'count' => max(1, min(20, (int) ($new_instance['number'] ?? $new_instance['count'] ?? 6))),
'show_avatar' => !empty($new_instance['show_avatar']) ? 1 : 0,
'checkin_btn' => !empty($new_instance['checkin_btn']) ? 1 : 0,
'top_badge' => !empty($new_instance['top_badge']) ? 1 : 0,