feat(forum): add complete forum workflows
This commit is contained in:
1 parent
a254cbd3e9
commit
ee65fc7fd2
39 files changed
+3425
-4
No files matched your search
@@ -0,0 +1,387 @@
|
||||
<?php
|
||||
|
||||
namespace Jio\Forum;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
final class View {
|
||||
public static function open(string $title, string $context): void {
|
||||
get_header();
|
||||
echo '<main id="forum" class="jio-forum jio-forum--' . esc_attr($context) . '"><div class="jio-forum__wrap">';
|
||||
echo '<nav class="jio-forum__breadcrumbs" aria-label="路径"><a href="' . esc_url(home_url('/')) . '">首页</a><span>/</span><a href="' . esc_url(Core::home_url()) . '">论坛</a>';
|
||||
if ($context !== 'home') {
|
||||
echo '<span>/</span><span>' . esc_html($title) . '</span>';
|
||||
}
|
||||
echo '</nav>';
|
||||
}
|
||||
|
||||
public static function close(): void {
|
||||
echo '</div></main>';
|
||||
get_footer();
|
||||
}
|
||||
|
||||
public static function sidebar(string $context): void {
|
||||
echo '<aside class="jio-forum__aside">';
|
||||
if (is_user_logged_in()) {
|
||||
echo '<a class="jio-forum__new" href="' . esc_url(Core::edit_url()) . '">发布帖子</a>';
|
||||
if ($context === 'home' && jio_get_setting('jio_forum_user_plates', true)) {
|
||||
echo '<button type="button" class="jio-forum__action jio-forum__create-plate" data-forum-open="plate">创建版块</button>';
|
||||
echo '<dialog class="jio-forum__dialog" data-forum-dialog="plate"><form data-forum-form="plate"><h2>创建版块</h2><label>名称<input name="title" required maxlength="80"></label><label>介绍<textarea name="content" rows="5"></textarea></label><p class="jio-forum__message" role="status"></p><div class="jio-forum__dialog-actions"><button type="button" data-forum-close>取消</button><button type="submit" class="jio-forum__primary">提交</button></div></form></dialog>';
|
||||
}
|
||||
} else {
|
||||
echo '<a class="jio-forum__new" href="' . esc_url(jio_get_login_url(Core::edit_url())) . '">登录后发帖</a>';
|
||||
}
|
||||
\Jio\WidgetSystem\WidgetAreas::render('forum_' . $context . '_sidebar');
|
||||
$plates = get_posts(['post_type' => Core::PLATE, 'post_status' => 'publish', 'posts_per_page' => 8, 'orderby' => 'date']);
|
||||
if ($plates) {
|
||||
echo '<section class="jio-forum__aside-section"><h2>热门版块</h2>';
|
||||
foreach ($plates as $plate) {
|
||||
echo '<a href="' . esc_url(get_permalink($plate)) . '">' . esc_html($plate->post_title) . '</a>';
|
||||
}
|
||||
echo '</section>';
|
||||
}
|
||||
echo '</aside>';
|
||||
}
|
||||
|
||||
public static function home(): void {
|
||||
self::open('论坛', 'home');
|
||||
\Jio\WidgetSystem\WidgetAreas::render('forum_home_top_fluid');
|
||||
echo '<div class="jio-forum__layout"><div class="jio-forum__main">';
|
||||
$name = (string) jio_get_setting('jio_forum_forum_name', '论坛');
|
||||
echo '<header class="jio-forum__hero"><h1>' . esc_html($name) . '</h1></header>';
|
||||
if (Access::is_admin(get_current_user_id())) {
|
||||
$pending = get_posts(['post_type' => Core::PLATE, 'post_status' => 'pending', 'posts_per_page' => 20]);
|
||||
if ($pending) {
|
||||
echo '<section class="jio-forum__pending"><h2>待审核版块</h2>';
|
||||
foreach ($pending as $plate) {
|
||||
echo '<div><span>' . esc_html($plate->post_title) . '</span><button type="button" data-forum-action="plate-audit" data-id="' . (int) $plate->ID . '">通过审核</button></div>';
|
||||
}
|
||||
echo '</section>';
|
||||
}
|
||||
self::term_management();
|
||||
}
|
||||
self::tabs();
|
||||
$categories = get_terms(['taxonomy' => Core::CATEGORY, 'hide_empty' => false]);
|
||||
if (is_array($categories) && $categories) {
|
||||
echo '<div class="jio-forum__chips">';
|
||||
foreach ($categories as $category) {
|
||||
echo '<a href="' . esc_url(get_term_link($category)) . '">' . esc_html($category->name) . '</a>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
self::posts(['post_type' => Core::POST, 'post_status' => 'publish'], 'home');
|
||||
echo '</div>';
|
||||
self::sidebar('home');
|
||||
echo '</div>';
|
||||
\Jio\WidgetSystem\WidgetAreas::render('forum_home_bottom_fluid');
|
||||
self::close();
|
||||
}
|
||||
|
||||
public static function listing(): void {
|
||||
$obj = get_queried_object();
|
||||
$plate = $obj instanceof \WP_Post && $obj->post_type === Core::PLATE ? $obj : null;
|
||||
$term = $obj instanceof \WP_Term ? $obj : null;
|
||||
$title = $plate ? $plate->post_title : ($term ? $term->name : '论坛');
|
||||
$context = $plate ? 'plate' : 'term';
|
||||
self::open($title, $context);
|
||||
\Jio\WidgetSystem\WidgetAreas::render('forum_' . $context . '_top_fluid');
|
||||
echo '<div class="jio-forum__layout"><div class="jio-forum__main">';
|
||||
echo '<header class="jio-forum__page-head"><h1>' . esc_html($title) . '</h1>';
|
||||
if ($plate) {
|
||||
echo '<div class="jio-forum__description">' . wp_kses_post(wpautop($plate->post_excerpt ?: $plate->post_content)) . '</div>';
|
||||
echo '<p class="jio-forum__stats">' . (int) get_post_meta($plate->ID, '_jio_forum_follow_count', true) . ' 人关注</p>';
|
||||
self::action('follow', $plate->ID, Access::follows(get_current_user_id(), $plate->ID) ? '已关注' : '关注版块');
|
||||
if (Access::is_moderator(get_current_user_id(), $plate->ID)) {
|
||||
self::plate_editor($plate);
|
||||
}
|
||||
if (is_user_logged_in() && !Access::is_moderator(get_current_user_id(), $plate->ID) && jio_get_setting('jio_forum_moderator_apply', true)) {
|
||||
self::action('apply', $plate->ID, '申请版主');
|
||||
}
|
||||
if (Access::is_admin(get_current_user_id()) || (int) $plate->post_author === get_current_user_id()) {
|
||||
self::applications($plate->ID);
|
||||
}
|
||||
} elseif ($term) {
|
||||
echo '<p>' . esc_html($term->description) . '</p>';
|
||||
}
|
||||
echo '</header>';
|
||||
self::tabs();
|
||||
if ($term && $term->taxonomy === Core::CATEGORY) {
|
||||
self::plates(['tax_query' => [['taxonomy' => Core::CATEGORY, 'terms' => [$term->term_id]]]]);
|
||||
} else {
|
||||
$args = ['post_type' => Core::POST, 'post_status' => 'publish'];
|
||||
if ($plate) {
|
||||
$args['meta_query'] = [['key' => '_jio_forum_plate_id', 'value' => $plate->ID]];
|
||||
} elseif ($term) {
|
||||
$args['tax_query'] = [['taxonomy' => $term->taxonomy, 'terms' => [$term->term_id]]];
|
||||
}
|
||||
self::posts($args, $context);
|
||||
if ($plate && Access::is_moderator(get_current_user_id(), $plate->ID)) {
|
||||
echo '<h2 class="jio-forum__section-title">待审核帖子</h2>';
|
||||
$args['post_status'] = 'pending';
|
||||
self::posts($args, $context);
|
||||
}
|
||||
}
|
||||
echo '</div>';
|
||||
self::sidebar($context);
|
||||
echo '</div>';
|
||||
\Jio\WidgetSystem\WidgetAreas::render('forum_' . $context . '_bottom_fluid');
|
||||
self::close();
|
||||
}
|
||||
|
||||
public static function tabs(): void {
|
||||
$tabs = ['latest' => '最新', 'popular' => '热门', 'essence' => '精华', 'question' => '问答', 'vote' => '投票', 'plates' => '版块', 'follow' => '已关注'];
|
||||
$enabled = (array) jio_get_setting('jio_forum_home_tabs', array_keys($tabs));
|
||||
$base_url = is_singular(Core::PLATE) ? get_permalink(get_queried_object_id()) : (is_tax([Core::CATEGORY, Core::TOPIC, Core::TAG]) ? get_term_link(get_queried_object()) : Core::home_url());
|
||||
echo '<nav class="jio-forum__tabs" aria-label="论坛栏目">';
|
||||
foreach ($tabs as $key => $label) {
|
||||
if (!in_array($key, $enabled, true)) continue;
|
||||
if ($key === 'follow' && !is_user_logged_in()) continue;
|
||||
$url = add_query_arg('forum_view', $key, $base_url);
|
||||
$selected = (string) ($_GET['forum_view'] ?? 'latest') === $key;
|
||||
echo '<a class="' . ($selected ? 'is-active' : '') . '" href="' . esc_url($url) . '">' . esc_html($label) . '</a>';
|
||||
}
|
||||
echo '</nav>';
|
||||
}
|
||||
|
||||
public static function posts(array $args, string $context = 'home'): void {
|
||||
$view = sanitize_key((string) ($_GET['forum_view'] ?? 'latest'));
|
||||
if ($view === 'plates') {
|
||||
self::plates([]);
|
||||
return;
|
||||
}
|
||||
if ($view === 'follow') {
|
||||
$ids = self::user_marked_ids(get_current_user_id(), '_jio_forum_follow_');
|
||||
$args['meta_query'][] = ['key' => '_jio_forum_plate_id', 'value' => $ids ?: [0], 'compare' => 'IN'];
|
||||
}
|
||||
if (in_array($view, ['question', 'vote'], true)) {
|
||||
$args['meta_query'][] = ['key' => '_jio_forum_type', 'value' => $view];
|
||||
}
|
||||
if ($view === 'essence') {
|
||||
$args['meta_query'][] = ['key' => '_jio_forum_essence', 'value' => 1];
|
||||
}
|
||||
$args['posts_per_page'] = max(1, min(50, (int) jio_get_setting('jio_forum_page_size', 20)));
|
||||
$args['paged'] = max(1, (int) get_query_var('paged', 1));
|
||||
$args['orderby'] = 'date';
|
||||
$args['order'] = 'DESC';
|
||||
$args['jio_forum_list'] = in_array($view, ['latest', 'popular', 'question', 'vote', 'essence', 'follow'], true) ? $view : 'latest';
|
||||
$query = new \WP_Query($args);
|
||||
\Jio\WidgetSystem\WidgetAreas::render('forum_' . $context . '_top_content');
|
||||
echo '<div class="jio-forum__list">';
|
||||
if (!$query->have_posts()) {
|
||||
echo '<p class="jio-forum__empty">暂无帖子</p>';
|
||||
}
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
self::post_card(get_post());
|
||||
}
|
||||
wp_reset_postdata();
|
||||
echo '</div>';
|
||||
self::pagination($query);
|
||||
\Jio\WidgetSystem\WidgetAreas::render('forum_' . $context . '_bottom_content');
|
||||
}
|
||||
|
||||
public static function plates(array $args): void {
|
||||
$query = new \WP_Query(array_merge(['post_type' => Core::PLATE, 'post_status' => 'publish', 'posts_per_page' => 20], $args));
|
||||
echo '<div class="jio-forum__plates">';
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
$plate = get_post();
|
||||
self::plate_card($plate);
|
||||
}
|
||||
wp_reset_postdata();
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
public static function plate_card(\WP_Post $plate): void {
|
||||
$url = get_permalink($plate);
|
||||
echo '<article class="jio-forum__plate"><a class="jio-forum__plate-cover" href="' . esc_url($url) . '">';
|
||||
if (jio_get_setting('jio_forum_show_plate_cover', true) && has_post_thumbnail($plate)) {
|
||||
echo get_the_post_thumbnail($plate, 'jio-card');
|
||||
}
|
||||
echo '</a><div><h2><a href="' . esc_url($url) . '">' . esc_html($plate->post_title) . '</a></h2><p>' . esc_html(wp_trim_words(wp_strip_all_tags($plate->post_excerpt ?: $plate->post_content), 22)) . '</p><small>' . (int) get_post_meta($plate->ID, '_jio_forum_follow_count', true) . ' 人关注</small></div></article>';
|
||||
}
|
||||
|
||||
public static function post_card(\WP_Post $post): void {
|
||||
$plate_id = (int) get_post_meta($post->ID, '_jio_forum_plate_id', true);
|
||||
$type = (string) get_post_meta($post->ID, '_jio_forum_type', true);
|
||||
echo '<article class="jio-forum__post"><a class="jio-forum__avatar" href="' . esc_url(get_author_posts_url((int) $post->post_author)) . '">' . get_avatar((int) $post->post_author, 44) . '</a><div class="jio-forum__post-body">';
|
||||
echo '<div class="jio-forum__post-top"><span>' . esc_html(get_the_author_meta('display_name', (int) $post->post_author)) . '</span><time datetime="' . esc_attr(get_the_date(DATE_W3C, $post)) . '">' . esc_html(get_the_date('', $post)) . '</time></div>';
|
||||
$url = $post->post_status === 'publish' ? get_permalink($post) : Core::edit_url($post->ID);
|
||||
echo '<h2><a href="' . esc_url($url) . '">' . esc_html($post->post_title) . '</a></h2>';
|
||||
$excerpt = Access::can_view(get_current_user_id(), $post->ID) ? wp_trim_words(wp_strip_all_tags($post->post_excerpt ?: $post->post_content), 30) : '内容已隐藏';
|
||||
echo '<p>' . esc_html($excerpt) . '</p>';
|
||||
echo '<div class="jio-forum__post-meta">';
|
||||
if (get_post_meta($post->ID, '_jio_forum_pinned', true)) {
|
||||
echo '<span class="jio-forum__badge">置顶</span>';
|
||||
}
|
||||
if ($type !== '') {
|
||||
echo '<span class="jio-forum__badge">' . esc_html($type === 'question' ? '问答' : '投票') . '</span>';
|
||||
}
|
||||
if ($type === 'question' && get_post_meta($post->ID, '_jio_forum_adopted_comment', true)) {
|
||||
echo '<span class="jio-forum__badge">已解决</span>';
|
||||
}
|
||||
if (get_post_meta($post->ID, '_jio_forum_essence', true)) {
|
||||
echo '<span class="jio-forum__badge">精华</span>';
|
||||
}
|
||||
if ($plate_id > 0) {
|
||||
echo '<a href="' . esc_url(get_permalink($plate_id)) . '">' . esc_html(get_the_title($plate_id)) . '</a>';
|
||||
}
|
||||
echo '<span>' . (int) get_post_meta($post->ID, '_jio_forum_views', true) . ' 阅读</span>';
|
||||
echo '<span>' . (int) $post->comment_count . ' 回复</span>';
|
||||
echo '<span>' . (int) get_post_meta($post->ID, '_jio_forum_score', true) . ' 评分</span>';
|
||||
echo '<span>' . (int) get_post_meta($post->ID, '_jio_forum_favorite_count', true) . ' 收藏</span></div></div></article>';
|
||||
$hot = get_comments(['post_id' => $post->ID, 'status' => 'approve', 'number' => 1, 'meta_key' => '_jio_forum_hot', 'meta_value' => '1']);
|
||||
if ($hot) {
|
||||
echo '<div class="jio-forum__hot-reply">热门回复:' . esc_html(wp_trim_words(wp_strip_all_tags($hot[0]->comment_content), 25)) . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
public static function replies(int $post_id): void {
|
||||
$page = max(1, (int) ($_GET['cpage'] ?? 1));
|
||||
$limit = max(1, min(100, (int) jio_get_setting('jio_forum_reply_page_size', 20)));
|
||||
$comments = get_comments(['post_id' => $post_id, 'status' => 'approve', 'number' => $limit, 'offset' => ($page - 1) * $limit, 'orderby' => 'comment_date_gmt', 'order' => 'ASC']);
|
||||
$total = (int) get_comments(['post_id' => $post_id, 'status' => 'approve', 'count' => true]);
|
||||
echo '<section class="jio-forum__replies" id="comments"><h2>回复 <small>' . $total . '</small></h2>';
|
||||
if (!$comments) echo '<p class="jio-forum__empty">暂无回复</p>';
|
||||
foreach ($comments as $comment) {
|
||||
$adopted = (bool) get_comment_meta($comment->comment_ID, '_jio_forum_adopted', true);
|
||||
$hot = (bool) get_comment_meta($comment->comment_ID, '_jio_forum_hot', true);
|
||||
echo '<article class="jio-forum__reply" id="comment-' . (int) $comment->comment_ID . '"><div class="jio-forum__reply-avatar">' . get_avatar((int) $comment->user_id, 40) . '</div><div class="jio-forum__reply-main"><div class="jio-forum__reply-head"><b>' . esc_html(get_comment_author($comment)) . '</b><time>' . esc_html(get_comment_date('', $comment)) . '</time>' . ($adopted ? '<strong>已采纳</strong>' : '') . '</div>';
|
||||
if ($hot) echo '<span class="jio-forum__badge">热门回复</span>';
|
||||
if ((int) $comment->comment_parent > 0) {
|
||||
$parent = get_comment((int) $comment->comment_parent);
|
||||
if ($parent instanceof \WP_Comment) echo '<p class="jio-forum__reply-parent">回复 @' . esc_html(get_comment_author($parent)) . '</p>';
|
||||
}
|
||||
echo '<div class="jio-forum__reply-text">' . wp_kses_post(wpautop($comment->comment_content)) . '</div><div class="jio-forum__reply-actions">';
|
||||
if (is_user_logged_in()) echo '<button type="button" data-forum-action="reply-like" data-id="' . (int) $comment->comment_ID . '">赞 ' . (int) get_comment_meta($comment->comment_ID, 'jio_comment_likes', true) . '</button>';
|
||||
if (is_user_logged_in() && ((int) $comment->user_id === get_current_user_id() || Access::is_moderator(get_current_user_id(), (int) get_post_meta($post_id, '_jio_forum_plate_id', true)))) echo '<button type="button" data-forum-action="reply-delete" data-id="' . (int) $comment->comment_ID . '">删除</button>';
|
||||
if (Access::is_moderator(get_current_user_id(), (int) get_post_meta($post_id, '_jio_forum_plate_id', true))) echo '<button type="button" data-forum-action="reply-hot" data-id="' . (int) $comment->comment_ID . '">' . ($hot ? '取消热门' : '设为热门') . '</button>';
|
||||
if (is_user_logged_in()) echo '<button type="button" data-forum-reply-to="' . (int) $comment->comment_ID . '">回复</button>';
|
||||
if (get_post_meta($post_id, '_jio_forum_type', true) === 'question' && !get_post_meta($post_id, '_jio_forum_adopted_comment', true) && Access::can_manage_post(get_current_user_id(), $post_id)) {
|
||||
echo '<button type="button" data-forum-action="adopt" data-id="' . $post_id . '" data-comment-id="' . (int) $comment->comment_ID . '">采纳</button>';
|
||||
}
|
||||
echo '</div></div></article>';
|
||||
}
|
||||
if ($total > $limit) {
|
||||
$links = paginate_links(['base' => add_query_arg('cpage', '%#%', get_permalink($post_id)), 'current' => $page, 'total' => (int) ceil($total / $limit), 'type' => 'list']);
|
||||
echo '<nav class="jio-forum__pagination" aria-label="回复分页">' . wp_kses_post((string) $links) . '</nav>';
|
||||
}
|
||||
if (get_post_field('comment_status', $post_id) === 'open') {
|
||||
if (is_user_logged_in()) {
|
||||
echo '<form class="jio-forum__reply-form" data-forum-form="reply" data-id="' . $post_id . '"><h3>发表回复</h3><input type="hidden" name="parent_id" value="0"><textarea name="content" required rows="5" placeholder="写下你的回复"></textarea><p class="jio-forum__message" role="status"></p><button type="submit" class="jio-forum__primary">提交回复</button></form>';
|
||||
} else {
|
||||
echo '<p><a href="' . esc_url(jio_get_login_url(get_permalink($post_id))) . '">登录后回复</a></p>';
|
||||
}
|
||||
} else {
|
||||
echo '<p class="jio-forum__empty">回复已关闭</p>';
|
||||
}
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
private static function term_management(): void {
|
||||
echo '<section class="jio-forum__term-management"><h2>分类与话题</h2><form data-forum-form="term"><label>类型<select name="type"><option value="category">版块分类</option><option value="topic">论坛话题</option><option value="tag">论坛标签</option></select></label><label>名称<input name="name" required maxlength="60"></label><p class="jio-forum__message" role="status"></p><button type="submit" class="jio-forum__action">添加</button></form>';
|
||||
foreach (['category' => Core::CATEGORY, 'topic' => Core::TOPIC, 'tag' => Core::TAG] as $label => $taxonomy) {
|
||||
$terms = get_terms(['taxonomy' => $taxonomy, 'hide_empty' => false, 'number' => 30]);
|
||||
if (!is_array($terms)) continue;
|
||||
foreach ($terms as $term) {
|
||||
echo '<div class="jio-forum__term-row"><span>' . esc_html($term->name) . '</span><button type="button" data-forum-action="term-edit" data-id="' . (int) $term->term_id . '">编辑</button><button type="button" data-forum-action="term-delete" data-id="' . (int) $term->term_id . '">删除</button></div>';
|
||||
}
|
||||
}
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
private static function plate_editor(\WP_Post $plate): void {
|
||||
$id = $plate->ID;
|
||||
echo '<button type="button" class="jio-forum__action" data-forum-open="plate-edit-' . $id . '">编辑版块</button>';
|
||||
echo '<button type="button" class="jio-forum__action" data-forum-action="plate-delete" data-id="' . $id . '">删除版块</button>';
|
||||
echo '<dialog class="jio-forum__dialog" data-forum-dialog="plate-edit-' . $id . '"><form data-forum-form="plate" data-id="' . $id . '"><h2>编辑版块</h2>';
|
||||
echo '<label>名称<input name="title" required value="' . esc_attr($plate->post_title) . '"></label>';
|
||||
echo '<label>介绍<textarea name="content" rows="5">' . esc_textarea($plate->post_content) . '</textarea></label>';
|
||||
echo '<label>发帖权限<select name="publish_limit"><option value="all">所有用户</option><option value="follow"' . selected(get_post_meta($id, '_jio_forum_publish_limit', true), 'follow', false) . '>已关注用户</option></select></label>';
|
||||
echo '<label>关注方式<select name="follow_mode"><option value="all">免费</option><option value="points"' . selected(get_post_meta($id, '_jio_forum_follow_mode', true), 'points', false) . '>积分</option><option value="pay"' . selected(get_post_meta($id, '_jio_forum_follow_mode', true), 'pay', false) . '>付费</option></select></label>';
|
||||
echo '<label>关注价格<input name="follow_price" type="number" min="0" step="0.01" value="' . esc_attr((string) get_post_meta($id, '_jio_forum_follow_price', true)) . '"></label>';
|
||||
echo '<label>会员一级价格<input name="follow_price_vip1" type="number" min="0" step="0.01" value="' . esc_attr((string) get_post_meta($id, '_jio_forum_follow_price_vip1', true)) . '"></label>';
|
||||
echo '<label>会员二级价格<input name="follow_price_vip2" type="number" min="0" step="0.01" value="' . esc_attr((string) get_post_meta($id, '_jio_forum_follow_price_vip2', true)) . '"></label>';
|
||||
echo '<label>阅读权限<select name="view_limit">';
|
||||
foreach (['all' => '所有人', 'login' => '登录后', 'follow' => '关注后', 'points' => '积分解锁', 'pay' => '付费解锁'] as $key => $label) {
|
||||
echo '<option value="' . esc_attr($key) . '"' . selected(get_post_meta($id, '_jio_forum_view_limit', true), $key, false) . '>' . esc_html($label) . '</option>';
|
||||
}
|
||||
echo '</select></label><p class="jio-forum__message" role="status"></p><div class="jio-forum__dialog-actions"><button type="button" data-forum-close>取消</button><button type="submit" class="jio-forum__primary">保存</button></div></form></dialog>';
|
||||
}
|
||||
|
||||
private static function applications(int $plate_id): void {
|
||||
$users = get_users(['meta_key' => '_jio_forum_application_' . $plate_id, 'meta_value' => 'pending', 'number' => 20]);
|
||||
echo '<section class="jio-forum__applications"><h2>版主管理</h2>';
|
||||
$moderators = array_map('absint', (array) get_post_meta($plate_id, '_jio_forum_moderators', true));
|
||||
foreach ($moderators as $user_id) {
|
||||
$user = get_userdata($user_id);
|
||||
if ($user) echo '<div class="jio-forum__application"><span>' . esc_html($user->display_name) . '</span><button type="button" data-forum-action="moderator-remove" data-id="' . $plate_id . '" data-user-id="' . $user_id . '">移除</button></div>';
|
||||
}
|
||||
echo '<form data-forum-form="moderator" data-id="' . $plate_id . '"><label>用户 ID<input name="user_id" type="number" min="1" required></label><p class="jio-forum__message" role="status"></p><button type="submit" class="jio-forum__action">添加版主</button></form>';
|
||||
if ($users) echo '<h3>待处理申请</h3>';
|
||||
foreach ($users as $user) {
|
||||
echo '<div class="jio-forum__application"><span>' . esc_html($user->display_name) . '</span><button type="button" data-forum-action="application" data-id="' . $plate_id . '" data-user-id="' . (int) $user->ID . '" data-status="approved">通过</button><button type="button" data-forum-action="application" data-id="' . $plate_id . '" data-user-id="' . (int) $user->ID . '" data-status="rejected">拒绝</button></div>';
|
||||
}
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
public static function pagination(\WP_Query $query): void {
|
||||
if ($query->max_num_pages <= 1) {
|
||||
return;
|
||||
}
|
||||
echo '<nav class="jio-forum__pagination" aria-label="分页">' . wp_kses_post(paginate_links(['total' => $query->max_num_pages, 'current' => max(1, (int) get_query_var('paged', 1)), 'type' => 'list'])) . '</nav>';
|
||||
}
|
||||
|
||||
public static function action(string $action, int $id, string $label): void {
|
||||
echo '<button type="button" class="jio-forum__action" data-forum-action="' . esc_attr($action) . '" data-id="' . esc_attr((string) $id) . '">' . esc_html($label) . '</button>';
|
||||
}
|
||||
|
||||
public static function user_marked_ids(int $user_id, string $prefix): array {
|
||||
if ($user_id <= 0) return [];
|
||||
$ids = [];
|
||||
foreach (get_user_meta($user_id) as $key => $values) {
|
||||
if (str_starts_with((string) $key, $prefix) && !empty($values[0])) {
|
||||
$id = absint(substr((string) $key, strlen($prefix)));
|
||||
if ($id) $ids[] = $id;
|
||||
}
|
||||
}
|
||||
return array_values(array_unique($ids));
|
||||
}
|
||||
|
||||
public static function user_panel(int $user_id, bool $owner): void {
|
||||
$tab = sanitize_key((string) ($_GET['forum_tab'] ?? 'posts'));
|
||||
$tabs = ['posts' => '帖子', 'plates' => '版块'];
|
||||
if ($owner) $tabs += ['favorites' => '收藏', 'follow' => '关注'];
|
||||
if (!isset($tabs[$tab])) $tab = 'posts';
|
||||
echo '<div id="forum" class="jio-forum jio-forum__user-panel"><nav class="jio-forum__tabs" aria-label="论坛内容">';
|
||||
foreach ($tabs as $key => $label) {
|
||||
echo '<a class="' . ($tab === $key ? 'is-active' : '') . '" href="' . esc_url(add_query_arg('forum_tab', $key)) . '">' . esc_html($label) . '</a>';
|
||||
}
|
||||
echo '</nav>';
|
||||
if ($owner) echo '<p><a class="jio-forum__primary" href="' . esc_url(Core::edit_url()) . '">发布帖子</a></p>';
|
||||
$args = ['post_status' => $owner ? ['publish', 'pending'] : 'publish', 'posts_per_page' => 20];
|
||||
if ($tab === 'posts' || $tab === 'plates') {
|
||||
$args['post_type'] = $tab === 'posts' ? Core::POST : Core::PLATE;
|
||||
$args['author'] = $user_id;
|
||||
} else {
|
||||
$args['post_type'] = $tab === 'favorites' ? Core::POST : Core::PLATE;
|
||||
$ids = self::user_marked_ids($user_id, $tab === 'favorites' ? '_jio_forum_favorite_' : '_jio_forum_follow_');
|
||||
$args['post__in'] = $ids ?: [0];
|
||||
}
|
||||
$query = new \WP_Query($args);
|
||||
echo '<div class="jio-forum__list">';
|
||||
if (!$query->have_posts()) echo '<p class="jio-forum__empty">暂无内容</p>';
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
$post = get_post();
|
||||
if ($post->post_type === Core::POST) self::post_card($post);
|
||||
else {
|
||||
$url = $post->post_status === 'publish' ? get_permalink($post) : '';
|
||||
echo '<div class="jio-forum__user-row">' . ($url ? '<a href="' . esc_url($url) . '">' : '<span>') . esc_html($post->post_title) . ($url ? '</a>' : '</span>') . ($url ? '' : '<small>待审核</small>') . '</div>';
|
||||
if ($owner && !$url) self::plate_editor($post);
|
||||
}
|
||||
}
|
||||
wp_reset_postdata();
|
||||
echo '</div></div>';
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user