ensure_cap();
$filters = $this->get_ban_filters($_GET);
$data = $this->query_ban_requests($filters, max(1, (int) ($_GET['paged'] ?? 1)));
$this->cache_ban_targets($data['items']);
$this->load_ban_restrictions($data['items']);
NativeUi::page_open('aksrt-ban-page');
NativeUi::header(
__('举报与禁封申诉', 'aksrt'),
__('核对举报内容与申诉资料,在审核弹窗中记录处理结果。用户禁封操作仍在前台用户主页完成。', 'aksrt'),
'dashicons-shield'
);
$this->flash();
NativeUi::card_open('', '', true, 'aksrt-ban-list-card');
$this->render_ban_filters($filters, $data['counts']);
echo '
';
$this->render_ban_table($data['items'], $filters, $data['page']);
NativeUi::table_wrap_close();
AdminListPagination::render('aksrt_user_ban', $data['total'], $data['page'], self::BAN_PER_PAGE, $filters, 'users.php');
NativeUi::card_close();
echo '
';
echo '
';
NativeUi::page_close();
}
private function ban_page_url(array $args = []): string {
return add_query_arg(array_merge(['page' => 'aksrt_user_ban'], $args), admin_url('users.php'));
}
private function render_ban_filters(array $filters, array $counts): void {
echo '
';
}
private function render_ban_table(array $items, array $filters, int $page): void {
echo '
' . esc_html__('举报与禁封申诉处理记录', 'aksrt') . '';
foreach (['type' => __('类型 / 编号', 'aksrt'), 'user' => __('提交用户', 'aksrt'), 'summary' => __('事项摘要', 'aksrt'), 'status' => __('状态', 'aksrt'), 'time' => __('提交时间', 'aksrt'), 'updated' => __('更新时间', 'aksrt'), 'actions' => __('操作', 'aksrt')] as $key => $label) {
$sortable = in_array($key, ['type', 'status', 'time', 'updated'], true);
$active = $sortable && $filters['orderby'] === $key;
echo '| ';
if ($sortable) {
$order = $active && $filters['order'] === 'DESC' ? 'ASC' : 'DESC';
$title = sprintf($order === 'ASC' ? __('按%s升序排列', 'aksrt') : __('按%s降序排列', 'aksrt'), $label);
echo '' . esc_html($label) . '' . ($active ? ($filters['order'] === 'ASC' ? '↑' : '↓') : '↕') . '';
} else {
echo esc_html($label);
}
echo ' | ';
}
echo '
';
if ($items === []) {
$filtered = $filters['s'] !== '' || $filters['send_user'] > 0;
echo NativeUi::empty_row(7,
!$filtered && $filters['status'] === 'pending' ? __('暂无待处理记录', 'aksrt') : __('没有符合条件的记录', 'aksrt'),
$filtered ? __('请调整关键词、清除用户筛选或切换类型和状态。', 'aksrt') : __('可切换状态查看处理记录,新举报和申诉将在这里显示。', 'aksrt')
);
}
foreach ($items as $row) $this->render_ban_row($row, $filters, $page);
echo '
';
}
private function render_ban_row(array $row, array $filters, int $page): void {
$report = $row['kind'] === 'report';
$payload = $row['payload'];
$key = $row['kind'] . '-' . $row['id'];
$user_id = (int) $row['user_id'];
echo '
| ' . NativeUi::badge($report ? __('用户举报', 'aksrt') : __('禁封申诉', 'aksrt'), $report ? 'info' : 'neutral', false);
echo ' #' . (int) $row['id'] . ' | ' . NativeUi::user_cell($user_id, __('用户已删除', 'aksrt'));
if ($user_id > 0) {
echo '' . esc_html__('筛选此用户', 'aksrt') . '';
}
echo ' | ';
if ($report) {
echo '' . $this->ban_target_link((string) ($payload['target_type'] ?? ''), (int) ($payload['target_id'] ?? 0)) . '';
echo ' ' . esc_html((string) ($payload['category'] ?? '')) . ' ';
} else {
echo '' . esc_html__('申请解除禁封', 'aksrt') . '';
}
if ((string) ($payload['reason'] ?? '') !== '') echo '' . esc_html((string) $payload['reason']) . ' ';
$this->render_ban_detail_template($row, $filters, $page);
echo ' | ' . $this->ban_status_badge($row) . ' | ';
echo '' . esc_html($this->ban_time((string) $row['time'])) . ' | ';
echo '' . esc_html($this->ban_time((string) $row['updated'])) . ' | ';
echo ' |
';
}
private function ban_status_badge(array $row): string {
if ($row['status'] === 'pending') return NativeUi::badge($row['raw_status'] === 'reviewing' ? __('审核中', 'aksrt') : __('待处理', 'aksrt'), 'warning');
if ($row['status'] === 'resolved') return NativeUi::badge($row['kind'] === 'report' ? __('已处理', 'aksrt') : __('已通过', 'aksrt'), 'success');
return NativeUi::badge(__('已驳回', 'aksrt'), 'danger');
}
private function ban_time(string $time): string {
return $time !== '' && $time !== '0000-00-00 00:00:00' ? $time : '—';
}
private function ban_user_home(int $user_id): string {
return function_exists('aksrt_get_user_home_url') ? aksrt_get_user_home_url($user_id) : get_author_posts_url($user_id);
}
private function ban_target_link(string $type, int $id): string {
$labels = ['post' => __('文章', 'aksrt'), 'comment' => __('评论', 'aksrt'), 'user' => __('用户', 'aksrt')];
$label = ($labels[$type] ?? __('目标', 'aksrt')) . ' #' . $id;
$url = '';
if ($type === 'post' && get_post($id)) {
$label = get_the_title($id) ?: $label;
$url = (string) get_permalink($id);
} elseif ($type === 'comment' && get_comment($id)) {
$url = (string) get_comment_link($id);
} elseif ($type === 'user' && ($user = get_userdata($id))) {
$label = $user->display_name . ' #' . $id;
$url = $this->ban_user_home($id);
}
return $url !== '' ? '
' . esc_html($label) . '' : esc_html($label . ' ' . __('(目标已不可用)', 'aksrt'));
}
private function cache_ban_targets(array $items): void {
$ids = ['post' => [], 'comment' => [], 'user' => []];
foreach ($items as $row) {
if ($row['kind'] !== 'report') continue;
$type = (string) ($row['payload']['target_type'] ?? '');
$id = (int) ($row['payload']['target_id'] ?? 0);
if (isset($ids[$type]) && $id > 0) $ids[$type][] = $id;
}
foreach ($ids as &$values) $values = array_values(array_unique($values));
unset($values);
if ($ids['post'] !== []) _prime_post_caches($ids['post'], false, false);
if ($ids['comment'] !== []) _prime_comment_caches($ids['comment'], false);
if ($ids['user'] !== []) cache_users($ids['user']);
}
private function load_ban_restrictions(array $items): void {
$this->ban_restrictions = [];
if (!class_exists(Restriction::class)) return;
$ids = [];
foreach ($items as $row) {
$id = $row['kind'] === 'appeal' ? (int) $row['user_id'] : (($row['payload']['target_type'] ?? '') === 'user' ? (int) $row['payload']['target_id'] : 0);
if ($id > 0) $ids[] = $id;
}
$ids = array_values(array_unique($ids));
if ($ids === []) return;
global $wpdb;
$placeholders = implode(',', array_fill(0, count($ids), '%d'));
$rows = $wpdb->get_results($wpdb->prepare(
"SELECT user_id, type, scope, reason, created_at, expires_at FROM {$wpdb->prefix}aksrt_user_restriction WHERE user_id IN ({$placeholders}) AND (expires_at IS NULL OR expires_at > %s) ORDER BY created_at DESC",
array_merge($ids, [current_time('mysql', true)])
), ARRAY_A);
foreach ((array) $rows as $row) $this->ban_restrictions[(int) $row['user_id']][] = $row;
}
}