feat(forum): plate info follow/compose + mods grid + board depth
Sidebar plate widgets gain follow/compose actions, super-mod roles, board list sorting/styles, and matching CSS polish.
This commit is contained in:
@@ -22,45 +22,65 @@ class WidgetForumPlateModerator extends \WP_Widget {
|
||||
);
|
||||
}
|
||||
|
||||
public function widget($args, $instance): void {
|
||||
$plate = $this->resolve_current_plate();
|
||||
/**
|
||||
* @return array{html:string}
|
||||
*/
|
||||
public static function render_payload(array $instance, ?\WP_Post $plate = null): array {
|
||||
$plate = $plate ?: WidgetForumPlateInfo::resolve_current_plate_static();
|
||||
if (!$plate) {
|
||||
return;
|
||||
return ['html' => ''];
|
||||
}
|
||||
|
||||
$id = (int) $plate->ID;
|
||||
$id = (int) $plate->ID;
|
||||
$author_id = (int) $plate->post_author;
|
||||
$mods = get_post_meta($id, '_aksrt_moderators', true);
|
||||
$mods = get_post_meta($id, '_aksrt_moderators', true);
|
||||
if (!is_array($mods)) {
|
||||
$mods = [];
|
||||
}
|
||||
$mods = array_values(array_unique(array_filter(array_map('intval', $mods))));
|
||||
|
||||
// Super-mods meta (zibll-like).
|
||||
$super = get_post_meta($id, '_aksrt_super_moderators', true);
|
||||
if (!is_array($super)) {
|
||||
$super = [];
|
||||
}
|
||||
$super = array_values(array_unique(array_filter(array_map('intval', $super))));
|
||||
|
||||
$people = [];
|
||||
if ($author_id > 0) {
|
||||
$people[] = ['id' => $author_id, 'role' => 'author'];
|
||||
}
|
||||
foreach ($super as $sid) {
|
||||
if ($sid === $author_id) {
|
||||
continue;
|
||||
}
|
||||
$people[] = ['id' => $sid, 'role' => 'super'];
|
||||
}
|
||||
foreach ($mods as $mid) {
|
||||
if ($mid === $author_id) {
|
||||
if ($mid === $author_id || in_array($mid, $super, true)) {
|
||||
continue;
|
||||
}
|
||||
$people[] = ['id' => $mid, 'role' => 'moderator'];
|
||||
}
|
||||
if (!$people) {
|
||||
return;
|
||||
return ['html' => ''];
|
||||
}
|
||||
|
||||
$title_text = (string) ($instance['title_text'] ?? __('版主', 'aksrt'));
|
||||
$title_text = (string) ($instance['title_text'] ?? __('版主', 'aksrt'));
|
||||
$show_avatar = !isset($instance['show_avatar']) || !empty($instance['show_avatar']);
|
||||
$style = sanitize_key((string) ($instance['style'] ?? 'list'));
|
||||
if (!in_array($style, ['list', 'grid'], true)) {
|
||||
$style = 'list';
|
||||
}
|
||||
|
||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
|
||||
echo '<div class="aksrt-plate-mods">';
|
||||
ob_start();
|
||||
echo '<div class="aksrt-plate-mods style-' . esc_attr($style) . ' ajax-item">';
|
||||
if ($title_text !== '') {
|
||||
echo '<div class="aksrt-plate-mods__head"><div class="title-theme">' . esc_html($title_text) . '</div></div>';
|
||||
}
|
||||
echo '<div class="aksrt-plate-mods__list">';
|
||||
foreach ($people as $row) {
|
||||
$uid = (int) $row['id'];
|
||||
$uid = (int) $row['id'];
|
||||
$user = get_userdata($uid);
|
||||
if (!$user) {
|
||||
continue;
|
||||
@@ -71,61 +91,66 @@ class WidgetForumPlateModerator extends \WP_Widget {
|
||||
$home = function_exists('aksrt_get_user_home_url')
|
||||
? aksrt_get_user_home_url($uid)
|
||||
: get_author_posts_url($uid);
|
||||
$role_label = $row['role'] === 'author'
|
||||
? __('超级版主', 'aksrt')
|
||||
: __('版主', 'aksrt');
|
||||
echo '<a class="aksrt-plate-mods__item" href="' . esc_url($home) . '">';
|
||||
echo '<img src="' . esc_url($avatar) . '" alt="" class="aksrt-plate-mods__avatar" loading="lazy" width="40" height="40" />';
|
||||
if ($row['role'] === 'author' || $row['role'] === 'super') {
|
||||
$role_label = __('超级版主', 'aksrt');
|
||||
} else {
|
||||
$role_label = __('版主', 'aksrt');
|
||||
}
|
||||
echo '<a class="aksrt-plate-mods__item role-' . esc_attr($row['role']) . '" href="' . esc_url($home) . '">';
|
||||
if ($show_avatar) {
|
||||
echo '<img src="' . esc_url($avatar) . '" alt="" class="aksrt-plate-mods__avatar" loading="lazy" width="40" height="40" />';
|
||||
}
|
||||
echo '<span class="aksrt-plate-mods__name">' . esc_html($user->display_name) . '</span>';
|
||||
echo '<span class="aksrt-plate-mods__role">' . esc_html($role_label) . '</span>';
|
||||
echo '</a>';
|
||||
}
|
||||
echo '</div></div>';
|
||||
|
||||
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
return ['html' => (string) ob_get_clean()];
|
||||
}
|
||||
|
||||
private function resolve_current_plate(): ?\WP_Post {
|
||||
if (is_singular('aksrt_forum_plate')) {
|
||||
$p = get_queried_object();
|
||||
return $p instanceof \WP_Post ? $p : null;
|
||||
public function widget($args, $instance): void {
|
||||
$payload = self::render_payload($instance);
|
||||
if ($payload['html'] === '') {
|
||||
return;
|
||||
}
|
||||
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);
|
||||
if ($plate_id <= 0) {
|
||||
$boards = get_the_terms($topic_id, 'aksrt_forum_board');
|
||||
if (!is_wp_error($boards) && !empty($boards[0])) {
|
||||
$linked = (int) get_term_meta((int) $boards[0]->term_id, '_aksrt_plate_id', true);
|
||||
if ($linked > 0) {
|
||||
$plate_id = $linked;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($plate_id > 0) {
|
||||
$p = get_post($plate_id);
|
||||
if ($p instanceof \WP_Post && $p->post_type === 'aksrt_forum_plate') {
|
||||
return $p;
|
||||
}
|
||||
}
|
||||
|
||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
// title_text is rendered inside payload head (zibll-like); optional WP title still allowed.
|
||||
$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
|
||||
}
|
||||
return null;
|
||||
echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
public function form($instance): void {
|
||||
?>
|
||||
<p>
|
||||
<label><?php esc_html_e('标题文案', 'aksrt'); ?>
|
||||
<label><?php esc_html_e('小标题文案', 'aksrt'); ?>
|
||||
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('title_text')); ?>" value="<?php echo esc_attr((string) ($instance['title_text'] ?? __('版主', 'aksrt'))); ?>">
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php esc_html_e('样式', 'aksrt'); ?>
|
||||
<select name="<?php echo esc_attr($this->get_field_name('style')); ?>">
|
||||
<option value="list" <?php selected(($instance['style'] ?? 'list'), 'list'); ?>><?php esc_html_e('列表', 'aksrt'); ?></option>
|
||||
<option value="grid" <?php selected(($instance['style'] ?? ''), 'grid'); ?>><?php esc_html_e('头像网格', 'aksrt'); ?></option>
|
||||
</select>
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_avatar')); ?>" value="1" <?php checked(!isset($instance['show_avatar']) || !empty($instance['show_avatar'])); ?>> <?php esc_html_e('显示头像', 'aksrt'); ?></label>
|
||||
</p>
|
||||
<p class="description"><?php esc_html_e('仅在版块/帖子页显示。', 'aksrt'); ?></p>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function update($new_instance, $old_instance): array {
|
||||
return [
|
||||
'title_text' => sanitize_text_field((string) ($new_instance['title_text'] ?? '')),
|
||||
'title_text' => sanitize_text_field((string) ($new_instance['title_text'] ?? '')),
|
||||
'style' => ($new_instance['style'] ?? '') === 'grid' ? 'grid' : 'list',
|
||||
'show_avatar' => !empty($new_instance['show_avatar']) ? 1 : 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user