false, 'message' => '']; $action = sanitize_text_field($_POST['feedback_action']); // 管理员操作 if (in_array($action, ['delete', 'toggle_public', 'reply', 'update_status'])) { if (!$is_admin) { echo json_encode(['success' => false, 'message' => '权限不足']); exit; } if (!isset($_POST['feedback_nonce']) || !wp_verify_nonce($_POST['feedback_nonce'], 'argon_feedback_manage')) { echo json_encode(['success' => false, 'message' => '安全验证失败']); exit; } } switch ($action) { case 'submit': $response = argon_handle_feedback_submit($_POST); break; case 'delete': $id = isset($_POST['id']) ? sanitize_text_field($_POST['id']) : ''; $response = ['success' => argon_delete_feedback($id)]; break; case 'toggle_public': $id = isset($_POST['id']) ? sanitize_text_field($_POST['id']) : ''; $response = argon_toggle_feedback_public($id); break; case 'reply': $id = isset($_POST['id']) ? sanitize_text_field($_POST['id']) : ''; $reply = isset($_POST['reply']) ? sanitize_textarea_field($_POST['reply']) : ''; $response = argon_reply_feedback($id, $reply); break; case 'update_status': $id = isset($_POST['id']) ? sanitize_text_field($_POST['id']) : ''; $status = isset($_POST['status']) ? sanitize_text_field($_POST['status']) : ''; $response = argon_update_feedback_status($id, $status); break; } echo json_encode($response); exit; } // ==================== 反馈数据操作函数 ==================== /** * 获取用户唯一标识 */ function argon_get_feedback_user_identifier() { if (is_user_logged_in()) { return 'user_' . get_current_user_id(); } $ip = ''; if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip_list = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $ip = trim($ip_list[0]); } elseif (!empty($_SERVER['HTTP_X_REAL_IP'])) { $ip = $_SERVER['HTTP_X_REAL_IP']; } else { $ip = $_SERVER['REMOTE_ADDR']; } $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; return substr(hash('sha256', $ip . '|' . $user_agent), 0, 16); } /** * 获取所有反馈 */ function argon_get_feedbacks($filter = 'all') { $feedbacks = get_option('argon_feedbacks', []); if (!is_array($feedbacks)) $feedbacks = []; // 按时间倒序 usort($feedbacks, function($a, $b) { return ($b['created_at'] ?? 0) - ($a['created_at'] ?? 0); }); if ($filter === 'public') { return array_filter($feedbacks, function($f) { return !empty($f['is_public']); }); } return $feedbacks; } /** * 获取单个反馈 */ function argon_get_feedback($id) { $feedbacks = argon_get_feedbacks(); foreach ($feedbacks as $f) { if ($f['id'] === $id) return $f; } return null; } /** * 添加反馈 */ function argon_add_feedback($data) { $feedbacks = get_option('argon_feedbacks', []); if (!is_array($feedbacks)) $feedbacks = []; $id = 'fb_' . uniqid(); $feedback = [ 'id' => $id, 'title' => sanitize_text_field($data['title'] ?? ''), 'content' => sanitize_textarea_field($data['content'] ?? ''), 'type' => sanitize_text_field($data['type'] ?? 'suggestion'), 'name' => sanitize_text_field($data['name'] ?? ''), 'email' => sanitize_email($data['email'] ?? ''), 'url' => esc_url_raw($data['url'] ?? ''), 'is_public' => !empty($data['is_public']), 'status' => 'pending', // pending, processing, resolved, closed 'user_identifier' => argon_get_feedback_user_identifier(), 'user_id' => is_user_logged_in() ? get_current_user_id() : 0, 'ip' => $_SERVER['REMOTE_ADDR'] ?? '', 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'created_at' => time(), 'reply' => '', 'reply_at' => 0, ]; $feedbacks[] = $feedback; update_option('argon_feedbacks', $feedbacks); return $id; } /** * 删除反馈 */ function argon_delete_feedback($id) { $feedbacks = get_option('argon_feedbacks', []); if (!is_array($feedbacks)) return false; foreach ($feedbacks as $key => $f) { if ($f['id'] === $id) { unset($feedbacks[$key]); update_option('argon_feedbacks', array_values($feedbacks)); return true; } } return false; } /** * 切换公开状态 */ function argon_toggle_feedback_public($id) { $feedbacks = get_option('argon_feedbacks', []); if (!is_array($feedbacks)) return ['success' => false]; foreach ($feedbacks as &$f) { if ($f['id'] === $id) { $f['is_public'] = !$f['is_public']; update_option('argon_feedbacks', $feedbacks); return ['success' => true, 'is_public' => $f['is_public']]; } } return ['success' => false]; } /** * 回复反馈 */ function argon_reply_feedback($id, $reply) { $feedbacks = get_option('argon_feedbacks', []); if (!is_array($feedbacks)) return ['success' => false]; foreach ($feedbacks as &$f) { if ($f['id'] === $id) { $f['reply'] = $reply; $f['reply_at'] = time(); if ($f['status'] === 'pending') { $f['status'] = 'processing'; } update_option('argon_feedbacks', $feedbacks); // 发送邮件通知 if (!empty($f['email']) && !empty($reply)) { $subject = sprintf('[%s] 您的反馈已收到回复', get_bloginfo('name')); $message = sprintf( "您好 %s!\n\n您提交的反馈「%s」已收到回复:\n\n%s\n\n感谢您的反馈!\n\n%s", $f['name'], $f['title'], $reply, home_url() ); wp_mail($f['email'], $subject, $message); } return ['success' => true]; } } return ['success' => false]; } /** * 更新反馈状态 */ function argon_update_feedback_status($id, $status) { $valid_statuses = ['pending', 'processing', 'resolved', 'closed']; if (!in_array($status, $valid_statuses)) { return ['success' => false, 'message' => '无效状态']; } $feedbacks = get_option('argon_feedbacks', []); if (!is_array($feedbacks)) return ['success' => false]; foreach ($feedbacks as &$f) { if ($f['id'] === $id) { $f['status'] = $status; update_option('argon_feedbacks', $feedbacks); return ['success' => true]; } } return ['success' => false]; } /** * 处理反馈提交 */ function argon_handle_feedback_submit($data) { // 验证必填字段 if (empty($data['feedback_email'])) { return ['success' => false, 'message' => __('请填写邮箱', 'argon')]; } if (empty($data['feedback_name'])) { return ['success' => false, 'message' => __('请填写昵称', 'argon')]; } if (empty($data['feedback_content'])) { return ['success' => false, 'message' => __('请填写反馈内容', 'argon')]; } // 验证邮箱格式 if (!is_email($data['feedback_email'])) { return ['success' => false, 'message' => __('邮箱格式错误', 'argon')]; } // 验证码检查 $captcha_enabled = get_option('argon_feedback_captcha', 'true') === 'true'; if ($captcha_enabled && function_exists('check_comment_captcha')) { $captcha_input = $data['feedback_captcha'] ?? ''; if (!check_comment_captcha($captcha_input)) { return ['success' => false, 'message' => __('验证码错误', 'argon')]; } } // 添加反馈 $id = argon_add_feedback([ 'title' => $data['feedback_title'] ?? '', 'content' => $data['feedback_content'], 'type' => $data['feedback_type'] ?? 'suggestion', 'name' => $data['feedback_name'], 'email' => $data['feedback_email'], 'url' => $data['feedback_url'] ?? '', 'is_public' => !empty($data['feedback_public']), ]); if ($id) { return ['success' => true, 'message' => __('反馈提交成功,感谢您的建议!', 'argon')]; } return ['success' => false, 'message' => __('提交失败,请稍后重试', 'argon')]; } // ==================== 页面渲染 ==================== // 获取反馈数据 $all_feedbacks = argon_get_feedbacks(); $public_feedbacks = argon_get_feedbacks('public'); $pending_count = count(array_filter($all_feedbacks, function($f) { return $f['status'] === 'pending'; })); // 验证码设置 $captcha_enabled = get_option('argon_feedback_captcha', 'true') === 'true'; // 从 Cookie 获取用户信息 $saved_name = isset($_COOKIE['comment_author_' . COOKIEHASH]) ? $_COOKIE['comment_author_' . COOKIEHASH] : ''; $saved_email = isset($_COOKIE['comment_author_email_' . COOKIEHASH]) ? $_COOKIE['comment_author_email_' . COOKIEHASH] : ''; $saved_url = isset($_COOKIE['comment_author_url_' . COOKIEHASH]) ? $_COOKIE['comment_author_url_' . COOKIEHASH] : ''; // 如果已登录,使用用户信息 if (is_user_logged_in()) { $current_user = wp_get_current_user(); $saved_name = $current_user->display_name; $saved_email = $current_user->user_email; $saved_url = $current_user->user_url; } get_header(); ?>

0) : ?>

()

__('Bug', 'argon'), 'suggestion' => __('建议', 'argon'), 'question' => __('问题', 'argon'), 'other' => __('其他', 'argon')]; $status_labels = ['pending' => __('待处理', 'argon'), 'processing' => __('处理中', 'argon'), 'resolved' => __('已解决', 'argon'), 'closed' => __('已关闭', 'argon')]; $type = $fb['type'] ?? 'other'; $status = $fb['status'] ?? 'pending'; $avatar_url = get_avatar_url($fb['email'], ['size' => 80]); ?>
| IP:
·

__('Bug', 'argon'), 'suggestion' => __('建议', 'argon'), 'question' => __('问题', 'argon'), 'other' => __('其他', 'argon')]; $status_labels = ['pending' => __('待处理', 'argon'), 'processing' => __('处理中', 'argon'), 'resolved' => __('已解决', 'argon'), 'closed' => __('已关闭', 'argon')]; $type = $fb['type'] ?? 'other'; $status = $fb['status'] ?? 'pending'; $avatar_url = get_avatar_url($fb['email'], ['size' => 80]); ?>
·