Merge pull request 'Worktree ux depth batch8' (#226) from worktree-ux-depth-batch8 into main
Reviewed-on: CYL/wordpress-theme-aksrt#226
This commit is contained in:
commit
2dd3b33cb7
10 files changed
+726
-503
No files matched your search
@@ -776,3 +776,14 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* User ranking extras (batch8) */
|
||||||
|
.aksrt-user-ranking__item { align-items: center; }
|
||||||
|
.aksrt-user-ranking__meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
|
||||||
|
.aksrt-user-ranking__desc {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--muted-2-color, #999);
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
+131
-49
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Public widget list REST endpoints (posts / tab-posts).
|
* Public widget list REST endpoints.
|
||||||
*
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
*/
|
*/
|
||||||
@@ -24,31 +24,30 @@ class WidgetAjax {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function register_routes(): void {
|
public function register_routes(): void {
|
||||||
register_rest_route('aksrt/v1', '/widgets/posts', [
|
$routes = [
|
||||||
'methods' => 'GET',
|
'/widgets/posts' => 'rest_main_posts',
|
||||||
'callback' => [$this, 'rest_main_posts'],
|
'/widgets/tab-posts' => 'rest_tab_posts',
|
||||||
'permission_callback' => '__return_true',
|
'/widgets/paid-posts' => 'rest_paid_posts',
|
||||||
]);
|
'/widgets/category-tabs' => 'rest_category_tabs',
|
||||||
register_rest_route('aksrt/v1', '/widgets/tab-posts', [
|
'/widgets/hot-posts' => 'rest_hot_posts',
|
||||||
'methods' => 'GET',
|
'/widgets/oneline-posts' => 'rest_oneline_posts',
|
||||||
'callback' => [$this, 'rest_tab_posts'],
|
'/widgets/recent-comments'=> 'rest_recent_comments',
|
||||||
'permission_callback' => '__return_true',
|
'/widgets/user-lists' => 'rest_user_lists',
|
||||||
]);
|
'/widgets/forum-topics' => 'rest_forum_topics',
|
||||||
register_rest_route('aksrt/v1', '/widgets/paid-posts', [
|
'/widgets/forum-terms' => 'rest_forum_terms',
|
||||||
'methods' => 'GET',
|
];
|
||||||
'callback' => [$this, 'rest_paid_posts'],
|
foreach ($routes as $path => $cb) {
|
||||||
'permission_callback' => '__return_true',
|
register_rest_route('aksrt/v1', $path, [
|
||||||
]);
|
'methods' => 'GET',
|
||||||
register_rest_route('aksrt/v1', '/widgets/category-tabs', [
|
'callback' => [$this, $cb],
|
||||||
'methods' => 'GET',
|
'permission_callback' => '__return_true',
|
||||||
'callback' => [$this, 'rest_category_tabs'],
|
]);
|
||||||
'permission_callback' => '__return_true',
|
}
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rest_main_posts(\WP_REST_Request $request) {
|
public function rest_main_posts(\WP_REST_Request $request) {
|
||||||
if (!class_exists('\AKSRT\Widgets\WidgetMainPosts')) {
|
if (!class_exists('\AKSRT\Widgets\WidgetMainPosts')) {
|
||||||
return new \WP_REST_Response(['success' => false, 'message' => 'unavailable'], 500);
|
return $this->fail();
|
||||||
}
|
}
|
||||||
$instance = [
|
$instance = [
|
||||||
'count' => max(1, min(30, (int) ($request->get_param('count') ?? 6))),
|
'count' => max(1, min(30, (int) ($request->get_param('count') ?? 6))),
|
||||||
@@ -62,21 +61,12 @@ class WidgetAjax {
|
|||||||
'paginate' => sanitize_key((string) ($request->get_param('paginate') ?? 'ajax')),
|
'paginate' => sanitize_key((string) ($request->get_param('paginate') ?? 'ajax')),
|
||||||
];
|
];
|
||||||
$page = max(1, (int) ($request->get_param('page') ?? $request->get_param('paged') ?? 1));
|
$page = max(1, (int) ($request->get_param('page') ?? $request->get_param('paged') ?? 1));
|
||||||
$payload = \AKSRT\Widgets\WidgetMainPosts::query_payload($instance, $page);
|
return $this->payload(\AKSRT\Widgets\WidgetMainPosts::query_payload($instance, $page), $page);
|
||||||
return new \WP_REST_Response([
|
|
||||||
'success' => true,
|
|
||||||
'html' => (string) ($payload['html'] ?? ''),
|
|
||||||
'paginate_html' => (string) ($payload['paginate_html'] ?? ''),
|
|
||||||
'has_more' => !empty($payload['has_more']),
|
|
||||||
'page' => (int) ($payload['page'] ?? $page),
|
|
||||||
'max_pages' => (int) ($payload['max_pages'] ?? 1),
|
|
||||||
'total' => (int) ($payload['total'] ?? 0),
|
|
||||||
], 200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rest_tab_posts(\WP_REST_Request $request) {
|
public function rest_tab_posts(\WP_REST_Request $request) {
|
||||||
if (!class_exists('\AKSRT\Widgets\TabPostsWidget')) {
|
if (!class_exists('\AKSRT\Widgets\TabPostsWidget')) {
|
||||||
return new \WP_REST_Response(['success' => false, 'message' => 'unavailable'], 500);
|
return $this->fail();
|
||||||
}
|
}
|
||||||
$default_count = max(1, min(20, (int) ($request->get_param('count') ?? 5)));
|
$default_count = max(1, min(20, (int) ($request->get_param('count') ?? 5)));
|
||||||
$tab = [
|
$tab = [
|
||||||
@@ -94,15 +84,12 @@ class WidgetAjax {
|
|||||||
} else {
|
} else {
|
||||||
$html = '<div class="widget-tab-posts__list widget-tab-posts__list--mini aksrt-main-posts style-mini">' . $html . '</div>';
|
$html = '<div class="widget-tab-posts__list widget-tab-posts__list--mini aksrt-main-posts style-mini">' . $html . '</div>';
|
||||||
}
|
}
|
||||||
return new \WP_REST_Response([
|
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||||
'success' => true,
|
|
||||||
'html' => $html,
|
|
||||||
], 200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rest_paid_posts(\WP_REST_Request $request) {
|
public function rest_paid_posts(\WP_REST_Request $request) {
|
||||||
if (!class_exists('\AKSRT\Widgets\WidgetPaidPosts')) {
|
if (!class_exists('\AKSRT\Widgets\WidgetPaidPosts')) {
|
||||||
return new \WP_REST_Response(['success' => false, 'message' => 'unavailable'], 500);
|
return $this->fail();
|
||||||
}
|
}
|
||||||
$instance = [
|
$instance = [
|
||||||
'count' => max(1, min(20, (int) ($request->get_param('count') ?? 6))),
|
'count' => max(1, min(20, (int) ($request->get_param('count') ?? 6))),
|
||||||
@@ -110,16 +97,7 @@ class WidgetAjax {
|
|||||||
'paginate' => sanitize_key((string) ($request->get_param('paginate') ?? 'ajax')),
|
'paginate' => sanitize_key((string) ($request->get_param('paginate') ?? 'ajax')),
|
||||||
];
|
];
|
||||||
$page = max(1, (int) ($request->get_param('page') ?? $request->get_param('paged') ?? 1));
|
$page = max(1, (int) ($request->get_param('page') ?? $request->get_param('paged') ?? 1));
|
||||||
$payload = \AKSRT\Widgets\WidgetPaidPosts::query_payload($instance, $page);
|
return $this->payload(\AKSRT\Widgets\WidgetPaidPosts::query_payload($instance, $page), $page);
|
||||||
return new \WP_REST_Response([
|
|
||||||
'success' => true,
|
|
||||||
'html' => (string) ($payload['html'] ?? ''),
|
|
||||||
'paginate_html' => (string) ($payload['paginate_html'] ?? ''),
|
|
||||||
'has_more' => !empty($payload['has_more']),
|
|
||||||
'page' => (int) ($payload['page'] ?? $page),
|
|
||||||
'max_pages' => (int) ($payload['max_pages'] ?? 1),
|
|
||||||
'total' => (int) ($payload['total'] ?? 0),
|
|
||||||
], 200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rest_category_tabs(\WP_REST_Request $request) {
|
public function rest_category_tabs(\WP_REST_Request $request) {
|
||||||
@@ -152,7 +130,111 @@ class WidgetAjax {
|
|||||||
echo '</ul>';
|
echo '</ul>';
|
||||||
}
|
}
|
||||||
wp_reset_postdata();
|
wp_reset_postdata();
|
||||||
$html = (string) ob_get_clean();
|
return new \WP_REST_Response(['success' => true, 'html' => (string) ob_get_clean()], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rest_hot_posts(\WP_REST_Request $request) {
|
||||||
|
if (!class_exists('\AKSRT\Widgets\HotPostsWidget')) {
|
||||||
|
return $this->fail();
|
||||||
|
}
|
||||||
|
$instance = [
|
||||||
|
'count' => max(1, min(20, (int) ($request->get_param('count') ?? 5))),
|
||||||
|
'order_by' => sanitize_key((string) ($request->get_param('order_by') ?? 'views')),
|
||||||
|
'days' => max(0, (int) ($request->get_param('days') ?? 30)),
|
||||||
|
'show_thumb' => $request->get_param('show_thumb') === null ? 1 : (int) $request->get_param('show_thumb'),
|
||||||
|
'paginate' => sanitize_key((string) ($request->get_param('paginate') ?? 'ajax')),
|
||||||
|
];
|
||||||
|
$page = max(1, (int) ($request->get_param('page') ?? 1));
|
||||||
|
return $this->payload(\AKSRT\Widgets\HotPostsWidget::query_payload($instance, $page), $page);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rest_oneline_posts(\WP_REST_Request $request) {
|
||||||
|
if (!class_exists('\AKSRT\Widgets\WidgetOnelinePosts')) {
|
||||||
|
return $this->fail();
|
||||||
|
}
|
||||||
|
$instance = [
|
||||||
|
'count' => max(1, min(20, (int) ($request->get_param('count') ?? 8))),
|
||||||
|
'style' => sanitize_key((string) ($request->get_param('style') ?? 'card')),
|
||||||
|
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')),
|
||||||
|
'cat' => max(0, (int) ($request->get_param('cat') ?? 0)),
|
||||||
|
'limit_day' => max(0, (int) ($request->get_param('limit_day') ?? 0)),
|
||||||
|
];
|
||||||
|
$html = \AKSRT\Widgets\WidgetOnelinePosts::render_html($instance);
|
||||||
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function rest_recent_comments(\WP_REST_Request $request) {
|
||||||
|
if (!class_exists('\AKSRT\Widgets\RecentCommentsWidget')) {
|
||||||
|
return $this->fail();
|
||||||
|
}
|
||||||
|
$instance = [
|
||||||
|
'count' => max(1, min(20, (int) ($request->get_param('count') ?? 5))),
|
||||||
|
'show_avatar' => $request->get_param('show_avatar') === null ? 1 : (int) $request->get_param('show_avatar'),
|
||||||
|
'outpost' => max(0, (int) ($request->get_param('outpost') ?? 0)),
|
||||||
|
'outer' => sanitize_text_field((string) ($request->get_param('outer') ?? '')),
|
||||||
|
];
|
||||||
|
$html = \AKSRT\Widgets\RecentCommentsWidget::render_html($instance);
|
||||||
|
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rest_user_lists(\WP_REST_Request $request) {
|
||||||
|
if (!class_exists('\AKSRT\Widgets\WidgetUserLists')) {
|
||||||
|
return $this->fail();
|
||||||
|
}
|
||||||
|
$instance = [
|
||||||
|
'number' => max(1, min(50, (int) ($request->get_param('number') ?? 8))),
|
||||||
|
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'user_registered')),
|
||||||
|
'order' => sanitize_key((string) ($request->get_param('order') ?? 'DESC')),
|
||||||
|
'include' => sanitize_text_field((string) ($request->get_param('include') ?? '')),
|
||||||
|
'exclude' => sanitize_text_field((string) ($request->get_param('exclude') ?? '')),
|
||||||
|
'hide_box' => (int) ($request->get_param('hide_box') ?? 0),
|
||||||
|
];
|
||||||
|
$html = \AKSRT\Widgets\WidgetUserLists::render_html($instance);
|
||||||
|
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rest_forum_topics(\WP_REST_Request $request) {
|
||||||
|
if (!class_exists('\AKSRT\Widgets\WidgetForumHotTopics')) {
|
||||||
|
return $this->fail();
|
||||||
|
}
|
||||||
|
$instance = [
|
||||||
|
'count' => max(1, min(20, (int) ($request->get_param('count') ?? 5))),
|
||||||
|
'period' => sanitize_key((string) ($request->get_param('period') ?? 'week')),
|
||||||
|
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'views')),
|
||||||
|
'paginate' => sanitize_key((string) ($request->get_param('paginate') ?? 'ajax')),
|
||||||
|
];
|
||||||
|
$page = max(1, (int) ($request->get_param('page') ?? 1));
|
||||||
|
return $this->payload(\AKSRT\Widgets\WidgetForumHotTopics::query_payload($instance, $page), $page);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rest_forum_terms(\WP_REST_Request $request) {
|
||||||
|
if (!class_exists('\AKSRT\Widgets\WidgetForumTopicTerms')) {
|
||||||
|
return $this->fail();
|
||||||
|
}
|
||||||
|
$instance = [
|
||||||
|
'number' => max(1, min(40, (int) ($request->get_param('number') ?? 12))),
|
||||||
|
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'count')),
|
||||||
|
'hide_empty' => $request->get_param('hide_empty') === null ? 1 : (int) $request->get_param('hide_empty'),
|
||||||
|
'include' => sanitize_text_field((string) ($request->get_param('include') ?? '')),
|
||||||
|
'style' => sanitize_key((string) ($request->get_param('style') ?? 'mini')),
|
||||||
|
];
|
||||||
|
$html = \AKSRT\Widgets\WidgetForumTopicTerms::render_html($instance);
|
||||||
|
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function fail(): \WP_REST_Response {
|
||||||
|
return new \WP_REST_Response(['success' => false, 'message' => 'unavailable'], 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function payload(array $payload, int $page): \WP_REST_Response {
|
||||||
|
return new \WP_REST_Response([
|
||||||
|
'success' => true,
|
||||||
|
'html' => (string) ($payload['html'] ?? ''),
|
||||||
|
'paginate_html' => (string) ($payload['paginate_html'] ?? ''),
|
||||||
|
'has_more' => !empty($payload['has_more']),
|
||||||
|
'page' => (int) ($payload['page'] ?? $page),
|
||||||
|
'max_pages' => (int) ($payload['max_pages'] ?? 1),
|
||||||
|
'total' => (int) ($payload['total'] ?? 0),
|
||||||
|
], 200);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
|
* Hot posts ranking (zibll hot posts + ajax).
|
||||||
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -9,151 +11,201 @@ defined('ABSPATH') || exit;
|
|||||||
|
|
||||||
class HotPostsWidget extends \WP_Widget {
|
class HotPostsWidget extends \WP_Widget {
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
parent::__construct(
|
parent::__construct(
|
||||||
'aksrt_hot_posts',
|
'aksrt_hot_posts',
|
||||||
esc_html__('AKSRT 热榜文章', 'aksrt'),
|
esc_html__('AKSRT 热榜文章', 'aksrt'),
|
||||||
[
|
[
|
||||||
'description' => esc_html__('按浏览量/评论数/点赞数排序的热门文章列表', 'aksrt'),
|
'description' => esc_html__('按浏览量/评论数/点赞数排序的热门文章列表', 'aksrt'),
|
||||||
'customize_selective_refresh' => true,
|
'customize_selective_refresh' => true,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function widget($args, $instance): void {
|
public static function build_query_args(array $instance, int $paged = 1): array {
|
||||||
echo $args['before_widget'];
|
$count = max(1, min(20, (int) ($instance['count'] ?? 5)));
|
||||||
|
$order_by = sanitize_key((string) ($instance['order_by'] ?? 'views'));
|
||||||
|
$days = max(0, (int) ($instance['days'] ?? 30));
|
||||||
|
$query_args = [
|
||||||
|
'post_type' => 'post',
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'posts_per_page' => $count,
|
||||||
|
'paged' => max(1, $paged),
|
||||||
|
'ignore_sticky_posts' => true,
|
||||||
|
];
|
||||||
|
if ($days > 0 && $days < 365) {
|
||||||
|
$query_args['date_query'] = [['after' => $days . ' days ago']];
|
||||||
|
}
|
||||||
|
switch ($order_by) {
|
||||||
|
case 'comments':
|
||||||
|
$query_args['orderby'] = 'comment_count';
|
||||||
|
$query_args['order'] = 'DESC';
|
||||||
|
break;
|
||||||
|
case 'likes':
|
||||||
|
$query_args['meta_key'] = '_aksrt_like_count';
|
||||||
|
$query_args['orderby'] = 'meta_value_num';
|
||||||
|
$query_args['order'] = 'DESC';
|
||||||
|
break;
|
||||||
|
case 'favorites':
|
||||||
|
$query_args['meta_key'] = '_aksrt_favorite_count';
|
||||||
|
$query_args['orderby'] = 'meta_value_num';
|
||||||
|
$query_args['order'] = 'DESC';
|
||||||
|
break;
|
||||||
|
case 'downloads':
|
||||||
|
$query_args['meta_key'] = '_aksrt_res_download_count';
|
||||||
|
$query_args['orderby'] = 'meta_value_num';
|
||||||
|
$query_args['order'] = 'DESC';
|
||||||
|
break;
|
||||||
|
case 'views':
|
||||||
|
default:
|
||||||
|
$query_args['meta_key'] = 'aksrt_post_views';
|
||||||
|
$query_args['orderby'] = 'meta_value_num';
|
||||||
|
$query_args['order'] = 'DESC';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $query_args;
|
||||||
|
}
|
||||||
|
|
||||||
$title = apply_filters('widget_title', $instance['title'] ?? __('热门文章', 'aksrt'), $instance, $this->id_base);
|
public static function render_items_html(\WP_Query $query, array $instance, int $start = 0): string {
|
||||||
$count = absint($instance['count'] ?? 5);
|
if (!$query->have_posts()) {
|
||||||
$order_by = $instance['order_by'] ?? 'views';
|
return '';
|
||||||
$days = absint($instance['days'] ?? 30);
|
}
|
||||||
$show_thumb = !empty($instance['show_thumb']);
|
$show_thumb = !empty($instance['show_thumb']);
|
||||||
|
ob_start();
|
||||||
|
$index = $start;
|
||||||
|
while ($query->have_posts()) {
|
||||||
|
$query->the_post();
|
||||||
|
$index++;
|
||||||
|
$rank_class = $index <= 3 ? ' rank-top' : '';
|
||||||
|
$views = (int) get_post_meta(get_the_ID(), 'aksrt_post_views', true);
|
||||||
|
?>
|
||||||
|
<div class="hot-post-item ajax-item <?php echo esc_attr($rank_class); ?>">
|
||||||
|
<span class="hot-post-item__rank"><?php echo esc_html((string) $index); ?></span>
|
||||||
|
<?php if ($show_thumb) :
|
||||||
|
$thumb = get_the_post_thumbnail_url(get_the_ID(), 'thumbnail');
|
||||||
|
?>
|
||||||
|
<a class="hot-post-item__thumb<?php echo $thumb ? '' : ' is-empty'; ?>" href="<?php the_permalink(); ?>">
|
||||||
|
<?php if ($thumb) : ?><img src="<?php echo esc_url($thumb); ?>" alt="" loading="lazy" /><?php endif; ?>
|
||||||
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
<div class="hot-post-item__info">
|
||||||
|
<a href="<?php the_permalink(); ?>" class="hot-post-item__title"><?php the_title(); ?></a>
|
||||||
|
<div class="hot-post-item__meta">
|
||||||
|
<span><i class="fas fa-eye" aria-hidden="true"></i> <?php echo esc_html(function_exists('aksrt_format_number') ? aksrt_format_number($views) : (string) $views); ?></span>
|
||||||
|
<span class="hot-post-item__time"><?php echo esc_html(human_time_diff(get_the_time('U'), current_time('timestamp')) . __('前', 'aksrt')); ?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
wp_reset_postdata();
|
||||||
|
return (string) ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
if ($title) {
|
/**
|
||||||
echo $args['before_title'] . esc_html($title) . $args['after_title'];
|
* @return array{html:string,paginate_html:string,has_more:bool,page:int,max_pages:int,total:int}
|
||||||
}
|
*/
|
||||||
|
public static function query_payload(array $instance, int $page = 1): array {
|
||||||
|
$page = max(1, $page);
|
||||||
|
$count = max(1, min(20, (int) ($instance['count'] ?? 5)));
|
||||||
|
$paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
|
||||||
|
$q = new \WP_Query(self::build_query_args($instance, $page));
|
||||||
|
$items = self::render_items_html($q, $instance, ($page - 1) * $count);
|
||||||
|
$html = $items !== '' ? '<div class="widget-hot-posts widget-hot-posts--mini">' . $items . '</div>' : '';
|
||||||
|
if ($html === '' && $page === 1) {
|
||||||
|
$html = function_exists('aksrt_get_widget_null')
|
||||||
|
? aksrt_get_widget_null(__('暂无热门文章', 'aksrt'))
|
||||||
|
: '<p class="widget-empty ajax-item">' . esc_html__('暂无热门文章', 'aksrt') . '</p>';
|
||||||
|
}
|
||||||
|
$max_pages = max(1, (int) $q->max_num_pages);
|
||||||
|
$total = (int) $q->found_posts;
|
||||||
|
$has_more = $page < $max_pages;
|
||||||
|
$paginate_html = '';
|
||||||
|
if ($paginate === 'ajax' && $has_more) {
|
||||||
|
$next = add_query_arg([
|
||||||
|
'page' => $page + 1,
|
||||||
|
'count' => $count,
|
||||||
|
'order_by' => sanitize_key((string) ($instance['order_by'] ?? 'views')),
|
||||||
|
'days' => max(0, (int) ($instance['days'] ?? 30)),
|
||||||
|
'show_thumb' => !empty($instance['show_thumb']) ? 1 : 0,
|
||||||
|
'paginate' => 'ajax',
|
||||||
|
], rest_url('aksrt/v1/widgets/hot-posts'));
|
||||||
|
$paginate_html = function_exists('aksrt_get_ajax_next_paginate')
|
||||||
|
? aksrt_get_ajax_next_paginate($total, $page, $count, $next)
|
||||||
|
: '<div class="text-center theme-pagination ajax-pag"><div class="next-page ajax-next"><a href="' . esc_url($next) . '">' . esc_html__('加载更多', 'aksrt') . '</a></div></div>';
|
||||||
|
} else {
|
||||||
|
$paginate_html = '<div class="ajax-pag hide"><div class="next-page ajax-next"><a href="#"></a></div></div>';
|
||||||
|
}
|
||||||
|
return compact('html', 'paginate_html', 'has_more', 'page', 'max_pages', 'total');
|
||||||
|
}
|
||||||
|
|
||||||
$query_args = [
|
public function widget($args, $instance): void {
|
||||||
'post_type' => 'post',
|
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
'post_status' => 'publish',
|
$title = apply_filters('widget_title', $instance['title'] ?? __('热门文章', 'aksrt'), $instance, $this->id_base);
|
||||||
'posts_per_page' => $count,
|
if ($title) {
|
||||||
'ignore_sticky_posts' => true,
|
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
'no_found_rows' => true,
|
}
|
||||||
];
|
$instance['paginate'] = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
|
||||||
|
$payload = self::query_payload($instance, 1);
|
||||||
|
$rest = rest_url('aksrt/v1/widgets/hot-posts');
|
||||||
|
echo '<div class="ajaxpager" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '">';
|
||||||
|
echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
echo '<div class="post_ajax_loader" data-aksrt-ajax-loader data-aksrt-ajax-loader-hide hidden></div>';
|
||||||
|
echo '</div>';
|
||||||
|
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
}
|
||||||
|
|
||||||
if ($days > 0 && $days < 365) {
|
public function form($instance): void {
|
||||||
$query_args['date_query'] = [['after' => $days . ' days ago']];
|
$title = $instance['title'] ?? __('热门文章', 'aksrt');
|
||||||
}
|
$count = (int) ($instance['count'] ?? 5);
|
||||||
|
$order_by = $instance['order_by'] ?? 'views';
|
||||||
|
$days = (int) ($instance['days'] ?? 30);
|
||||||
|
?>
|
||||||
|
<p>
|
||||||
|
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php esc_html_e('标题:', 'aksrt'); ?></label>
|
||||||
|
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr((string) $title); ?>">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="<?php echo esc_attr($this->get_field_id('count')); ?>"><?php esc_html_e('显示数量:', 'aksrt'); ?></label>
|
||||||
|
<input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('count')); ?>" name="<?php echo esc_attr($this->get_field_name('count')); ?>" type="number" min="1" max="20" value="<?php echo (int) $count; ?>">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="<?php echo esc_attr($this->get_field_id('order_by')); ?>"><?php esc_html_e('排序方式:', 'aksrt'); ?></label>
|
||||||
|
<select class="widefat" id="<?php echo esc_attr($this->get_field_id('order_by')); ?>" name="<?php echo esc_attr($this->get_field_name('order_by')); ?>">
|
||||||
|
<option value="views" <?php selected($order_by, 'views'); ?>><?php esc_html_e('浏览量', 'aksrt'); ?></option>
|
||||||
|
<option value="comments" <?php selected($order_by, 'comments'); ?>><?php esc_html_e('评论数', 'aksrt'); ?></option>
|
||||||
|
<option value="likes" <?php selected($order_by, 'likes'); ?>><?php esc_html_e('点赞数', 'aksrt'); ?></option>
|
||||||
|
<option value="favorites" <?php selected($order_by, 'favorites'); ?>><?php esc_html_e('收藏数', 'aksrt'); ?></option>
|
||||||
|
<option value="downloads" <?php selected($order_by, 'downloads'); ?>><?php esc_html_e('下载数', 'aksrt'); ?></option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="<?php echo esc_attr($this->get_field_id('days')); ?>"><?php esc_html_e('时间范围(天,0=不限):', 'aksrt'); ?></label>
|
||||||
|
<input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('days')); ?>" name="<?php echo esc_attr($this->get_field_name('days')); ?>" type="number" min="0" max="365" value="<?php echo (int) $days; ?>">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_thumb')); ?>" value="1" <?php checked(!empty($instance['show_thumb'])); ?>> <?php esc_html_e('显示缩略图', 'aksrt'); ?></label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label><?php esc_html_e('分页', 'aksrt'); ?>
|
||||||
|
<select name="<?php echo esc_attr($this->get_field_name('paginate')); ?>">
|
||||||
|
<option value="ajax" <?php selected(($instance['paginate'] ?? 'ajax'), 'ajax'); ?>><?php esc_html_e('AJAX', 'aksrt'); ?></option>
|
||||||
|
<option value="none" <?php selected(($instance['paginate'] ?? ''), 'none'); ?>><?php esc_html_e('无', 'aksrt'); ?></option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
switch ($order_by) {
|
public function update($new_instance, $old_instance): array {
|
||||||
case 'comments':
|
return [
|
||||||
$query_args['orderby'] = 'comment_count';
|
'title' => sanitize_text_field($new_instance['title'] ?? ''),
|
||||||
$query_args['order'] = 'DESC';
|
'count' => absint($new_instance['count'] ?? 5),
|
||||||
break;
|
'order_by' => in_array($new_instance['order_by'] ?? '', ['views', 'comments', 'likes', 'favorites', 'downloads'], true) ? $new_instance['order_by'] : 'views',
|
||||||
case 'likes':
|
'days' => absint($new_instance['days'] ?? 30),
|
||||||
$query_args['meta_key'] = '_aksrt_like_count';
|
'show_thumb' => !empty($new_instance['show_thumb']) ? 1 : 0,
|
||||||
$query_args['orderby'] = 'meta_value_num';
|
'paginate' => sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) === 'none' ? 'none' : 'ajax',
|
||||||
$query_args['order'] = 'DESC';
|
];
|
||||||
break;
|
}
|
||||||
case 'favorites':
|
|
||||||
$query_args['meta_key'] = '_aksrt_favorite_count';
|
|
||||||
$query_args['orderby'] = 'meta_value_num';
|
|
||||||
$query_args['order'] = 'DESC';
|
|
||||||
break;
|
|
||||||
case 'downloads':
|
|
||||||
$query_args['meta_key'] = '_aksrt_res_download_count';
|
|
||||||
$query_args['orderby'] = 'meta_value_num';
|
|
||||||
$query_args['order'] = 'DESC';
|
|
||||||
break;
|
|
||||||
case 'views':
|
|
||||||
default:
|
|
||||||
$query_args['meta_key'] = 'aksrt_post_views';
|
|
||||||
$query_args['orderby'] = 'meta_value_num';
|
|
||||||
$query_args['order'] = 'DESC';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = new \WP_Query($query_args);
|
|
||||||
|
|
||||||
if ($query->have_posts()) {
|
|
||||||
echo '<div class="widget-hot-posts widget-hot-posts--mini">';
|
|
||||||
$index = 0;
|
|
||||||
while ($query->have_posts()) {
|
|
||||||
$query->the_post();
|
|
||||||
$index++;
|
|
||||||
$rank_class = $index <= 3 ? ' rank-top' : '';
|
|
||||||
$views = (int) get_post_meta(get_the_ID(), 'aksrt_post_views', true);
|
|
||||||
?>
|
|
||||||
<div class="hot-post-item <?php echo esc_attr($rank_class); ?>">
|
|
||||||
<span class="hot-post-item__rank"><?php echo esc_html($index); ?></span>
|
|
||||||
<?php if ($show_thumb) :
|
|
||||||
$thumb = get_the_post_thumbnail_url(get_the_ID(), 'thumbnail');
|
|
||||||
?>
|
|
||||||
<a class="hot-post-item__thumb<?php echo $thumb ? '' : ' is-empty'; ?>" href="<?php the_permalink(); ?>">
|
|
||||||
<?php if ($thumb) : ?><img src="<?php echo esc_url($thumb); ?>" alt="" loading="lazy" /><?php endif; ?>
|
|
||||||
</a>
|
|
||||||
<?php endif; ?>
|
|
||||||
<div class="hot-post-item__info">
|
|
||||||
<a href="<?php the_permalink(); ?>" class="hot-post-item__title"><?php the_title(); ?></a>
|
|
||||||
<div class="hot-post-item__meta">
|
|
||||||
<span><i class="fas fa-eye" aria-hidden="true"></i> <?php echo esc_html(function_exists('aksrt_format_number') ? aksrt_format_number($views) : (string) $views); ?></span>
|
|
||||||
<span class="hot-post-item__time"><?php echo esc_html(human_time_diff(get_the_time('U'), current_time('timestamp')) . __('前', 'aksrt')); ?></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
echo '</div>';
|
|
||||||
wp_reset_postdata();
|
|
||||||
} else {
|
|
||||||
echo function_exists('aksrt_get_widget_null') ? aksrt_get_widget_null(__('暂无热门文章', 'aksrt')) : '<p class="widget-empty">' . esc_html__('暂无热门文章', 'aksrt') . '</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $args['after_widget'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function form($instance): void {
|
|
||||||
$title = $instance['title'] ?? __('热门文章', 'aksrt');
|
|
||||||
$count = (int) ($instance['count'] ?? 5);
|
|
||||||
$order_by = $instance['order_by'] ?? 'views';
|
|
||||||
$days = (int) ($instance['days'] ?? 30);
|
|
||||||
?>
|
|
||||||
<p>
|
|
||||||
<label for="<?php echo $this->get_field_id('title'); ?>"><?php esc_html_e('标题:', 'aksrt'); ?></label>
|
|
||||||
<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>">
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<label for="<?php echo $this->get_field_id('count'); ?>"><?php esc_html_e('显示数量:', 'aksrt'); ?></label>
|
|
||||||
<input class="tiny-text" id="<?php echo $this->get_field_id('count'); ?>" name="<?php echo $this->get_field_name('count'); ?>" type="number" min="1" max="20" value="<?php echo $count; ?>">
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<label for="<?php echo $this->get_field_id('order_by'); ?>"><?php esc_html_e('排序方式:', 'aksrt'); ?></label>
|
|
||||||
<select class="widefat" id="<?php echo $this->get_field_id('order_by'); ?>" name="<?php echo $this->get_field_name('order_by'); ?>">
|
|
||||||
<option value="views" <?php selected($order_by, 'views'); ?>><?php esc_html_e('浏览量', 'aksrt'); ?></option>
|
|
||||||
<option value="comments" <?php selected($order_by, 'comments'); ?>><?php esc_html_e('评论数', 'aksrt'); ?></option>
|
|
||||||
<option value="likes" <?php selected($order_by, 'likes'); ?>><?php esc_html_e('点赞数', 'aksrt'); ?></option>
|
|
||||||
<option value="favorites" <?php selected($order_by, 'favorites'); ?>><?php esc_html_e('收藏数', 'aksrt'); ?></option>
|
|
||||||
<option value="downloads" <?php selected($order_by, 'downloads'); ?>><?php esc_html_e('下载数', 'aksrt'); ?></option>
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<label for="<?php echo $this->get_field_id('days'); ?>"><?php esc_html_e('时间范围(天,0=不限):', 'aksrt'); ?></label>
|
|
||||||
<input class="tiny-text" id="<?php echo $this->get_field_id('days'); ?>" name="<?php echo $this->get_field_name('days'); ?>" type="number" min="0" max="365" value="<?php echo $days; ?>">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_thumb')); ?>" value="1" <?php checked(!empty($instance['show_thumb'])); ?>> <?php esc_html_e('显示缩略图', 'aksrt'); ?></label>
|
|
||||||
</p>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update($new_instance, $old_instance): array {
|
|
||||||
return [
|
|
||||||
'title' => sanitize_text_field($new_instance['title'] ?? ''),
|
|
||||||
'count' => absint($new_instance['count'] ?? 5),
|
|
||||||
'order_by' => in_array($new_instance['order_by'] ?? '', ['views', 'comments', 'likes', 'favorites', 'downloads'], true) ? $new_instance['order_by'] : 'views',
|
|
||||||
'days' => absint($new_instance['days'] ?? 30),
|
|
||||||
'show_thumb' => !empty($new_instance['show_thumb']) ? 1 : 0,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Recent comments mini list (zibll widget_ui_new_comment lite).
|
* Recent comments mini list (zibll widget_ui_new_comment + remote HTML).
|
||||||
*
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
*/
|
*/
|
||||||
@@ -17,18 +17,11 @@ class RecentCommentsWidget extends \WP_Widget {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function widget($args, $instance): void {
|
public static function render_html(array $instance): string {
|
||||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
||||||
$title = apply_filters('widget_title', (string) ($instance['title'] ?? __('最新评论', 'aksrt')), $instance, $this->id_base);
|
|
||||||
$count = max(1, min(20, (int) ($instance['count'] ?? $instance['limit'] ?? 5)));
|
$count = max(1, min(20, (int) ($instance['count'] ?? $instance['limit'] ?? 5)));
|
||||||
$show_avatar = !isset($instance['show_avatar']) || !empty($instance['show_avatar']);
|
$show_avatar = !isset($instance['show_avatar']) || !empty($instance['show_avatar']);
|
||||||
$outpost = max(0, (int) ($instance['outpost'] ?? 0));
|
$outpost = max(0, (int) ($instance['outpost'] ?? 0));
|
||||||
$outer = sanitize_text_field((string) ($instance['outer'] ?? ''));
|
$outer = sanitize_text_field((string) ($instance['outer'] ?? ''));
|
||||||
|
|
||||||
if ($title !== '') {
|
|
||||||
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = [
|
$query = [
|
||||||
'number' => $count,
|
'number' => $count,
|
||||||
'status' => 'approve',
|
'status' => 'approve',
|
||||||
@@ -37,10 +30,6 @@ class RecentCommentsWidget extends \WP_Widget {
|
|||||||
if ($outpost > 0) {
|
if ($outpost > 0) {
|
||||||
$query['post__not_in'] = [$outpost];
|
$query['post__not_in'] = [$outpost];
|
||||||
}
|
}
|
||||||
if ($outer !== '') {
|
|
||||||
// Exclude comments containing outer keywords (comma separated).
|
|
||||||
// Implemented post-filter below.
|
|
||||||
}
|
|
||||||
$comments = get_comments($query);
|
$comments = get_comments($query);
|
||||||
if ($outer !== '' && $comments) {
|
if ($outer !== '' && $comments) {
|
||||||
$keys = array_filter(array_map('trim', preg_split('/[,,]/', $outer) ?: []));
|
$keys = array_filter(array_map('trim', preg_split('/[,,]/', $outer) ?: []));
|
||||||
@@ -56,32 +45,40 @@ class RecentCommentsWidget extends \WP_Widget {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!$comments) {
|
||||||
if ($comments) {
|
return '<p class="widget-empty ajax-item">' . esc_html__('暂无评论', 'aksrt') . '</p>';
|
||||||
echo '<div class="widget-recent-comments comment-mini-lists">';
|
|
||||||
foreach ($comments as $comment) {
|
|
||||||
$post = get_post($comment->comment_post_ID);
|
|
||||||
if (!$post) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
echo '<div class="widget-recent-comments__item">';
|
|
||||||
if ($show_avatar) {
|
|
||||||
echo '<div class="widget-recent-comments__avatar">' . get_avatar($comment, 32) . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
||||||
}
|
|
||||||
echo '<div class="widget-recent-comments__body">';
|
|
||||||
echo '<div class="widget-recent-comments__meta">';
|
|
||||||
echo '<strong class="widget-recent-comments__author">' . esc_html($comment->comment_author) . '</strong>';
|
|
||||||
echo '<span class="widget-recent-comments__time">' . esc_html(human_time_diff(strtotime($comment->comment_date), current_time('timestamp'))) . '</span>';
|
|
||||||
echo '</div>';
|
|
||||||
echo '<p class="widget-recent-comments__text"><a href="' . esc_url(get_comment_link($comment)) . '">' . esc_html(wp_trim_words($comment->comment_content, 15, '...')) . '</a></p>';
|
|
||||||
echo '<div class="widget-recent-comments__post muted-2-color em09"><a href="' . esc_url(get_permalink($post)) . '">' . esc_html(get_the_title($post)) . '</a></div>';
|
|
||||||
echo '</div></div>';
|
|
||||||
}
|
|
||||||
echo '</div>';
|
|
||||||
} else {
|
|
||||||
echo '<p class="widget-empty">' . esc_html__('暂无评论', 'aksrt') . '</p>';
|
|
||||||
}
|
}
|
||||||
|
ob_start();
|
||||||
|
echo '<div class="widget-recent-comments comment-mini-lists ajax-item">';
|
||||||
|
foreach ($comments as $comment) {
|
||||||
|
$post = get_post($comment->comment_post_ID);
|
||||||
|
if (!$post) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
echo '<div class="widget-recent-comments__item">';
|
||||||
|
if ($show_avatar) {
|
||||||
|
echo '<div class="widget-recent-comments__avatar">' . get_avatar($comment, 32) . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
}
|
||||||
|
echo '<div class="widget-recent-comments__body">';
|
||||||
|
echo '<div class="widget-recent-comments__meta">';
|
||||||
|
echo '<strong class="widget-recent-comments__author">' . esc_html($comment->comment_author) . '</strong>';
|
||||||
|
echo '<span class="widget-recent-comments__time">' . esc_html(human_time_diff(strtotime($comment->comment_date), current_time('timestamp'))) . '</span>';
|
||||||
|
echo '</div>';
|
||||||
|
echo '<p class="widget-recent-comments__text"><a href="' . esc_url(get_comment_link($comment)) . '">' . esc_html(wp_trim_words($comment->comment_content, 15, '...')) . '</a></p>';
|
||||||
|
echo '<div class="widget-recent-comments__post muted-2-color em09"><a href="' . esc_url(get_permalink($post)) . '">' . esc_html(get_the_title($post)) . '</a></div>';
|
||||||
|
echo '</div></div>';
|
||||||
|
}
|
||||||
|
echo '</div>';
|
||||||
|
return (string) ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function widget($args, $instance): void {
|
||||||
|
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
$title = apply_filters('widget_title', (string) ($instance['title'] ?? __('最新评论', 'aksrt')), $instance, $this->id_base);
|
||||||
|
if ($title !== '') {
|
||||||
|
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
}
|
||||||
|
echo self::render_html($instance); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,6 +94,9 @@ class RecentCommentsWidget extends \WP_Widget {
|
|||||||
<input class="tiny-text" type="number" min="1" max="20" name="<?php echo esc_attr($this->get_field_name('count')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['count'] ?? 5))); ?>">
|
<input class="tiny-text" type="number" min="1" max="20" name="<?php echo esc_attr($this->get_field_name('count')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['count'] ?? 5))); ?>">
|
||||||
</label>
|
</label>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_avatar')); ?>" value="1" <?php checked(!isset($instance['show_avatar']) || !empty($instance['show_avatar'])); ?>> <?php esc_html_e('显示头像', 'aksrt'); ?></label>
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label><?php esc_html_e('排除文章 ID', 'aksrt'); ?>
|
<label><?php esc_html_e('排除文章 ID', 'aksrt'); ?>
|
||||||
<input class="tiny-text" type="number" min="0" name="<?php echo esc_attr($this->get_field_name('outpost')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['outpost'] ?? 0))); ?>">
|
<input class="tiny-text" type="number" min="0" name="<?php echo esc_attr($this->get_field_name('outpost')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['outpost'] ?? 0))); ?>">
|
||||||
@@ -107,9 +107,6 @@ class RecentCommentsWidget extends \WP_Widget {
|
|||||||
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('outer')); ?>" value="<?php echo esc_attr((string) ($instance['outer'] ?? '')); ?>">
|
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('outer')); ?>" value="<?php echo esc_attr((string) ($instance['outer'] ?? '')); ?>">
|
||||||
</label>
|
</label>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
|
||||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_avatar')); ?>" value="1" <?php checked(!isset($instance['show_avatar']) || !empty($instance['show_avatar'])); ?>> <?php esc_html_e('显示头像', 'aksrt'); ?></label>
|
|
||||||
</p>
|
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,9 +114,9 @@ class RecentCommentsWidget extends \WP_Widget {
|
|||||||
return [
|
return [
|
||||||
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
|
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
|
||||||
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 5))),
|
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 5))),
|
||||||
|
'show_avatar' => !empty($new_instance['show_avatar']) ? 1 : 0,
|
||||||
'outpost' => max(0, (int) ($new_instance['outpost'] ?? 0)),
|
'outpost' => max(0, (int) ($new_instance['outpost'] ?? 0)),
|
||||||
'outer' => sanitize_text_field((string) ($new_instance['outer'] ?? '')),
|
'outer' => sanitize_text_field((string) ($new_instance['outer'] ?? '')),
|
||||||
'show_avatar' => !empty($new_instance['show_avatar']) ? 1 : 0,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
|
* Forum hot / recent topic widgets with shared AJAX payload.
|
||||||
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -7,105 +9,157 @@ namespace AKSRT\Widgets;
|
|||||||
|
|
||||||
defined('ABSPATH') || exit;
|
defined('ABSPATH') || exit;
|
||||||
|
|
||||||
/**
|
|
||||||
* Forum-specific widgets.
|
|
||||||
*
|
|
||||||
* @package AKSRT
|
|
||||||
*/
|
|
||||||
|
|
||||||
defined('ABSPATH') || exit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forum Hot Topics Widget
|
|
||||||
*/
|
|
||||||
class WidgetForumHotTopics extends \WP_Widget {
|
class WidgetForumHotTopics extends \WP_Widget {
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
parent::__construct(
|
parent::__construct(
|
||||||
'aksrt_forum_hot_topics',
|
'aksrt_forum_hot_topics',
|
||||||
__('论坛 - 热门话题', 'aksrt'),
|
__('论坛 - 热门话题', 'aksrt'),
|
||||||
['description' => __('显示论坛热门话题列表。', 'aksrt')]
|
['description' => __('显示论坛热门话题列表。', 'aksrt')]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function widget($args, $instance): void {
|
public static function build_query_args(array $instance, int $paged = 1): array {
|
||||||
$title = !empty($instance['title']) ? $instance['title'] : __('热门话题', 'aksrt');
|
$count = max(1, min(20, (int) ($instance['count'] ?? 5)));
|
||||||
$count = !empty($instance['count']) ? max(1, min(20, (int) $instance['count'])) : 5;
|
$period = sanitize_key((string) ($instance['period'] ?? 'week'));
|
||||||
$period = !empty($instance['period']) ? sanitize_key($instance['period']) : 'week';
|
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'views'));
|
||||||
|
$date_query = [];
|
||||||
|
if ($period === 'week') {
|
||||||
|
$date_query = [['after' => '7 days ago']];
|
||||||
|
} elseif ($period === 'month') {
|
||||||
|
$date_query = [['after' => '30 days ago']];
|
||||||
|
}
|
||||||
|
$query = [
|
||||||
|
'post_type' => 'aksrt_forum_topic',
|
||||||
|
'posts_per_page' => $count,
|
||||||
|
'paged' => max(1, $paged),
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'date_query' => $date_query,
|
||||||
|
];
|
||||||
|
if ($orderby === 'comments') {
|
||||||
|
$query['orderby'] = 'comment_count';
|
||||||
|
$query['order'] = 'DESC';
|
||||||
|
} elseif ($orderby === 'date') {
|
||||||
|
$query['orderby'] = 'date';
|
||||||
|
$query['order'] = 'DESC';
|
||||||
|
} else {
|
||||||
|
$query['meta_key'] = '_aksrt_views';
|
||||||
|
$query['orderby'] = 'meta_value_num';
|
||||||
|
$query['order'] = 'DESC';
|
||||||
|
}
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
echo $args['before_widget'];
|
public static function render_items_html(\WP_Query $query, int $start = 0): string {
|
||||||
echo $args['before_title'] . esc_html($title) . $args['after_title'];
|
if (!$query->have_posts()) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
ob_start();
|
||||||
|
$i = $start;
|
||||||
|
while ($query->have_posts()) {
|
||||||
|
$query->the_post();
|
||||||
|
$i++;
|
||||||
|
$views = (int) get_post_meta(get_the_ID(), '_aksrt_views', true);
|
||||||
|
echo '<li class="aksrt-forum-widget__item ajax-item">';
|
||||||
|
echo '<span class="aksrt-forum-widget__rank">' . esc_html((string) $i) . '</span>';
|
||||||
|
echo '<a href="' . esc_url(get_permalink()) . '" class="aksrt-forum-widget__link">';
|
||||||
|
echo esc_html(get_the_title());
|
||||||
|
echo '</a>';
|
||||||
|
echo '<span class="aksrt-forum-widget__views"><i class="fas fa-eye"></i> ' . esc_html((string) $views) . '</span>';
|
||||||
|
echo '</li>';
|
||||||
|
}
|
||||||
|
wp_reset_postdata();
|
||||||
|
return (string) ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
$date_query = [];
|
/**
|
||||||
if ($period === 'week') {
|
* @return array{html:string,paginate_html:string,has_more:bool,page:int,max_pages:int,total:int}
|
||||||
$date_query = [['after' => '7 days ago']];
|
*/
|
||||||
} elseif ($period === 'month') {
|
public static function query_payload(array $instance, int $page = 1): array {
|
||||||
$date_query = [['after' => '30 days ago']];
|
$page = max(1, $page);
|
||||||
}
|
$count = max(1, min(20, (int) ($instance['count'] ?? 5)));
|
||||||
|
$paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
|
||||||
|
$q = new \WP_Query(self::build_query_args($instance, $page));
|
||||||
|
$items = self::render_items_html($q, ($page - 1) * $count);
|
||||||
|
$html = $items !== '' ? '<ul class="aksrt-forum-widget__list">' . $items . '</ul>' : '';
|
||||||
|
if ($html === '' && $page === 1) {
|
||||||
|
$html = '<p class="aksrt-forum-widget__empty ajax-item">' . esc_html__('暂无话题', 'aksrt') . '</p>';
|
||||||
|
}
|
||||||
|
$max_pages = max(1, (int) $q->max_num_pages);
|
||||||
|
$total = (int) $q->found_posts;
|
||||||
|
$has_more = $page < $max_pages;
|
||||||
|
$paginate_html = '';
|
||||||
|
if ($paginate === 'ajax' && $has_more) {
|
||||||
|
$next = add_query_arg([
|
||||||
|
'page' => $page + 1,
|
||||||
|
'count' => $count,
|
||||||
|
'period' => sanitize_key((string) ($instance['period'] ?? 'week')),
|
||||||
|
'orderby' => sanitize_key((string) ($instance['orderby'] ?? 'views')),
|
||||||
|
'paginate' => 'ajax',
|
||||||
|
], rest_url('aksrt/v1/widgets/forum-topics'));
|
||||||
|
$paginate_html = function_exists('aksrt_get_ajax_next_paginate')
|
||||||
|
? aksrt_get_ajax_next_paginate($total, $page, $count, $next)
|
||||||
|
: '<div class="text-center theme-pagination ajax-pag"><div class="next-page ajax-next"><a href="' . esc_url($next) . '">' . esc_html__('加载更多', 'aksrt') . '</a></div></div>';
|
||||||
|
} else {
|
||||||
|
$paginate_html = '<div class="ajax-pag hide"><div class="next-page ajax-next"><a href="#"></a></div></div>';
|
||||||
|
}
|
||||||
|
return compact('html', 'paginate_html', 'has_more', 'page', 'max_pages', 'total');
|
||||||
|
}
|
||||||
|
|
||||||
$query = new \WP_Query([
|
public function widget($args, $instance): void {
|
||||||
'post_type' => 'aksrt_forum_topic',
|
$title = !empty($instance['title']) ? $instance['title'] : __('热门话题', 'aksrt');
|
||||||
'posts_per_page' => $count,
|
$instance['paginate'] = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
|
||||||
'post_status' => 'publish',
|
$payload = self::query_payload($instance, 1);
|
||||||
'meta_key' => '_aksrt_views',
|
|
||||||
'orderby' => 'meta_value_num',
|
|
||||||
'order' => 'DESC',
|
|
||||||
'date_query' => $date_query,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($query->have_posts()) {
|
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
echo '<ul class="aksrt-forum-widget__list">';
|
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
$i = 0;
|
$rest = rest_url('aksrt/v1/widgets/forum-topics');
|
||||||
while ($query->have_posts()) {
|
echo '<div class="ajaxpager" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '">';
|
||||||
$query->the_post();
|
echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
$i++;
|
echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
$views = (int) get_post_meta(get_the_ID(), '_aksrt_views', true);
|
echo '<div class="post_ajax_loader" data-aksrt-ajax-loader data-aksrt-ajax-loader-hide hidden></div>';
|
||||||
echo '<li class="aksrt-forum-widget__item">';
|
echo '</div>';
|
||||||
echo '<span class="aksrt-forum-widget__rank">' . $i . '</span>';
|
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
echo '<a href="' . esc_url(get_permalink()) . '" class="aksrt-forum-widget__link">';
|
}
|
||||||
echo esc_html(get_the_title());
|
|
||||||
echo '</a>';
|
|
||||||
echo '<span class="aksrt-forum-widget__views"><i class="fas fa-eye"></i> ' . $views . '</span>';
|
|
||||||
echo '</li>';
|
|
||||||
}
|
|
||||||
echo '</ul>';
|
|
||||||
wp_reset_postdata();
|
|
||||||
} else {
|
|
||||||
echo '<p class="aksrt-forum-widget__empty">' . esc_html__('暂无话题', 'aksrt') . '</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $args['after_widget'];
|
public function form($instance): void {
|
||||||
}
|
$title = !empty($instance['title']) ? $instance['title'] : __('热门话题', 'aksrt');
|
||||||
|
$count = !empty($instance['count']) ? (int) $instance['count'] : 5;
|
||||||
|
$period = !empty($instance['period']) ? $instance['period'] : 'week';
|
||||||
|
?>
|
||||||
|
<p>
|
||||||
|
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php esc_html_e('标题:', 'aksrt'); ?></label>
|
||||||
|
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr($title); ?>">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="<?php echo esc_attr($this->get_field_id('count')); ?>"><?php esc_html_e('数量:', 'aksrt'); ?></label>
|
||||||
|
<input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('count')); ?>" name="<?php echo esc_attr($this->get_field_name('count')); ?>" type="number" value="<?php echo esc_attr((string) $count); ?>" min="1" max="20">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="<?php echo esc_attr($this->get_field_id('period')); ?>"><?php esc_html_e('时间范围:', 'aksrt'); ?></label>
|
||||||
|
<select id="<?php echo esc_attr($this->get_field_id('period')); ?>" name="<?php echo esc_attr($this->get_field_name('period')); ?>">
|
||||||
|
<option value="all" <?php selected($period, 'all'); ?>><?php esc_html_e('全部', 'aksrt'); ?></option>
|
||||||
|
<option value="week" <?php selected($period, 'week'); ?>><?php esc_html_e('最近一周', 'aksrt'); ?></option>
|
||||||
|
<option value="month" <?php selected($period, 'month'); ?>><?php esc_html_e('最近一月', 'aksrt'); ?></option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label><?php esc_html_e('分页', 'aksrt'); ?>
|
||||||
|
<select name="<?php echo esc_attr($this->get_field_name('paginate')); ?>">
|
||||||
|
<option value="ajax" <?php selected(($instance['paginate'] ?? 'ajax'), 'ajax'); ?>><?php esc_html_e('AJAX', 'aksrt'); ?></option>
|
||||||
|
<option value="none" <?php selected(($instance['paginate'] ?? ''), 'none'); ?>><?php esc_html_e('无', 'aksrt'); ?></option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
public function form($instance): void {
|
public function update($new_instance, $old_instance): array {
|
||||||
$title = !empty($instance['title']) ? $instance['title'] : __('热门话题', 'aksrt');
|
return [
|
||||||
$count = !empty($instance['count']) ? (int) $instance['count'] : 5;
|
'title' => sanitize_text_field($new_instance['title'] ?? ''),
|
||||||
$period = !empty($instance['period']) ? $instance['period'] : 'week';
|
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 5))),
|
||||||
?>
|
'period' => in_array($new_instance['period'] ?? '', ['all', 'week', 'month'], true) ? $new_instance['period'] : 'week',
|
||||||
<p>
|
'paginate' => sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) === 'none' ? 'none' : 'ajax',
|
||||||
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php esc_html_e('标题:', 'aksrt'); ?></label>
|
];
|
||||||
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr($title); ?>">
|
}
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<label for="<?php echo esc_attr($this->get_field_id('count')); ?>"><?php esc_html_e('数量:', 'aksrt'); ?></label>
|
|
||||||
<input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('count')); ?>" name="<?php echo esc_attr($this->get_field_name('count')); ?>" type="number" value="<?php echo esc_attr($count); ?>" min="1" max="20">
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<label for="<?php echo esc_attr($this->get_field_id('period')); ?>"><?php esc_html_e('时间范围:', 'aksrt'); ?></label>
|
|
||||||
<select id="<?php echo esc_attr($this->get_field_id('period')); ?>" name="<?php echo esc_attr($this->get_field_name('period')); ?>">
|
|
||||||
<option value="all" <?php selected($period, 'all'); ?>><?php esc_html_e('全部', 'aksrt'); ?></option>
|
|
||||||
<option value="week" <?php selected($period, 'week'); ?>><?php esc_html_e('最近一周', 'aksrt'); ?></option>
|
|
||||||
<option value="month" <?php selected($period, 'month'); ?>><?php esc_html_e('最近一月', 'aksrt'); ?></option>
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update($new_instance, $old_instance): array {
|
|
||||||
$instance = [];
|
|
||||||
$instance['title'] = sanitize_text_field($new_instance['title'] ?? '');
|
|
||||||
$instance['count'] = max(1, min(20, (int) ($new_instance['count'] ?? 5)));
|
|
||||||
$instance['period'] = in_array($new_instance['period'] ?? '', ['all', 'week', 'month'], true) ? $new_instance['period'] : 'week';
|
|
||||||
return $instance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
|
* Forum recent topics — thin wrapper over hot-topics payload with date order.
|
||||||
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -7,74 +9,62 @@ namespace AKSRT\Widgets;
|
|||||||
|
|
||||||
defined('ABSPATH') || exit;
|
defined('ABSPATH') || exit;
|
||||||
|
|
||||||
/**
|
|
||||||
* Forum Recent Topics Widget
|
|
||||||
*/
|
|
||||||
class WidgetForumRecentTopics extends \WP_Widget {
|
class WidgetForumRecentTopics extends \WP_Widget {
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
parent::__construct(
|
parent::__construct(
|
||||||
'aksrt_forum_recent_topics',
|
'aksrt_forum_recent_topics',
|
||||||
__('论坛 - 最新话题', 'aksrt'),
|
__('论坛 - 最新话题', 'aksrt'),
|
||||||
['description' => __('显示论坛最新话题列表。', 'aksrt')]
|
['description' => __('显示论坛最新话题列表。', 'aksrt')]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function widget($args, $instance): void {
|
public function widget($args, $instance): void {
|
||||||
$title = !empty($instance['title']) ? $instance['title'] : __('最新话题', 'aksrt');
|
$title = !empty($instance['title']) ? $instance['title'] : __('最新话题', 'aksrt');
|
||||||
$count = !empty($instance['count']) ? max(1, min(20, (int) $instance['count'])) : 5;
|
$instance['orderby'] = 'date';
|
||||||
|
$instance['period'] = 'all';
|
||||||
|
$instance['paginate'] = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
|
||||||
|
$payload = WidgetForumHotTopics::query_payload($instance, 1);
|
||||||
|
|
||||||
echo $args['before_widget'];
|
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
echo $args['before_title'] . esc_html($title) . $args['after_title'];
|
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
$rest = rest_url('aksrt/v1/widgets/forum-topics');
|
||||||
|
echo '<div class="ajaxpager" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '">';
|
||||||
|
echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
echo '<div class="post_ajax_loader" data-aksrt-ajax-loader data-aksrt-ajax-loader-hide hidden></div>';
|
||||||
|
echo '</div>';
|
||||||
|
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
}
|
||||||
|
|
||||||
$query = new \WP_Query([
|
public function form($instance): void {
|
||||||
'post_type' => 'aksrt_forum_topic',
|
$title = !empty($instance['title']) ? $instance['title'] : __('最新话题', 'aksrt');
|
||||||
'posts_per_page' => $count,
|
$count = !empty($instance['count']) ? (int) $instance['count'] : 5;
|
||||||
'post_status' => 'publish',
|
?>
|
||||||
'orderby' => 'date',
|
<p>
|
||||||
'order' => 'DESC',
|
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php esc_html_e('标题:', 'aksrt'); ?></label>
|
||||||
]);
|
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr($title); ?>">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="<?php echo esc_attr($this->get_field_id('count')); ?>"><?php esc_html_e('数量:', 'aksrt'); ?></label>
|
||||||
|
<input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('count')); ?>" name="<?php echo esc_attr($this->get_field_name('count')); ?>" type="number" value="<?php echo esc_attr((string) $count); ?>" min="1" max="20">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label><?php esc_html_e('分页', 'aksrt'); ?>
|
||||||
|
<select name="<?php echo esc_attr($this->get_field_name('paginate')); ?>">
|
||||||
|
<option value="ajax" <?php selected(($instance['paginate'] ?? 'ajax'), 'ajax'); ?>><?php esc_html_e('AJAX', 'aksrt'); ?></option>
|
||||||
|
<option value="none" <?php selected(($instance['paginate'] ?? ''), 'none'); ?>><?php esc_html_e('无', 'aksrt'); ?></option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
if ($query->have_posts()) {
|
public function update($new_instance, $old_instance): array {
|
||||||
echo '<ul class="aksrt-forum-widget__list">';
|
return [
|
||||||
while ($query->have_posts()) {
|
'title' => sanitize_text_field($new_instance['title'] ?? ''),
|
||||||
$query->the_post();
|
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 5))),
|
||||||
$author = get_the_author_meta('display_name');
|
'paginate' => sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) === 'none' ? 'none' : 'ajax',
|
||||||
echo '<li class="aksrt-forum-widget__item">';
|
];
|
||||||
echo '<a href="' . esc_url(get_permalink()) . '" class="aksrt-forum-widget__link">';
|
}
|
||||||
echo esc_html(get_the_title());
|
|
||||||
echo '</a>';
|
|
||||||
echo '<span class="aksrt-forum-widget__author">' . esc_html($author) . '</span>';
|
|
||||||
echo '</li>';
|
|
||||||
}
|
|
||||||
echo '</ul>';
|
|
||||||
wp_reset_postdata();
|
|
||||||
} else {
|
|
||||||
echo '<p class="aksrt-forum-widget__empty">' . esc_html__('暂无话题', 'aksrt') . '</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $args['after_widget'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function form($instance): void {
|
|
||||||
$title = !empty($instance['title']) ? $instance['title'] : __('最新话题', 'aksrt');
|
|
||||||
$count = !empty($instance['count']) ? (int) $instance['count'] : 5;
|
|
||||||
?>
|
|
||||||
<p>
|
|
||||||
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php esc_html_e('标题:', 'aksrt'); ?></label>
|
|
||||||
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr($title); ?>">
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<label for="<?php echo esc_attr($this->get_field_id('count')); ?>"><?php esc_html_e('数量:', 'aksrt'); ?></label>
|
|
||||||
<input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('count')); ?>" name="<?php echo esc_attr($this->get_field_name('count')); ?>" type="number" value="<?php echo esc_attr($count); ?>" min="1" max="20">
|
|
||||||
</p>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update($new_instance, $old_instance): array {
|
|
||||||
$instance = [];
|
|
||||||
$instance['title'] = sanitize_text_field($new_instance['title'] ?? '');
|
|
||||||
$instance['count'] = max(1, min(20, (int) ($new_instance['count'] ?? 5)));
|
|
||||||
return $instance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Forum topic tags / topic taxonomy list (zibll zib_bbs_widget_ui_topic_lists).
|
* Forum topic tags list (zibll topic_lists + remote HTML).
|
||||||
*
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
*/
|
*/
|
||||||
@@ -22,52 +22,60 @@ class WidgetForumTopicTerms extends \WP_Widget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function widget($args, $instance): void {
|
/** @return array<int,int> */
|
||||||
|
public static function parse_ids_static(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 static function render_html(array $instance): string {
|
||||||
$tax = taxonomy_exists('aksrt_forum_tag') ? 'aksrt_forum_tag' : (taxonomy_exists('aksrt_forum_topic_cat') ? 'aksrt_forum_topic_cat' : '');
|
$tax = taxonomy_exists('aksrt_forum_tag') ? 'aksrt_forum_tag' : (taxonomy_exists('aksrt_forum_topic_cat') ? 'aksrt_forum_topic_cat' : '');
|
||||||
if ($tax === '') {
|
if ($tax === '') {
|
||||||
return;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$number = max(1, min(40, (int) ($instance['number'] ?? 12)));
|
$number = max(1, min(40, (int) ($instance['number'] ?? 12)));
|
||||||
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'count'));
|
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'count'));
|
||||||
$hide_empty = !isset($instance['hide_empty']) || !empty($instance['hide_empty']);
|
$hide_empty = !isset($instance['hide_empty']) || !empty($instance['hide_empty']);
|
||||||
$include = $this->parse_ids((string) ($instance['include'] ?? ''));
|
$include = self::parse_ids_static((string) ($instance['include'] ?? ''));
|
||||||
$style = sanitize_key((string) ($instance['style'] ?? 'mini'));
|
$style = sanitize_key((string) ($instance['style'] ?? 'mini'));
|
||||||
|
|
||||||
$term_args = [
|
$term_args = [
|
||||||
'taxonomy' => $tax,
|
'taxonomy' => $tax,
|
||||||
'number' => $number,
|
'number' => $number,
|
||||||
'hide_empty' => $hide_empty,
|
'hide_empty' => (bool) $hide_empty,
|
||||||
];
|
];
|
||||||
if ($include) {
|
if ($include) {
|
||||||
$term_args['include'] = $include;
|
$term_args['include'] = $include;
|
||||||
$term_args['orderby'] = 'include';
|
$term_args['orderby'] = 'include';
|
||||||
|
} elseif ($orderby === 'name') {
|
||||||
|
$term_args['orderby'] = 'name';
|
||||||
|
$term_args['order'] = 'ASC';
|
||||||
|
} elseif ($orderby === 'views') {
|
||||||
|
$term_args['meta_key'] = '_aksrt_views';
|
||||||
|
$term_args['orderby'] = 'meta_value_num';
|
||||||
|
$term_args['order'] = 'DESC';
|
||||||
} else {
|
} else {
|
||||||
if ($orderby === 'name') {
|
$term_args['orderby'] = 'count';
|
||||||
$term_args['orderby'] = 'name';
|
$term_args['order'] = 'DESC';
|
||||||
$term_args['order'] = 'ASC';
|
|
||||||
} elseif ($orderby === 'views') {
|
|
||||||
$term_args['meta_key'] = '_aksrt_views';
|
|
||||||
$term_args['orderby'] = 'meta_value_num';
|
|
||||||
$term_args['order'] = 'DESC';
|
|
||||||
} else {
|
|
||||||
$term_args['orderby'] = 'count';
|
|
||||||
$term_args['order'] = 'DESC';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$terms = get_terms($term_args);
|
$terms = get_terms($term_args);
|
||||||
if (is_wp_error($terms) || !$terms) {
|
if (is_wp_error($terms) || !$terms) {
|
||||||
return;
|
return function_exists('aksrt_get_ajax_null')
|
||||||
|
? aksrt_get_ajax_null(__('暂无话题', 'aksrt'))
|
||||||
|
: '<p class="widget-empty ajax-item">' . esc_html__('暂无话题', 'aksrt') . '</p>';
|
||||||
}
|
}
|
||||||
|
ob_start();
|
||||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
$list_cls = $style === 'card' ? 'aksrt-ftag-list is-card ajax-item' : 'aksrt-ftag-list is-mini ajax-item';
|
||||||
$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
|
|
||||||
}
|
|
||||||
|
|
||||||
$list_cls = $style === 'card' ? 'aksrt-ftag-list is-card' : 'aksrt-ftag-list is-mini';
|
|
||||||
echo '<div class="' . esc_attr($list_cls) . '">';
|
echo '<div class="' . esc_attr($list_cls) . '">';
|
||||||
foreach ($terms as $term) {
|
foreach ($terms as $term) {
|
||||||
$link = get_term_link($term);
|
$link = get_term_link($term);
|
||||||
@@ -84,23 +92,28 @@ class WidgetForumTopicTerms extends \WP_Widget {
|
|||||||
echo '</a>';
|
echo '</a>';
|
||||||
}
|
}
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
|
return (string) ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function widget($args, $instance): void {
|
||||||
|
$html = self::render_html($instance);
|
||||||
|
if ($html === '') {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
// IAS-style wrap for remote refresh.
|
||||||
|
echo '<div class="zib-widget padding-6 ajaxpager" data-aksrt-ajaxpager>';
|
||||||
|
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
echo '</div>';
|
||||||
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return array<int,int> */
|
|
||||||
private function parse_ids(string $raw): array {
|
private function parse_ids(string $raw): array {
|
||||||
if ($raw === '') {
|
return self::parse_ids_static($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 {
|
public function form($instance): void {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Horizontal one-line posts scroller (zibll widget_ui_oneline_posts lite).
|
* Horizontal one-line posts scroller (zibll oneline + remote HTML).
|
||||||
*
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
*/
|
*/
|
||||||
@@ -22,16 +22,11 @@ class WidgetOnelinePosts extends \WP_Widget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function widget($args, $instance): void {
|
public static function build_query_args(array $instance): array {
|
||||||
$count = max(1, min(20, (int) ($instance['count'] ?? 8)));
|
$count = max(1, min(20, (int) ($instance['count'] ?? 8)));
|
||||||
$style = sanitize_key((string) ($instance['style'] ?? 'card'));
|
|
||||||
if (!in_array($style, ['card', 'mini', 'list'], true)) {
|
|
||||||
$style = 'card';
|
|
||||||
}
|
|
||||||
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'date'));
|
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'date'));
|
||||||
$cat = (int) ($instance['cat'] ?? 0);
|
$cat = (int) ($instance['cat'] ?? 0);
|
||||||
$limit_day = max(0, (int) ($instance['limit_day'] ?? 0));
|
$limit_day = max(0, (int) ($instance['limit_day'] ?? 0));
|
||||||
|
|
||||||
$query = [
|
$query = [
|
||||||
'post_type' => 'post',
|
'post_type' => 'post',
|
||||||
'post_status' => 'publish',
|
'post_status' => 'publish',
|
||||||
@@ -62,20 +57,23 @@ class WidgetOnelinePosts extends \WP_Widget {
|
|||||||
$query['orderby'] = 'date';
|
$query['orderby'] = 'date';
|
||||||
$query['order'] = 'DESC';
|
$query['order'] = 'DESC';
|
||||||
}
|
}
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
$q = new \WP_Query($query);
|
public static function render_html(array $instance): string {
|
||||||
|
$style = sanitize_key((string) ($instance['style'] ?? 'card'));
|
||||||
|
if (!in_array($style, ['card', 'mini', 'list'], true)) {
|
||||||
|
$style = 'card';
|
||||||
|
}
|
||||||
|
$q = new \WP_Query(self::build_query_args($instance));
|
||||||
if (!$q->have_posts()) {
|
if (!$q->have_posts()) {
|
||||||
wp_reset_postdata();
|
wp_reset_postdata();
|
||||||
return;
|
return function_exists('aksrt_get_ajax_null')
|
||||||
|
? aksrt_get_ajax_null(__('暂无文章', 'aksrt'))
|
||||||
|
: '<p class="widget-empty ajax-item">' . esc_html__('暂无文章', 'aksrt') . '</p>';
|
||||||
}
|
}
|
||||||
|
ob_start();
|
||||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
echo '<div class="aksrt-oneline style-' . esc_attr($style) . ' ajax-item"><div class="aksrt-oneline__track">';
|
||||||
$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 '<div class="aksrt-oneline style-' . esc_attr($style) . '"><div class="aksrt-oneline__track">';
|
|
||||||
while ($q->have_posts()) {
|
while ($q->have_posts()) {
|
||||||
$q->the_post();
|
$q->the_post();
|
||||||
$thumb = get_the_post_thumbnail_url(get_the_ID(), $style === 'card' ? 'medium' : 'thumbnail');
|
$thumb = get_the_post_thumbnail_url(get_the_ID(), $style === 'card' ? 'medium' : 'thumbnail');
|
||||||
@@ -94,7 +92,20 @@ class WidgetOnelinePosts extends \WP_Widget {
|
|||||||
}
|
}
|
||||||
echo '</div></div>';
|
echo '</div></div>';
|
||||||
wp_reset_postdata();
|
wp_reset_postdata();
|
||||||
|
return (string) ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function widget($args, $instance): void {
|
||||||
|
$html = self::render_html($instance);
|
||||||
|
if ($html === '') {
|
||||||
|
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 $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
|
* Horizontal swiper product widget — uses shared product list payload.
|
||||||
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -7,26 +9,33 @@ namespace AKSRT\Widgets;
|
|||||||
|
|
||||||
defined('ABSPATH') || exit;
|
defined('ABSPATH') || exit;
|
||||||
|
|
||||||
/**
|
|
||||||
* Horizontal swiper product widget — equivalent to zibll `zib_shop_widget_ui_oneline_product_lists`.
|
|
||||||
*/
|
|
||||||
class WidgetProductOneline extends WidgetProductList {
|
class WidgetProductOneline extends WidgetProductList {
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
\WP_Widget::__construct(
|
\WP_Widget::__construct(
|
||||||
'aksrt_product_oneline',
|
'aksrt_product_oneline',
|
||||||
__('横滑商品', 'aksrt'),
|
__('横滑商品', 'aksrt'),
|
||||||
['description' => __('AKSRT 单行横滑商品 Swiper 组件。', 'aksrt')]
|
['description' => __('AKSRT 单行横滑商品列表(AJAX 同源)。', 'aksrt')]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function widget($args, $instance): void {
|
public function widget($args, $instance): void {
|
||||||
$instance['style'] = 'oneline';
|
$instance['style'] = 'oneline';
|
||||||
parent::widget($args, $instance);
|
// Prefer no paginate for horizontal scroller (zibll loads fixed count).
|
||||||
}
|
if (!isset($instance['paginate'])) {
|
||||||
|
$instance['paginate'] = 'none';
|
||||||
|
}
|
||||||
|
parent::widget($args, $instance);
|
||||||
|
}
|
||||||
|
|
||||||
public function form($instance): void {
|
public function form($instance): void {
|
||||||
$instance = wp_parse_args($instance, ['style' => 'oneline']);
|
$instance = wp_parse_args($instance, ['style' => 'oneline', 'paginate' => 'none']);
|
||||||
parent::form($instance);
|
parent::form($instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function update($new_instance, $old_instance): array {
|
||||||
|
$out = parent::update($new_instance, $old_instance);
|
||||||
|
$out['style'] = 'oneline';
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Registered user list (zibll widget_ui_user_lists).
|
* Registered user list (zibll widget_ui_user_lists + remote HTML).
|
||||||
*
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
*/
|
*/
|
||||||
@@ -22,20 +22,34 @@ class WidgetUserLists extends \WP_Widget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function widget($args, $instance): void {
|
/** @return array<int,int> */
|
||||||
|
public static function parse_ids_static(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 static function render_html(array $instance): string {
|
||||||
$number = max(1, min(50, (int) ($instance['number'] ?? 8)));
|
$number = max(1, min(50, (int) ($instance['number'] ?? 8)));
|
||||||
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'user_registered'));
|
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'user_registered'));
|
||||||
$order = strtoupper((string) ($instance['order'] ?? 'DESC')) === 'ASC' ? 'ASC' : 'DESC';
|
$order = strtoupper((string) ($instance['order'] ?? 'DESC')) === 'ASC' ? 'ASC' : 'DESC';
|
||||||
$include = $this->parse_ids((string) ($instance['include'] ?? ''));
|
$include = self::parse_ids_static((string) ($instance['include'] ?? ''));
|
||||||
$exclude = $this->parse_ids((string) ($instance['exclude'] ?? ''));
|
$exclude = self::parse_ids_static((string) ($instance['exclude'] ?? ''));
|
||||||
$hide_box = !empty($instance['hide_box']);
|
$hide_box = !empty($instance['hide_box']);
|
||||||
|
|
||||||
$query = [
|
$query = [
|
||||||
'number' => $number,
|
'number' => $number,
|
||||||
'order' => $order,
|
'order' => $order,
|
||||||
'fields' => ['ID', 'display_name', 'user_nicename'],
|
'fields' => ['ID', 'display_name', 'user_nicename'],
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($include) {
|
if ($include) {
|
||||||
$query['include'] = $include;
|
$query['include'] = $include;
|
||||||
$query['orderby'] = 'include';
|
$query['orderby'] = 'include';
|
||||||
@@ -52,7 +66,6 @@ class WidgetUserLists extends \WP_Widget {
|
|||||||
$query['orderby'] = 'meta_value';
|
$query['orderby'] = 'meta_value';
|
||||||
break;
|
break;
|
||||||
case 'followed-user-count':
|
case 'followed-user-count':
|
||||||
// Fallback: registered date; fan ranking needs denormalized meta when available.
|
|
||||||
$query['meta_key'] = 'aksrt_follower_count';
|
$query['meta_key'] = 'aksrt_follower_count';
|
||||||
$query['orderby'] = 'meta_value_num';
|
$query['orderby'] = 'meta_value_num';
|
||||||
break;
|
break;
|
||||||
@@ -66,11 +79,12 @@ class WidgetUserLists extends \WP_Widget {
|
|||||||
|
|
||||||
$users = get_users($query);
|
$users = get_users($query);
|
||||||
if (!$users) {
|
if (!$users) {
|
||||||
return;
|
return function_exists('aksrt_get_ajax_null')
|
||||||
|
? aksrt_get_ajax_null(__('暂无用户', 'aksrt'))
|
||||||
|
: '<p class="widget-empty ajax-item">' . esc_html__('暂无用户', 'aksrt') . '</p>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// If follower meta empty for all, re-query by registered when fan order requested.
|
if ($orderby === 'followed-user-count' && !$include && class_exists('\AKSRT\User\Follow')) {
|
||||||
if ($orderby === 'followed-user-count' && !$include) {
|
|
||||||
$has_meta = false;
|
$has_meta = false;
|
||||||
foreach ($users as $u) {
|
foreach ($users as $u) {
|
||||||
if ((int) get_user_meta($u->ID, 'aksrt_follower_count', true) > 0) {
|
if ((int) get_user_meta($u->ID, 'aksrt_follower_count', true) > 0) {
|
||||||
@@ -78,8 +92,7 @@ class WidgetUserLists extends \WP_Widget {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!$has_meta && class_exists('\AKSRT\User\Follow')) {
|
if (!$has_meta) {
|
||||||
// Rank by live follower counts (small N only).
|
|
||||||
usort($users, static function ($a, $b) {
|
usort($users, static function ($a, $b) {
|
||||||
$fa = \AKSRT\User\Follow::get_instance()->get_follower_count((int) $a->ID);
|
$fa = \AKSRT\User\Follow::get_instance()->get_follower_count((int) $a->ID);
|
||||||
$fb = \AKSRT\User\Follow::get_instance()->get_follower_count((int) $b->ID);
|
$fb = \AKSRT\User\Follow::get_instance()->get_follower_count((int) $b->ID);
|
||||||
@@ -88,13 +101,8 @@ class WidgetUserLists extends \WP_Widget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
ob_start();
|
||||||
$title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base);
|
$wrap = $hide_box ? 'aksrt-user-lists is-bare ajax-item' : 'aksrt-user-lists ajax-item';
|
||||||
if ($title !== '') {
|
|
||||||
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
||||||
}
|
|
||||||
|
|
||||||
$wrap = $hide_box ? 'aksrt-user-lists is-bare' : 'aksrt-user-lists';
|
|
||||||
echo '<div class="' . esc_attr($wrap) . '">';
|
echo '<div class="' . esc_attr($wrap) . '">';
|
||||||
foreach ($users as $user) {
|
foreach ($users as $user) {
|
||||||
$uid = (int) $user->ID;
|
$uid = (int) $user->ID;
|
||||||
@@ -111,26 +119,22 @@ class WidgetUserLists extends \WP_Widget {
|
|||||||
echo '</a>';
|
echo '</a>';
|
||||||
}
|
}
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
|
return (string) ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function widget($args, $instance): void {
|
||||||
|
$html = self::render_html($instance);
|
||||||
|
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 $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array<int, int>
|
|
||||||
*/
|
|
||||||
private function parse_ids(string $raw): array {
|
private function parse_ids(string $raw): array {
|
||||||
if ($raw === '') {
|
return self::parse_ids_static($raw);
|
||||||
return [];
|
|
||||||
}
|
|
||||||
$parts = preg_split('/[\s,]+/', $raw) ?: [];
|
|
||||||
$ids = [];
|
|
||||||
foreach ($parts as $p) {
|
|
||||||
$id = (int) $p;
|
|
||||||
if ($id > 0) {
|
|
||||||
$ids[] = $id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return array_values(array_unique($ids));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function form($instance): void {
|
public function form($instance): void {
|
||||||
@@ -187,13 +191,13 @@ class WidgetUserLists extends \WP_Widget {
|
|||||||
$orderby = 'user_registered';
|
$orderby = 'user_registered';
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
|
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
|
||||||
'number' => max(1, min(50, (int) ($new_instance['number'] ?? 8))),
|
'number' => max(1, min(50, (int) ($new_instance['number'] ?? 8))),
|
||||||
'include' => sanitize_text_field((string) ($new_instance['include'] ?? '')),
|
'include' => sanitize_text_field((string) ($new_instance['include'] ?? '')),
|
||||||
'exclude' => sanitize_text_field((string) ($new_instance['exclude'] ?? '')),
|
'exclude' => sanitize_text_field((string) ($new_instance['exclude'] ?? '')),
|
||||||
'orderby' => $orderby,
|
'orderby' => $orderby,
|
||||||
'order' => strtoupper((string) ($new_instance['order'] ?? 'DESC')) === 'ASC' ? 'ASC' : 'DESC',
|
'order' => strtoupper((string) ($new_instance['order'] ?? 'DESC')) === 'ASC' ? 'ASC' : 'DESC',
|
||||||
'hide_box'=> !empty($new_instance['hide_box']) ? 1 : 0,
|
'hide_box' => !empty($new_instance['hide_box']) ? 1 : 0,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user