post_type !== Core::PLATE) { self::term(); return; } self::open($plate->post_title, 'plate', $plate); \Jio\WidgetSystem\WidgetAreas::render('forum_plate_top_fluid'); echo '
'; echo Cards::plate_header($plate); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo self::tab_bar($plate); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo '
'; self::close('plate'); } /** Taxonomy archives (plate category / topic / tag). */ public static function term(): void { $term = get_queried_object(); if (!$term instanceof \WP_Term) { self::open('论坛', 'term', null); self::close('term'); return; } self::open($term->name, 'term', null, $term); \Jio\WidgetSystem\WidgetAreas::render('forum_term_top_fluid'); echo '
'; echo self::tab_bar(null, $term); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo '
'; self::close('term'); } private static function open(string $title, string $context, ?\WP_Post $plate, ?\WP_Term $term = null): void { echo '
'; echo '
'; echo '
'; if ($plate) { $plate_name = (string) jio_get_setting('jio_forum_plate_name', '版块') ?: '版块'; echo ''; } elseif ($term instanceof \WP_Term) { echo '
' . esc_html($term->name) . '
'; if ($term->description !== '') echo '

' . esc_html($term->description) . '

'; echo '
'; } } private static function close(string $context): void { echo '
'; self::sidebar($context); echo '
'; \Jio\WidgetSystem\WidgetAreas::render('forum_' . $context . '_bottom_fluid'); echo '
'; } private static function sidebar(string $context): void { if (!jio_is_show_sidebar()) return; echo ''; } /** Plate tab bar + panes; the first tab renders server-side, the rest load by `?plate_tab=N`. */ public static function tab_bar(?\WP_Post $plate = null, ?\WP_Term $term = null): string { $tabs = self::tabs($plate); if (!$tabs) return ''; $active = self::active_index(count($tabs)); $base = remove_query_arg(['plate_tab', 'fpage']); if ($term instanceof \WP_Term) $base = get_term_link($term); $nav = $panes = ''; foreach ($tabs as $index => $tab) { $id = 'plate-tab-' . $index; $href = add_query_arg('plate_tab', $index, is_string($base) ? $base : Core::home_url()); $nav .= '' . $tab['title'] . ''; $panes .= '
'; $panes .= $index === $active ? self::pane($tab, $plate, $term, $index) : '
' . HomeTabs::placeholder('posts', 3) . '
'; $panes .= '
'; } return '
    ' . $nav . '
' . $panes . '
'; } /** @return array> */ public static function tabs(?\WP_Post $plate = null): array { $tabs = []; $configured = jio_get_setting('jio_forum_plate_tab_items', null); if (is_array($configured) && $configured) { foreach ($configured as $row) { if (!is_array($row)) continue; $tabs[] = [ 'title' => wp_kses_post((string) ($row['title'] ?? '') ?: '栏目'), 'orderby' => sanitize_key((string) ($row['orderby'] ?? 'date')), 'filter' => sanitize_key((string) ($row['filter'] ?? '')), 'style' => sanitize_key((string) ($row['style'] ?? 'detail')), ]; } } else { foreach ([ ['最新发布', 'date', '', 'detail'], ['最近回复', 'last_reply', '', 'detail'], ['热门', 'views', '', 'detail'], ['精华', 'modified', 'essence', 'detail'], ] as [$title, $orderby, $filter, $style]) { $tabs[] = ['title' => $title, 'orderby' => $orderby, 'filter' => $filter, 'style' => $style]; } } $user_id = get_current_user_id(); if ($plate instanceof \WP_Post && Access::is_moderator($user_id, $plate->ID)) { $tabs[] = ['title' => '待审核', 'orderby' => 'date', 'filter' => '', 'style' => 'mini', 'status' => 'pending']; $tabs[] = ['title' => '回收站', 'orderby' => 'date', 'filter' => '', 'style' => 'mini', 'status' => 'trash']; } return $tabs; } public static function active_index(int $count): int { $raw = $_GET['plate_tab'] ?? 0; $index = (is_scalar($raw) ? absint($raw) : 0) ?: (int) jio_get_setting('jio_forum_plate_tab_active', 1); return $index >= 1 && $index <= $count ? $index : 1; } private static function pane(array $tab, ?\WP_Post $plate, ?\WP_Term $term, int $index): string { $page = max(1, is_scalar($_GET['fpage'] ?? 1) ? absint($_GET['fpage'] ?? 1) : 1); $args = [ 'post_type' => Core::POST, 'post_status' => $tab['status'] ?? 'publish', 'posts_per_page' => max(1, min(50, (int) jio_get_setting('jio_forum_page_size', 20))), 'paged' => $page, 'jio_forum_list' => $tab['orderby'], ]; if ($plate instanceof \WP_Post) { $args['meta_query'][] = ['key' => '_jio_forum_plate_id', 'value' => $plate->ID]; $topping = self::topping($plate->ID, $tab); if ($topping) { $args['post__not_in'] = $topping; } } elseif ($term instanceof \WP_Term) { $args['tax_query'][] = ['taxonomy' => $term->taxonomy, 'terms' => [$term->term_id]]; } if (($tab['filter'] ?? '') === 'essence') { $args['meta_query'][] = ['key' => '_jio_forum_essence', 'value' => 1]; } $query = new \WP_Query($args); $html = ''; if ($plate instanceof \WP_Post && ($tab['status'] ?? '') === '') { Cards::prime($topping_posts = self::topping_posts($plate->ID, $tab)); foreach ($topping_posts as $post) { $html .= Cards::post_mini($post, 'ajax-item', true); } } if ($query->have_posts()) { Cards::prime($query->posts); foreach ($query->posts as $post) { $html .= ($tab['style'] ?? 'detail') === 'detail' ? Cards::post_detail($post, 'ajax-item') : Cards::post_mini($post, 'ajax-item'); } } $base = $plate instanceof \WP_Post ? get_permalink($plate) : ($term instanceof \WP_Term ? get_term_link($term) : Core::home_url()); $next = add_query_arg(['plate_tab' => $index, 'fpage' => $page + 1], is_string($base) ? $base : Core::home_url()); if ($page < (int) $query->max_num_pages) { $html .= ''; } $html .= '
' . HomeTabs::placeholder('posts', 3) . '
'; if ($html !== '' && trim(wp_strip_all_tags($html)) !== '') return $html; $empty = jio_get_ajax_null('内容空空如也'); if ($index === 1 && $page === 1 && $plate instanceof \WP_Post) { $empty .= ''; } return $empty; } /** @return int[] */ private static function topping(int $plate_id, array $tab): array { if (($tab['filter'] ?? '') === 'essence' || ($tab['status'] ?? '') !== '') return []; return wp_list_pluck(self::topping_posts($plate_id, $tab), 'ID'); } /** @return \WP_Post[] */ private static function topping_posts(int $plate_id, array $tab): array { return get_posts([ 'post_type' => Core::POST, 'post_status' => 'publish', 'posts_per_page' => 5, 'meta_query' => [ ['key' => '_jio_forum_plate_id', 'value' => $plate_id], ['key' => '_jio_forum_pinned', 'value' => 1], ], ]); } }