(bool) ($all['user_report_s'] ?? (isset($all['user_report_enabled']) ? $all['user_report_enabled'] : true)), 'desc' => (string) ($all['ban_appeal_desc'] ?? ''), 'keys' => $keys, ]; } public static function get_status(int $user_id): string { return sanitize_key((string) get_user_meta($user_id, self::META_STATUS, true)); } /** * @return array */ public static function get_payload(int $user_id): array { $p = get_user_meta($user_id, self::META_PAYLOAD, true); return is_array($p) ? $p : []; } public function ajax_submit(): void { if (!is_user_logged_in()) { wp_send_json(['error' => 1, 'msg' => __('请先登录', 'aksrt')]); } if (!check_ajax_referer('aksrt_ban_appeal', '_wpnonce', false)) { wp_send_json(['error' => 1, 'msg' => __('安全校验失败', 'aksrt')]); } $user_id = get_current_user_id(); $s = self::settings(); if (!$s['enabled']) { wp_send_json(['error' => 1, 'msg' => __('申诉功能未开启', 'aksrt')]); } // 禁封状态门禁:封号(ban)与小黑屋(suspend)均可申诉 // (对齐参考主题 zib_user_is_ban 的 1/2 双类型语义)。 $restricted = class_exists('\AKSRT\User\Restriction') && in_array( \AKSRT\User\Restriction::get_instance()->get_display_state($user_id), [\AKSRT\User\Restriction::STATE_BANNED, \AKSRT\User\Restriction::STATE_RESTRICTED], true ); if (!$restricted) { wp_send_json(['error' => 1, 'msg' => __('当前账号未处于禁封状态', 'aksrt')]); } // 禁封时勾选“禁止用户申诉”的门禁(参考主题 no_appeal 同语义)。 $no_appeal = get_user_meta($user_id, '_aksrt_no_appeal', true); if (is_array($no_appeal) && $no_appeal['desc'] !== '') { wp_send_json(['error' => 1, 'msg' => sprintf(__('当前账号已被限制申诉:%s', 'aksrt'), (string) $no_appeal['desc'])]); } if (self::get_status($user_id) === 'pending') { wp_send_json(['error' => 1, 'msg' => __('申诉正在处理中,请勿重复提交', 'aksrt')]); } $reason_key = isset($_POST['reason_key']) ? sanitize_text_field(wp_unslash((string) $_POST['reason_key'])) : ''; $reason = isset($_POST['reason']) ? sanitize_textarea_field(wp_unslash((string) $_POST['reason'])) : ''; $data_rows = null; // 申诉弹窗表单(1:1 参考主题 zib_get_user_ban_appeal_modal):资料项以 // data[] 逐项提交,申诉说明取 data['申诉说明'];旧版平铺字段保持兼容。 if (isset($_POST['data']) && is_array($_POST['data'])) { $clean = []; foreach ($_POST['data'] as $k => $v) { $clean[sanitize_text_field(wp_unslash((string) $k))] = sanitize_textarea_field(wp_unslash((string) $v)); } $data_rows = $clean; $reason_key = ''; $reason = (string) ($clean[__('申诉说明', 'aksrt')] ?? ''); if ($reason === '') { foreach ($clean as $v) { if (trim((string) $v) !== '') { $reason = (string) $v; break; } } } } if ($reason === '') { wp_send_json(['error' => 1, 'msg' => __('请填写申诉说明', 'aksrt')]); } $payload = [ 'reason_key' => $reason_key, 'reason' => $reason, 'time' => current_time('Y-m-d H:i'), ]; if ($data_rows !== null) { $payload['data'] = $data_rows; } update_user_meta($user_id, self::META_PAYLOAD, $payload); update_user_meta($user_id, self::META_STATUS, 'pending'); $history = get_user_meta($user_id, self::META_HISTORY, true); $history = is_array($history) ? $history : []; $history[] = $payload; update_user_meta($user_id, self::META_HISTORY, array_slice($history, -20)); // Notify admins via site message table if available. if (class_exists('\AKSRT\Messages\Message')) { $admins = get_users(['role' => 'administrator', 'fields' => 'ID', 'number' => 20]); $summary = sprintf( /* translators: 1: user login 2: reason */ __('用户 %1$s 提交禁封申诉:%2$s', 'aksrt'), wp_get_current_user()->user_login, mb_substr($reason, 0, 80) ); foreach ($admins as $admin_id) { \AKSRT\Messages\Message::get_instance()->send( (int) $admin_id, 'ban_appeal', $summary, [ 'title' => __('禁封申诉', 'aksrt'), // 直达待处理申诉队列(与工单页 type=appeal&status=pending 过滤同参)。 'target_url' => admin_url('users.php?page=aksrt_user_ban&type=appeal&status=pending'), ] ); } } /** * @param int $user_id * @param array $payload */ do_action('aksrt_ban_appeal_submitted', $user_id, $payload); wp_send_json([ 'error' => 0, 'msg' => __('申诉已提交,请等待管理员处理', 'aksrt'), 'reload' => true, ]); } }