Files
wordpress-theme-aksrt/templates/pages/page-forums.php
T
kate522 aaf458af1c refactor(autoload): migrate theme classes to Composer PSR-4
Move 288 types from global AKSRT_* + inc/classes manual requires into
namespace AKSRT\{Domain} under src/AKSRT/, wire composer.json psr-4,
and slim bootstrap to helpers/modules/hooks only. Split multi-class
widget/gateway files, update admin contract audit paths, and document
the layout in ADR/README.
2026-07-17 13:29:22 +08:00

360 lines
20 KiB
PHP

<?php
/**
* Template Name: AKSRT - Forums
* Template Post Type: page
*
* §7.10 / stream-h §3 — 主站社区首页:公开 tabs + 侧栏发帖/热门,pending 不进公开主内容。
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
get_header();
$forum = class_exists('\AKSRT\Forum\Forum') ? \AKSRT\Forum\Forum::get_instance() : null;
$current_user_id = get_current_user_id();
$view = $forum ? $forum->get_home_view($current_user_id) : [
'boards' => [],
'recent_topics' => [],
'hot_topics' => [],
'stats' => [],
'permissions' => ['can_compose' => false, 'can_manage' => false],
'applications' => [],
'home_tabs' => [],
'active_index' => 1,
'quick_posts' => true,
];
$boards = $view['boards'] ?? [];
$recent_topics = $view['recent_topics'] ?? [];
$synthesis = is_array($view['synthesis'] ?? null) ? $view['synthesis'] : ['items' => $recent_topics, 'max_pages' => 1, 'page' => 1, 'total' => count($recent_topics)];
$synthesis_max = max(1, (int) ($synthesis['max_pages'] ?? 1));
$hot_topics = $view['hot_topics'] ?? [];
$stats = $view['stats'] ?? [];
$permissions = $view['permissions'] ?? [];
$applications = $view['applications'] ?? [];
$compose_url = aksrt_get_forum_compose_url();
$forum_settings = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_forum_settings() : [];
$forum_names = $forum_settings['names'] ?? [];
$name_forum = $forum_names['forum'] ?? __('论坛', 'aksrt');
$name_plate = $forum_names['plate'] ?? __('版块', 'aksrt');
$name_topic = $forum_names['posts'] ?? __('主题', 'aksrt');
$name_reply = $forum_names['comment'] ?? __('回复', 'aksrt');
$admin_forum_url = admin_url('admin.php?page=aksrt-theme-admin#/forum');
$home_tabs = $view['home_tabs'] ?? [];
$active_index = max(0, min(count($home_tabs) - 1, (int) ($view['active_index'] ?? 1)));
$quick_posts = !empty($view['quick_posts']);
$nonce = wp_create_nonce('aksrt_public_nonce');
// Resolve active tab from query param or default
$active_tab_type = isset($_GET['forum_tab']) ? sanitize_key(wp_unslash($_GET['forum_tab'])) : '';
if ($active_tab_type === '' && isset($home_tabs[$active_index])) {
$active_tab_type = $home_tabs[$active_index]['type'] ?? 'synthesis';
}
if ($active_tab_type === '') {
$active_tab_type = 'synthesis';
}
// 前台公开主 tabs 不允许 pending;未登录时 follow 回落到综合
$can_manage = !empty($permissions['can_manage']);
if ($active_tab_type === 'pending') {
$active_tab_type = 'synthesis';
}
if ($active_tab_type === 'follow' && $current_user_id <= 0) {
$active_tab_type = 'synthesis';
}
// 配置里的 pending 类型从公开 tab 列表剔除(治理入口单独渲染)
$public_home_tabs = [];
foreach ((array) $home_tabs as $tab_row) {
$tt = sanitize_key((string) ($tab_row['type'] ?? ''));
if ($tt === '' || $tt === 'pending') {
continue;
}
$public_home_tabs[] = $tab_row;
}
if (empty($public_home_tabs)) {
$public_home_tabs = [
['type' => 'synthesis', 'label' => __('综合', 'aksrt')],
['type' => 'follow', 'label' => __('关注', 'aksrt')],
['type' => 'plate', 'label' => $name_plate],
];
}
?>
<main id="main-content" class="site-main content-shell" tabindex="-1">
<?php if (function_exists('aksrt_breadcrumbs')) { aksrt_breadcrumbs(); } ?>
<header class="aksrt-forum-header container">
<div class="aksrt-forum-header__content">
<div class="aksrt-forum-header__eyebrow">
<span class="aksrt-forum-header__eyebrow-pill"><i class="fas fa-comments"></i> <?php echo esc_html($name_forum); ?></span>
<span class="aksrt-forum-header__eyebrow-meta"><?php printf(esc_html__('%1$d 个%2$s · %3$d 条%4$s', 'aksrt'), (int) ($stats['board_count'] ?? 0), esc_html($name_plate), (int) ($stats['topic_count'] ?? 0), esc_html($name_topic)); ?></span>
</div>
<h1 class="aksrt-forum-header__title"><?php echo esc_html(get_the_title() ?: __('社区论坛', 'aksrt')); ?></h1>
<?php if (get_the_excerpt()) : ?>
<p class="aksrt-forum-header__desc"><?php echo esc_html(get_the_excerpt()); ?></p>
<?php else : ?>
<p class="aksrt-forum-header__desc"><?php esc_html_e('围绕站点内容延展讨论、问答与经验分享,保留社区能力但回归主站内容流语义。', 'aksrt'); ?></p>
<?php endif; ?>
<div class="aksrt-forum-header__actions">
<?php if (!empty($permissions['can_compose'])) : ?>
<a class="aksrt-forum-header__action" href="<?php echo esc_url($compose_url); ?>">
<i class="fas fa-pen"></i> <?php esc_html_e('发布主题', 'aksrt'); ?>
</a>
<?php elseif ($current_user_id <= 0) : ?>
<a class="aksrt-forum-header__action" href="<?php echo esc_url(function_exists('aksrt_get_login_url') ? aksrt_get_login_url(get_permalink()) : wp_login_url(get_permalink())); ?>">
<i class="fas fa-sign-in-alt"></i> <?php esc_html_e('登录后参与', 'aksrt'); ?>
</a>
<?php endif; ?>
</div>
</div>
</header>
<?php if (isset($_GET['compose_status']) && $_GET['compose_status'] === 'pending') : ?>
<div class="aksrt-alert aksrt-alert--info" data-aksrt-flash-query="compose_status">
<?php esc_html_e('你的主题已提交审核,审核通过后会在版块中展示。', 'aksrt'); ?>
</div>
<?php endif; ?>
<div class="aksrt-forum container">
<div class="content-wrap">
<div class="content-layout content-layout--no-sidebar">
<div class="content-layout__primary">
<div class="aksrt-forum__layout">
<div class="aksrt-forum__main">
<?php if (!empty($public_home_tabs)) : ?>
<nav class="aksrt-forum-home-tabs" id="aksrt-forum-home-tabs"
data-nonce="<?php echo esc_attr($nonce); ?>"
data-ajax-url="<?php echo esc_attr(admin_url('admin-ajax.php')); ?>"
aria-label="<?php esc_attr_e('论坛内容切换', 'aksrt'); ?>">
<?php
$rendered_types = [];
foreach ($public_home_tabs as $tab) :
$tab_type = sanitize_key($tab['type'] ?? 'synthesis');
if ($tab_type === '' || isset($rendered_types[$tab_type])) {
continue;
}
// plate 由下方统一按钮渲染,避免配置重复
if ($tab_type === 'plate') {
continue;
}
$rendered_types[$tab_type] = true;
$tab_label = esc_html($tab['label'] ?? $tab_type);
$is_active = $tab_type === $active_tab_type;
?>
<button type="button"
class="aksrt-forum-home-tabs__btn<?php echo $is_active ? ' is-active' : ''; ?>"
data-tab-type="<?php echo esc_attr($tab_type); ?>">
<?php echo $tab_label; ?>
</button>
<?php endforeach; ?>
<?php if (!empty($boards)) : ?>
<button type="button"
class="aksrt-forum-home-tabs__btn<?php echo $active_tab_type === 'plate' ? ' is-active' : ''; ?>"
data-tab-type="plate">
<?php echo esc_html($name_plate); ?>
</button>
<?php endif; ?>
<?php if ($can_manage && (int) ($stats['pending_topic_count'] ?? 0) > 0) : ?>
<a class="aksrt-forum-home-tabs__btn aksrt-forum-home-tabs__btn--secondary" href="<?php echo esc_url($admin_forum_url); ?>">
<?php esc_html_e('审核', 'aksrt'); ?>
<span class="aksrt-forum-home-tabs__badge"><?php echo esc_html((string) ($stats['pending_topic_count'] ?? 0)); ?></span>
</a>
<?php endif; ?>
</nav>
<?php endif; ?>
<div class="aksrt-forum-home-content" id="aksrt-forum-home-content">
<?php if ($active_tab_type === 'plate') : ?>
<?php if (!empty($boards)) : ?>
<div class="aksrt-forum-boards__grid">
<?php foreach ($boards as $board) :
$board_id = (int) ($board['id'] ?? 0);
?>
<article class="aksrt-forum-board-card">
<a class="aksrt-forum-board-card__link" href="<?php echo esc_url((string) ($board['url'] ?? '#')); ?>">
<div class="aksrt-forum-board-card__icon">
<?php if (!empty($board['thumbnail_url'])) : ?>
<img src="<?php echo esc_url((string) $board['thumbnail_url']); ?>" alt="" width="48" height="48">
<?php else : ?>
<i class="<?php echo esc_attr((string) ($board['icon'] ?: 'fas fa-comments')); ?>"></i>
<?php endif; ?>
</div>
<div class="aksrt-forum-board-card__body">
<div class="aksrt-forum-board-card__head">
<h3 class="aksrt-forum-board-card__title"><?php echo esc_html((string) ($board['name'] ?? '')); ?></h3>
</div>
<?php if (!empty($board['description'])) : ?>
<p class="aksrt-forum-board-card__desc"><?php echo esc_html((string) $board['description']); ?></p>
<?php endif; ?>
<div class="aksrt-forum-board-card__meta">
<span><i class="fas fa-file-alt"></i> <?php echo esc_html(number_format_i18n((int) ($board['topic_count'] ?? $board['post_count'] ?? 0))); ?></span>
<span><i class="fas fa-comment"></i> <?php echo esc_html(number_format_i18n((int) ($board['reply_count'] ?? 0))); ?></span>
<span><i class="fas fa-heart"></i> <?php echo esc_html(number_format_i18n((int) ($board['follow_count'] ?? 0))); ?></span>
</div>
</div>
</a>
</article>
<?php endforeach; ?>
</div>
<?php else : ?>
<div class="aksrt-forum__empty">
<i class="fas fa-comments"></i>
<p><?php esc_html_e('当前还没有论坛版块。', 'aksrt'); ?></p>
</div>
<?php endif; ?>
<?php elseif ($active_tab_type === 'follow') : ?>
<?php
$follow_data = $forum ? $forum->get_follow_stream($current_user_id) : ['items' => []];
if (!empty($follow_data['items'])) : ?>
<div class="aksrt-forum-topics__list js-aksrt-home-topic-list">
<?php foreach ($follow_data['items'] as $topic) { $forum->render_topic_row($topic); } ?>
</div>
<?php if ($follow_data['max_pages'] > 1) : ?>
<div class="aksrt-forum-home__load-more">
<button type="button" class="aksrt-forum-replies__more-btn js-aksrt-home-load-more"
data-page="1" data-max="<?php echo esc_attr((string) $follow_data['max_pages']); ?>"
data-tab="follow">
<i class="fas fa-chevron-down"></i> <?php esc_html_e('加载更多', 'aksrt'); ?>
</button>
</div>
<?php endif; ?>
<?php elseif ($current_user_id > 0) : ?>
<div class="aksrt-forum__empty">
<i class="far fa-heart"></i>
<p><?php esc_html_e('你还没有关注任何版块,去看看有哪些版块吧!', 'aksrt'); ?></p>
</div>
<?php else : ?>
<div class="aksrt-forum__empty">
<i class="fas fa-sign-in-alt"></i>
<p><?php esc_html_e('登录后即可看到你关注的版块内容。', 'aksrt'); ?></p>
</div>
<?php endif; ?>
<?php else : /* synthesis (default) — pending 不在公开主内容区渲染 */ ?>
<?php if (!empty($recent_topics)) : ?>
<div class="aksrt-forum-topics__list js-aksrt-home-topic-list">
<?php foreach ($recent_topics as $topic) {
if ($forum) { $forum->render_topic_row($topic); }
} ?>
</div>
<?php if ($synthesis_max > 1) : ?>
<div class="aksrt-forum-home__load-more">
<button type="button" class="aksrt-forum-replies__more-btn js-aksrt-home-load-more"
data-page="1" data-max="<?php echo esc_attr((string) $synthesis_max); ?>" data-tab="synthesis">
<i class="fas fa-chevron-down"></i> <?php esc_html_e('加载更多', 'aksrt'); ?>
</button>
</div>
<?php endif; ?>
<?php else : ?>
<div class="aksrt-forum__empty">
<i class="fas fa-feather-alt"></i>
<p><?php esc_html_e('内容空空如也', 'aksrt'); ?></p>
<?php if (!empty($permissions['can_compose'])) : ?>
<a href="<?php echo esc_url($compose_url); ?>"><?php esc_html_e('发布第一个主题', 'aksrt'); ?></a>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
<aside class="aksrt-forum__sidebar">
<?php if ($quick_posts && !empty($permissions['can_compose'])) : ?>
<div class="aksrt-forum-sidebar-card aksrt-forum-sidebar-card--compose">
<a class="aksrt-forum-quick-post__input" href="<?php echo esc_url($compose_url); ?>">
<?php echo get_avatar($current_user_id, 32); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<span><?php esc_html_e('分享你的想法…', 'aksrt'); ?></span>
</a>
</div>
<?php elseif ($current_user_id <= 0) : ?>
<div class="aksrt-forum-sidebar-card aksrt-forum-sidebar-card--compose">
<a class="aksrt-forum-header__action" href="<?php echo esc_url(function_exists('aksrt_get_login_url') ? aksrt_get_login_url(get_permalink()) : wp_login_url(get_permalink())); ?>">
<i class="fas fa-sign-in-alt"></i> <?php esc_html_e('登录后发帖', 'aksrt'); ?>
</a>
</div>
<?php endif; ?>
<div class="aksrt-forum-sidebar-card">
<h3 class="aksrt-forum-sidebar-card__title">
<i class="fas fa-fire"></i>
<?php printf(esc_html__('热门%s', 'aksrt'), esc_html($name_topic)); ?>
</h3>
<?php if (!empty($hot_topics)) : ?>
<ul class="aksrt-forum-sidebar-card__list">
<?php foreach ($hot_topics as $index => $topic) : ?>
<li class="aksrt-forum-sidebar-card__item">
<span class="aksrt-forum-sidebar-card__rank"><?php echo esc_html((string) ($index + 1)); ?></span>
<a href="<?php echo esc_url((string) ($topic['permalink'] ?? '#')); ?>" class="aksrt-forum-sidebar-card__link">
<?php echo esc_html((string) ($topic['title'] ?? '')); ?>
</a>
<span class="aksrt-forum-sidebar-card__views"><?php echo esc_html(number_format_i18n((int) ($topic['views'] ?? 0))); ?></span>
</li>
<?php endforeach; ?>
</ul>
<?php else : ?>
<p class="aksrt-forum-sidebar-card__empty"><?php esc_html_e('暂无热门主题', 'aksrt'); ?></p>
<?php endif; ?>
</div>
<?php if (!empty($boards)) : ?>
<div class="aksrt-forum-sidebar-card">
<h3 class="aksrt-forum-sidebar-card__title">
<i class="fas fa-th-list"></i>
<?php echo esc_html($name_plate); ?>
</h3>
<ul class="aksrt-forum-sidebar-card__list">
<?php foreach (array_slice($boards, 0, 8) as $board) : ?>
<li class="aksrt-forum-sidebar-card__item">
<a href="<?php echo esc_url((string) ($board['url'] ?? '#')); ?>" class="aksrt-forum-sidebar-card__link">
<?php echo esc_html((string) ($board['name'] ?? '')); ?>
</a>
<span class="aksrt-forum-sidebar-card__views"><?php echo esc_html(number_format_i18n((int) ($board['topic_count'] ?? $board['post_count'] ?? 0))); ?></span>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<?php if ($can_manage && !empty($applications)) : ?>
<div class="aksrt-forum-sidebar-card">
<h3 class="aksrt-forum-sidebar-card__title">
<i class="fas fa-shield-alt"></i>
<?php esc_html_e('版主申请状态', 'aksrt'); ?>
</h3>
<ul class="aksrt-forum-sidebar-card__list aksrt-forum-sidebar-card__list--applications">
<?php foreach ($applications as $board_id => $application) :
if (!$application) continue;
$board_name = '';
foreach ($boards as $board) {
if ((int) ($board['id'] ?? 0) === (int) $board_id) {
$board_name = (string) ($board['name'] ?? '');
break;
}
}
?>
<li class="aksrt-forum-sidebar-card__item aksrt-forum-sidebar-card__item--stack">
<strong><?php echo esc_html($board_name); ?></strong>
<span><?php echo esc_html((string) ($application['status_label'] ?? '')); ?></span>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
</aside>
</div>
</div>
</div>
</div>
</div>
</main>
<?php get_footer(); ?>