feat(forum): rebuild forum home page
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
51d5b8a2a1
commit
024ecddfed
16 files changed
+1061
-198
No files matched your search
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
namespace Jio\Forum;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
final class HomeContent {
|
||||
public static function render(array $tab, int $index): string {
|
||||
$page = self::page();
|
||||
$html = match ($tab['type']) {
|
||||
'plate' => self::plate_tab(),
|
||||
'follow' => self::follow_tab($tab, $index, $page),
|
||||
'pending' => self::pending_tab($tab, $index, $page),
|
||||
default => self::posts_tab($tab, $index, $page),
|
||||
};
|
||||
if ($page === 1 && $tab['type'] !== 'plate' && jio_get_setting('jio_forum_home_quick_post', true) && $index === (int) jio_get_setting('jio_forum_home_quick_post_tab', 2)) {
|
||||
$html = QuickPost::render() . $html;
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
public static function page(): int {
|
||||
$raw = $_GET['fpage'] ?? 1;
|
||||
return max(1, is_scalar($raw) ? absint($raw) : 1);
|
||||
}
|
||||
|
||||
private static function posts_tab(array $tab, int $index, int $page): string {
|
||||
$args = self::query_args($tab, $page);
|
||||
$html = self::post_list($args, $tab, $index, $page, $tab['type'] === 'synthesis');
|
||||
if ($html !== '') return $html;
|
||||
$html = jio_get_ajax_null('内容空空如也');
|
||||
if ($page === 1) {
|
||||
$html .= '<div class="text-center mb20 ajax-item">' . self::create_plate_button('ml10 mr10 mt10 but hollow c-blue padding-lg') . self::publish_button('ml10 mr10 mt10 but hollow c-green padding-lg') . '</div>';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
private static function follow_tab(array $tab, int $index, int $page): string {
|
||||
$user_id = get_current_user_id();
|
||||
if (!$user_id) {
|
||||
return '<div class="ajax-item">' . jio_get_null('登录后继续查看', 20, 'null-user.svg', '', 0, 220)
|
||||
. '<p class="text-center mb20"><a class="but jb-blue padding-lg" href="' . esc_url(jio_get_login_url(Core::home_url())) . '"><i class="fa fas fa-sign-in-alt mr6"></i>登录</a></p></div>';
|
||||
}
|
||||
$followed = View::user_marked_ids($user_id, '_jio_forum_follow_');
|
||||
$html = '';
|
||||
if ($page === 1 && jio_get_setting('jio_forum_home_recommend_plate', true)) {
|
||||
$plates = self::plates(['posts_per_page' => 8, 'post__not_in' => $followed]);
|
||||
$slide = Cards::plate_slide($plates);
|
||||
if ($slide !== '') {
|
||||
$html .= '<div class="ajax-item mb20"><div class="box-body notop"><div class="title-theme">热门推荐</div></div>' . $slide . '</div>';
|
||||
}
|
||||
}
|
||||
$list = '';
|
||||
if ($followed) {
|
||||
$args = self::query_args($tab, $page);
|
||||
$args['meta_query'][] = ['key' => '_jio_forum_plate_id', 'value' => $followed, 'compare' => 'IN'];
|
||||
$list = self::post_list($args, $tab, $index, $page);
|
||||
}
|
||||
return $html . ($list !== '' ? $list : jio_get_ajax_null('暂无内容', 60, 'null.svg'));
|
||||
}
|
||||
|
||||
private static function pending_tab(array $tab, int $index, int $page): string {
|
||||
$html = '';
|
||||
if ($page === 1) {
|
||||
foreach (get_posts(['post_type' => Core::PLATE, 'post_status' => 'pending', 'posts_per_page' => 20]) as $plate) {
|
||||
$html .= '<div class="forum-pending-plate jio-widget-box flex ac jsb ajax-item"><span class="text-ellipsis"><span class="badg badg-sm c-yellow mr6">待审核版块</span>' . esc_html($plate->post_title) . '</span>'
|
||||
. '<button type="button" class="but c-blue p2-10 px12 flex0" data-forum-action="plate-audit" data-id="' . (int) $plate->ID . '">通过审核</button></div>';
|
||||
}
|
||||
}
|
||||
$list = self::post_list(['post_type' => Core::POST, 'post_status' => 'pending', 'posts_per_page' => self::per_page(), 'paged' => $page], $tab, $index, $page);
|
||||
$html .= $list;
|
||||
return $html !== '' ? $html : jio_get_ajax_null('暂无待审核内容');
|
||||
}
|
||||
|
||||
private static function plate_tab(): string {
|
||||
$html = '';
|
||||
$user_id = get_current_user_id();
|
||||
if ($user_id && jio_get_setting('jio_forum_home_follow_plate', true)) {
|
||||
$followed = View::user_marked_ids($user_id, '_jio_forum_follow_');
|
||||
$slide = $followed ? Cards::plate_slide(self::plates(['post__in' => $followed, 'posts_per_page' => 20]), 'mini', false, true) : '';
|
||||
if ($slide !== '') $html .= self::panel('我关注的版块', $slide);
|
||||
}
|
||||
if (jio_get_setting('jio_forum_home_hot_plate', true)) {
|
||||
$slide = Cards::plate_slide(self::plates(['posts_per_page' => 8, 'meta_key' => '_jio_forum_follow_count', 'orderby' => 'meta_value_num']));
|
||||
if ($slide !== '') $html .= self::panel('热门推荐', $slide);
|
||||
}
|
||||
$all = self::plates(['posts_per_page' => -1, 'orderby' => 'menu_order title', 'order' => 'ASC']);
|
||||
$groups = [];
|
||||
$loose = [];
|
||||
$terms = wp_get_object_terms(wp_list_pluck($all, 'ID'), Core::CATEGORY, ['fields' => 'all_with_object_id']);
|
||||
$by_plate = [];
|
||||
foreach (is_array($terms) ? $terms : [] as $term) {
|
||||
$by_plate[(int) $term->object_id][] = $term;
|
||||
}
|
||||
foreach ($all as $plate) {
|
||||
if (empty($by_plate[$plate->ID])) {
|
||||
$loose[] = $plate;
|
||||
continue;
|
||||
}
|
||||
foreach ($by_plate[$plate->ID] as $term) {
|
||||
$groups[$term->term_id]['term'] = $term;
|
||||
$groups[$term->term_id]['plates'][] = $plate;
|
||||
}
|
||||
}
|
||||
uasort($groups, static fn(array $a, array $b): int => count($b['plates']) <=> count($a['plates']));
|
||||
$plate_name = (string) jio_get_setting('jio_forum_plate_name', '版块') ?: '版块';
|
||||
$single_group = count($groups) === 0 && $loose;
|
||||
if ($loose) $groups[0] = ['term' => null, 'plates' => $loose];
|
||||
$i = 1;
|
||||
foreach ($groups as $term_id => $group) {
|
||||
$name = $group['term'] instanceof \WP_Term ? $group['term']->name : ($single_group ? '全部' . $plate_name : '其他' . $plate_name);
|
||||
$html .= self::plate_group('home-plate-panel-' . $i++, $name, $group['plates'], (int) $term_id);
|
||||
}
|
||||
if ($html === '') {
|
||||
$html = jio_get_null('暂时没有版块', 60, 'null.svg', '', 0, 170) . '<div class="text-center mt20">' . self::create_plate_button('but hollow c-blue padding-lg') . '</div>';
|
||||
}
|
||||
return '<div class="ajax-item">' . $html . '</div>';
|
||||
}
|
||||
|
||||
/** @param \WP_Post[] $plates */
|
||||
private static function plate_group(string $id, string $name, array $plates, int $term_id): string {
|
||||
$add = self::create_plate_button('plate-add ml20 but hollow c-blue p2-10 px12 flex0', $term_id);
|
||||
$items = '';
|
||||
foreach ($plates as $plate) {
|
||||
$items .= Cards::plate_item($plate);
|
||||
}
|
||||
$title = '<span class="title-theme" title="' . esc_attr($name) . '"><span class="text-ellipsis">' . esc_html($name) . '</span></span>';
|
||||
$top = wp_is_mobile()
|
||||
? '<h4 class="panel-title flex ac">' . $title . $add . '</h4>'
|
||||
: '<h4 class="panel-title flex ac"><a class="flex ac jsb flex1" data-toggle="collapse" href="#' . esc_attr($id) . '">' . $title . '<span><i class="ml10 mr10 fas fa-angle-up em14 muted-2-color"></i></span></a>' . $add . '</h4>';
|
||||
return '<div class="panel panel-plate">' . $top . '<div id="' . esc_attr($id) . '" class="panel-collapse collapse in"><div class="plate-lists">' . $items . '</div></div></div>';
|
||||
}
|
||||
|
||||
private static function panel(string $title, string $body): string {
|
||||
return '<div class="panel panel-plate"><h4 class="panel-title" title="' . esc_attr($title) . '"><span class="title-theme">' . esc_html($title) . '</span></h4>' . $body . '</div>';
|
||||
}
|
||||
|
||||
/** @return \WP_Post[] */
|
||||
private static function plates(array $args): array {
|
||||
$plates = get_posts(array_merge(['post_type' => Core::PLATE, 'post_status' => 'publish', 'orderby' => 'modified', 'order' => 'DESC', 'no_found_rows' => true], $args));
|
||||
PlateStats::prime(wp_list_pluck($plates, 'ID'));
|
||||
return $plates;
|
||||
}
|
||||
|
||||
private static function query_args(array $tab, int $page): array {
|
||||
$args = [
|
||||
'post_type' => Core::POST,
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => self::per_page(),
|
||||
'paged' => $page,
|
||||
'jio_forum_list' => $tab['orderby'],
|
||||
'meta_query' => [],
|
||||
];
|
||||
if ($tab['filter'] === 'essence') {
|
||||
$args['meta_query'][] = ['key' => '_jio_forum_essence', 'value' => 1];
|
||||
} elseif (in_array($tab['filter'], ['question', 'vote'], true)) {
|
||||
$args['meta_query'][] = ['key' => '_jio_forum_type', 'value' => $tab['filter']];
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
private static function post_list(array $args, array $tab, int $index, int $page, bool $show_topping = false): string {
|
||||
$query = new \WP_Query($args);
|
||||
if (!$query->have_posts()) return '';
|
||||
Cards::prime($query->posts);
|
||||
$html = '';
|
||||
foreach ($query->posts as $post) {
|
||||
$html .= $tab['style'] === 'mini' || $tab['type'] === 'pending'
|
||||
? Cards::post_mini($post, 'alone ajax-item', $show_topping)
|
||||
: Cards::post_detail($post, 'alone ajax-item', true, $show_topping);
|
||||
}
|
||||
if ($page < (int) $query->max_num_pages) {
|
||||
$next = add_query_arg(['index' => $index, 'fpage' => $page + 1], remove_query_arg(['index', 'fpage']));
|
||||
$html .= '<div class="text-center theme-pagination forum-more"><a class="but hollow c-blue" href="' . esc_url($next) . '" data-forum-more>加载更多</a></div>';
|
||||
}
|
||||
$html .= '<div class="post_ajax_loader">' . HomeTabs::placeholder('posts', 2) . '</div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
private static function per_page(): int {
|
||||
return max(1, min(50, (int) jio_get_setting('jio_forum_page_size', 20)));
|
||||
}
|
||||
|
||||
public static function create_plate_button(string $class, int $term_id = 0): string {
|
||||
$user_id = get_current_user_id();
|
||||
if (!$user_id || (!Access::is_admin($user_id) && !jio_get_setting('jio_forum_user_plates', true))) return '';
|
||||
$name = (string) jio_get_setting('jio_forum_plate_name', '版块') ?: '版块';
|
||||
return '<button type="button" class="' . esc_attr($class) . '" data-forum-open="plate" data-category="' . (int) $term_id . '"><i class="fa fas fa-plus mr3"></i>创建' . esc_html($name) . '</button>';
|
||||
}
|
||||
|
||||
public static function publish_button(string $class): string {
|
||||
$name = (string) jio_get_setting('jio_forum_post_name', '帖子') ?: '帖子';
|
||||
$url = is_user_logged_in() ? Core::edit_url() : jio_get_login_url(Core::edit_url());
|
||||
return '<a class="' . esc_attr($class) . '" href="' . esc_url($url) . '"><i class="fa fas fa-edit mr3"></i>发布' . esc_html($name) . '</a>';
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user