esc_html__('按排序/版块筛选展示论坛帖子(支持 AJAX 加载更多)。', 'aksrt'), 'classname' => 'widget_aksrt_forum_topic_lists', ] ); } /** * @param array $instance * @param int $paged * @return array */ public static function build_query_args(array $instance, int $paged = 1): array { $count = max(1, min(30, (int) ($instance['count'] ?? 8))); $orderby = sanitize_key((string) ($instance['orderby'] ?? 'date')); $plate_id = (int) ($instance['plate_id'] ?? 0); $query = [ 'post_type' => 'aksrt_forum_topic', 'post_status' => 'publish', 'posts_per_page' => $count, 'paged' => max(1, $paged), 'order' => 'DESC', ]; switch ($orderby) { case 'views': $query['meta_key'] = '_aksrt_views'; $query['orderby'] = 'meta_value_num'; break; case 'comments': $query['orderby'] = 'comment_count'; break; case 'modified': $query['orderby'] = 'modified'; break; case 'essence': $query['meta_query'] = [[ 'key' => '_aksrt_essence', 'value' => '1', ]]; $query['orderby'] = 'date'; break; default: $query['orderby'] = 'date'; } if ($plate_id > 0) { $query['meta_query'] = array_values(array_filter(array_merge( isset($query['meta_query']) ? $query['meta_query'] : [], [[ 'key' => '_aksrt_plate_id', 'value' => $plate_id, ]] ))); } return $query; } public static function render_items_html(\WP_Query $q, string $style = 'mini'): string { if (!$q->have_posts()) { return ''; } ob_start(); echo $style === 'detail' ? '
' : '
'; while ($q->have_posts()) { $q->the_post(); if ($style === 'detail' && function_exists('aksrt_render_forum_topic_detail')) { echo aksrt_render_forum_topic_detail(null, 'ajax-item', true); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } elseif (function_exists('aksrt_render_forum_topic_mini')) { echo aksrt_render_forum_topic_mini(null, 'ajax-item', true); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } else { $views = (int) get_post_meta(get_the_ID(), '_aksrt_views', true); echo '
'; echo '' . esc_html(get_the_title()) . ''; echo '' . esc_html((string) $views) . ''; echo '
'; } } echo '
'; wp_reset_postdata(); return (string) ob_get_clean(); } /** * @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); $style = sanitize_key((string) ($instance['style'] ?? 'mini')); $paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax')); if (!in_array($paginate, ['none', 'ajax', 'number'], true)) { $paginate = 'ajax'; } $q = new \WP_Query(self::build_query_args($instance, $page)); $html = self::render_items_html($q, $style); if ($html === '' && $page === 1) { $html = function_exists('aksrt_get_ajax_null') ? aksrt_get_ajax_null(__('暂无内容', 'aksrt')) : '

' . esc_html__('暂无内容', 'aksrt') . '

'; } $max_pages = max(1, (int) $q->max_num_pages); $total = (int) $q->found_posts; $has_more = $page < $max_pages; $base_qs = array_filter([ 'count' => max(1, min(30, (int) ($instance['count'] ?? 8))), 'orderby' => sanitize_key((string) ($instance['orderby'] ?? 'date')), 'style' => $style, 'plate_id' => (int) ($instance['plate_id'] ?? 0), 'paginate' => $paginate, ], static function ($v) { return $v !== '' && $v !== null; }); $rest_base = add_query_arg($base_qs, rest_url('aksrt/v1/forum/frontend/widgets/topics')); $paginate_html = ''; if ($paginate === 'ajax' && $has_more) { $next = add_query_arg(['page' => $page + 1], $rest_base); $paginate_html = function_exists('aksrt_get_ajax_next_paginate') ? aksrt_get_ajax_next_paginate($total, $page, max(1, (int) ($instance['count'] ?? 8)), $next) : '
'; } elseif ($paginate === 'number' && $max_pages > 1) { $paginate_html = function_exists('aksrt_get_ajax_number_paginate') ? aksrt_get_ajax_number_paginate($total, $page, max(1, (int) ($instance['count'] ?? 8)), $rest_base) : '
'; } else { $paginate_html = '
'; } return [ 'html' => $html, 'paginate_html' => $paginate_html, 'has_more' => $has_more, 'page' => $page, 'max_pages' => $max_pages, 'total' => $total, ]; } public function widget($args, $instance): void { if (!post_type_exists('aksrt_forum_topic')) { return; } $count = max(1, min(30, (int) ($instance['count'] ?? 8))); $orderby = sanitize_key((string) ($instance['orderby'] ?? 'date')); $style = sanitize_key((string) ($instance['style'] ?? 'mini')); $plate_id = (int) ($instance['plate_id'] ?? 0); $current_plate = !empty($instance['current_plate']); $paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax')); if ($current_plate) { $resolved = $this->resolve_current_plate_id(); if ($resolved <= 0) { return; } $plate_id = $resolved; } $instance['count'] = $count; $instance['orderby'] = $orderby; $instance['style'] = $style; $instance['plate_id'] = $plate_id; $instance['paginate'] = $paginate; $payload = self::query_payload($instance, 1); $rest = rest_url('aksrt/v1/forum/frontend/widgets/topics'); 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 '
'; echo '
'; echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo ''; echo '
'; echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } private function resolve_current_plate_id(): int { if (is_singular('aksrt_forum_plate')) { return (int) get_queried_object_id(); } if (is_singular('aksrt_forum_topic')) { $topic_id = (int) get_queried_object_id(); $plate_id = (int) get_post_meta($topic_id, '_aksrt_plate_id', true); return max(0, $plate_id); } return 0; } public function form($instance): void { $defaults = [ 'title' => __('帖子列表', 'aksrt'), 'count' => 8, 'orderby' => 'date', 'style' => 'mini', 'plate_id' => 0, 'current_plate' => 0, 'paginate' => 'ajax', ]; $instance = wp_parse_args($instance, $defaults); ?>

sanitize_text_field((string) ($new_instance['title'] ?? '')), 'count' => max(1, min(30, (int) ($new_instance['count'] ?? 8))), 'orderby' => sanitize_key((string) ($new_instance['orderby'] ?? 'date')), 'style' => sanitize_key((string) ($new_instance['style'] ?? 'mini')), 'plate_id' => max(0, (int) ($new_instance['plate_id'] ?? 0)), 'current_plate' => !empty($new_instance['current_plate']) ? 1 : 0, 'paginate' => in_array(sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')), ['none', 'ajax', 'number'], true) ? sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) : 'ajax', ]; } }