diff --git a/src/AKSRT/Core/WidgetAjax.php b/src/AKSRT/Core/WidgetAjax.php index c16a409e..5cd0166d 100644 --- a/src/AKSRT/Core/WidgetAjax.php +++ b/src/AKSRT/Core/WidgetAjax.php @@ -1,6 +1,6 @@ 'GET', - 'callback' => [$this, 'rest_main_posts'], - 'permission_callback' => '__return_true', - ]); - register_rest_route('aksrt/v1', '/widgets/tab-posts', [ - 'methods' => 'GET', - 'callback' => [$this, 'rest_tab_posts'], - 'permission_callback' => '__return_true', - ]); - register_rest_route('aksrt/v1', '/widgets/paid-posts', [ - 'methods' => 'GET', - 'callback' => [$this, 'rest_paid_posts'], - 'permission_callback' => '__return_true', - ]); - register_rest_route('aksrt/v1', '/widgets/category-tabs', [ - 'methods' => 'GET', - 'callback' => [$this, 'rest_category_tabs'], - 'permission_callback' => '__return_true', - ]); + $routes = [ + '/widgets/posts' => 'rest_main_posts', + '/widgets/tab-posts' => 'rest_tab_posts', + '/widgets/paid-posts' => 'rest_paid_posts', + '/widgets/category-tabs' => 'rest_category_tabs', + '/widgets/hot-posts' => 'rest_hot_posts', + '/widgets/oneline-posts' => 'rest_oneline_posts', + '/widgets/recent-comments'=> 'rest_recent_comments', + '/widgets/user-lists' => 'rest_user_lists', + '/widgets/forum-topics' => 'rest_forum_topics', + '/widgets/forum-terms' => 'rest_forum_terms', + ]; + foreach ($routes as $path => $cb) { + register_rest_route('aksrt/v1', $path, [ + 'methods' => 'GET', + 'callback' => [$this, $cb], + 'permission_callback' => '__return_true', + ]); + } } public function rest_main_posts(\WP_REST_Request $request) { if (!class_exists('\AKSRT\Widgets\WidgetMainPosts')) { - return new \WP_REST_Response(['success' => false, 'message' => 'unavailable'], 500); + return $this->fail(); } $instance = [ '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')), ]; $page = max(1, (int) ($request->get_param('page') ?? $request->get_param('paged') ?? 1)); - $payload = \AKSRT\Widgets\WidgetMainPosts::query_payload($instance, $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); + return $this->payload(\AKSRT\Widgets\WidgetMainPosts::query_payload($instance, $page), $page); } public function rest_tab_posts(\WP_REST_Request $request) { 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))); $tab = [ @@ -94,15 +84,12 @@ class WidgetAjax { } else { $html = '
'; } - return new \WP_REST_Response([ - 'success' => true, - 'html' => $html, - ], 200); + return new \WP_REST_Response(['success' => true, 'html' => $html], 200); } public function rest_paid_posts(\WP_REST_Request $request) { if (!class_exists('\AKSRT\Widgets\WidgetPaidPosts')) { - return new \WP_REST_Response(['success' => false, 'message' => 'unavailable'], 500); + return $this->fail(); } $instance = [ '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')), ]; $page = max(1, (int) ($request->get_param('page') ?? $request->get_param('paged') ?? 1)); - $payload = \AKSRT\Widgets\WidgetPaidPosts::query_payload($instance, $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); + return $this->payload(\AKSRT\Widgets\WidgetPaidPosts::query_payload($instance, $page), $page); } public function rest_category_tabs(\WP_REST_Request $request) { @@ -152,7 +130,111 @@ class WidgetAjax { echo ''; } 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); } + + 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); + } } diff --git a/src/AKSRT/Widgets/HotPostsWidget.php b/src/AKSRT/Widgets/HotPostsWidget.php index f24d9b81..fb011cc5 100644 --- a/src/AKSRT/Widgets/HotPostsWidget.php +++ b/src/AKSRT/Widgets/HotPostsWidget.php @@ -1,5 +1,7 @@ esc_html__('按浏览量/评论数/点赞数排序的热门文章列表', 'aksrt'), - 'customize_selective_refresh' => true, - ] - ); - } + public function __construct() { + parent::__construct( + 'aksrt_hot_posts', + esc_html__('AKSRT 热榜文章', 'aksrt'), + [ + 'description' => esc_html__('按浏览量/评论数/点赞数排序的热门文章列表', 'aksrt'), + 'customize_selective_refresh' => true, + ] + ); + } - public function widget($args, $instance): void { - echo $args['before_widget']; + public static function build_query_args(array $instance, int $paged = 1): array { + $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); - $count = absint($instance['count'] ?? 5); - $order_by = $instance['order_by'] ?? 'views'; - $days = absint($instance['days'] ?? 30); - $show_thumb = !empty($instance['show_thumb']); + public static function render_items_html(\WP_Query $query, array $instance, int $start = 0): string { + if (!$query->have_posts()) { + return ''; + } + $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); + ?> ++ + +
++ + +
++ + +
++ + +
++ +
++ +
+ have_posts()) { - echo '