文章目录[隐藏]
开发指南:为WordPress网站创建自定义在线问卷调查工具
引言:为什么需要自定义问卷调查工具
在当今数据驱动的互联网时代,问卷调查已成为网站收集用户反馈、进行市场研究、评估客户满意度的重要工具。虽然WordPress生态中有许多现成的问卷调查插件,如WPForms、Gravity Forms等,但这些通用解决方案往往无法完全满足特定业务需求。自定义问卷调查工具能够提供更精准的数据收集、更符合品牌形象的用户界面以及更灵活的集成能力。
通过WordPress代码二次开发实现自定义问卷调查工具,不仅可以节省长期使用付费插件的成本,还能确保工具完全按照您的业务流程和需求定制。本指南将详细介绍如何从零开始,为WordPress网站开发一个功能完善的自定义在线问卷调查工具。
第一章:开发前的准备工作
1.1 环境搭建与工具选择
在开始开发之前,需要确保具备以下环境:
- 本地开发环境:推荐使用XAMPP、MAMP或Local by Flywheel搭建本地WordPress环境
- 代码编辑器:Visual Studio Code、PHPStorm或Sublime Text
- 版本控制:Git用于代码版本管理
- 浏览器开发者工具:用于调试前端代码
1.2 需求分析与功能规划
在编写代码之前,明确问卷调查工具的核心需求:
- 问卷创建与管理:后台界面用于创建、编辑和删除问卷
- 问题类型支持:单选题、多选题、文本题、评分题等
- 响应收集与存储:安全地存储用户提交的问卷数据
- 数据分析与导出:后台查看统计结果并导出数据
- 前端展示与交互:用户友好的问卷填写界面
- 权限控制:限制问卷访问权限(公开/私有)
1.3 数据库设计
设计合理的数据库结构是开发成功的关键。我们需要创建以下数据表:
-
surveys表:存储问卷基本信息
- id (主键)
- title (问卷标题)
- description (问卷描述)
- status (状态:草稿/发布/归档)
- created_at (创建时间)
- updated_at (更新时间)
-
questions表:存储问题信息
- id (主键)
- survey_id (关联问卷ID)
- question_text (问题文本)
- question_type (问题类型:单选/多选/文本等)
- options (选项,JSON格式存储)
- required (是否必答)
- sort_order (排序)
-
responses表:存储用户回答
- id (主键)
- survey_id (问卷ID)
- question_id (问题ID)
- answer (用户答案)
- user_id (用户ID,匿名则为空)
- submitted_at (提交时间)
- session_id (会话ID,用于匿名用户跟踪)
第二章:创建基础插件结构
2.1 初始化插件文件
在WordPress的wp-content/plugins/目录下创建新文件夹custom-survey-tool,并创建以下基础文件:
custom-survey-tool/
├── custom-survey-tool.php # 主插件文件
├── includes/
│ ├── class-database.php # 数据库处理类
│ ├── class-survey.php # 问卷核心类
│ ├── class-admin.php # 后台管理类
│ └── class-frontend.php # 前端展示类
├── admin/
│ ├── css/
│ │ └── admin-style.css # 后台样式
│ └── js/
│ └── admin-script.js # 后台脚本
├── public/
│ ├── css/
│ │ └── public-style.css # 前端样式
│ └── js/
│ └── public-script.js # 前端脚本
├── templates/ # 模板文件
└── assets/ # 静态资源
2.2 主插件文件配置
编辑custom-survey-tool.php文件,添加插件基本信息:
<?php
/**
* Plugin Name: 自定义问卷调查工具
* Plugin URI: https://yourwebsite.com/
* Description: 为WordPress网站创建自定义在线问卷调查工具
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: custom-survey-tool
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('CST_VERSION', '1.0.0');
define('CST_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CST_PLUGIN_URL', plugin_dir_url(__FILE__));
// 自动加载类文件
spl_autoload_register(function ($class_name) {
$prefix = 'CST_';
$base_dir = CST_PLUGIN_DIR . 'includes/';
$len = strlen($prefix);
if (strncmp($prefix, $class_name, $len) !== 0) {
return;
}
$relative_class = substr($class_name, $len);
$file = $base_dir . 'class-' . strtolower(str_replace('_', '-', $relative_class)) . '.php';
if (file_exists($file)) {
require_once $file;
}
});
// 初始化插件
function cst_init() {
// 检查WordPress版本
if (version_compare(get_bloginfo('version'), '5.0', '<')) {
wp_die(__('本插件需要WordPress 5.0或更高版本', 'custom-survey-tool'));
}
// 实例化核心类
$database = new CST_Database();
$survey = new CST_Survey();
$admin = new CST_Admin();
$frontend = new CST_Frontend();
// 激活/停用钩子
register_activation_hook(__FILE__, array($database, 'create_tables'));
register_deactivation_hook(__FILE__, array($database, 'drop_tables'));
}
add_action('plugins_loaded', 'cst_init');
第三章:数据库与核心功能开发
3.1 数据库处理类
创建includes/class-database.php文件,处理数据库表的创建与维护:
<?php
class CST_Database {
public function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_prefix = $wpdb->prefix . 'cst_';
// 创建问卷表
$surveys_table = $table_prefix . 'surveys';
$sql1 = "CREATE TABLE IF NOT EXISTS $surveys_table (
id int(11) NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
description text,
status varchar(20) DEFAULT 'draft',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
// 创建问题表
$questions_table = $table_prefix . 'questions';
$sql2 = "CREATE TABLE IF NOT EXISTS $questions_table (
id int(11) NOT NULL AUTO_INCREMENT,
survey_id int(11) NOT NULL,
question_text text NOT NULL,
question_type varchar(50) NOT NULL,
options text,
required tinyint(1) DEFAULT 0,
sort_order int(11) DEFAULT 0,
PRIMARY KEY (id),
KEY survey_id (survey_id)
) $charset_collate;";
// 创建回答表
$responses_table = $table_prefix . 'responses';
$sql3 = "CREATE TABLE IF NOT EXISTS $responses_table (
id int(11) NOT NULL AUTO_INCREMENT,
survey_id int(11) NOT NULL,
question_id int(11) NOT NULL,
answer text NOT NULL,
user_id int(11) DEFAULT NULL,
session_id varchar(100) DEFAULT NULL,
submitted_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY survey_id (survey_id),
KEY question_id (question_id),
KEY user_id (user_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql1);
dbDelta($sql2);
dbDelta($sql3);
// 添加默认数据(示例问卷)
$this->add_sample_data();
}
private function add_sample_data() {
global $wpdb;
$table_prefix = $wpdb->prefix . 'cst_';
// 检查是否已有数据
$count = $wpdb->get_var("SELECT COUNT(*) FROM {$table_prefix}surveys");
if ($count == 0) {
// 添加示例问卷
$wpdb->insert(
$table_prefix . 'surveys',
array(
'title' => '客户满意度调查',
'description' => '帮助我们改进服务的简短问卷',
'status' => 'published'
)
);
$survey_id = $wpdb->insert_id;
// 添加示例问题
$sample_questions = array(
array(
'survey_id' => $survey_id,
'question_text' => '您如何评价我们的产品质量?',
'question_type' => 'rating',
'options' => json_encode(array('min' => 1, 'max' => 5, 'labels' => array('非常差', '差', '一般', '好', '非常好'))),
'required' => 1,
'sort_order' => 1
),
array(
'survey_id' => $survey_id,
'question_text' => '您是通过什么渠道了解到我们的?',
'question_type' => 'checkbox',
'options' => json_encode(array('搜索引擎', '社交媒体', '朋友推荐', '广告', '其他')),
'required' => 0,
'sort_order' => 2
),
array(
'survey_id' => $survey_id,
'question_text' => '您有什么改进建议?',
'question_type' => 'textarea',
'options' => json_encode(array('rows' => 4)),
'required' => 0,
'sort_order' => 3
)
);
foreach ($sample_questions as $question) {
$wpdb->insert($table_prefix . 'questions', $question);
}
}
}
public function drop_tables() {
global $wpdb;
$tables = array(
$wpdb->prefix . 'cst_surveys',
$wpdb->prefix . 'cst_questions',
$wpdb->prefix . 'cst_responses'
);
foreach ($tables as $table) {
$wpdb->query("DROP TABLE IF EXISTS $table");
}
}
}
3.2 问卷核心功能类
创建includes/class-survey.php文件,实现问卷的核心业务逻辑:
<?php
class CST_Survey {
private $db;
public function __construct() {
global $wpdb;
$this->db = $wpdb;
$this->table_prefix = $wpdb->prefix . 'cst_';
}
// 获取所有问卷
public function get_all_surveys($status = null) {
$where = '';
if ($status) {
$where = $this->db->prepare("WHERE status = %s", $status);
}
return $this->db->get_results(
"SELECT * FROM {$this->table_prefix}surveys $where ORDER BY created_at DESC"
);
}
// 获取单个问卷
public function get_survey($id) {
return $this->db->get_row(
$this->db->prepare(
"SELECT * FROM {$this->table_prefix}surveys WHERE id = %d",
$id
)
);
}
// 获取问卷的所有问题
public function get_survey_questions($survey_id) {
return $this->db->get_results(
$this->db->prepare(
"SELECT * FROM {$this->table_prefix}questions
WHERE survey_id = %d
ORDER BY sort_order ASC",
$survey_id
)
);
}
// 创建新问卷
public function create_survey($data) {
$defaults = array(
'title' => '新问卷',
'description' => '',
'status' => 'draft'
);
$data = wp_parse_args($data, $defaults);
$this->db->insert(
$this->table_prefix . 'surveys',
$data
);
return $this->db->insert_id;
}
// 更新问卷
public function update_survey($id, $data) {
return $this->db->update(
$this->table_prefix . 'surveys',
$data,
array('id' => $id)
);
}
// 删除问卷
public function delete_survey($id) {
// 先删除相关问题
$this->db->delete(
$this->table_prefix . 'questions',
array('survey_id' => $id)
);
// 再删除问卷
return $this->db->delete(
$this->table_prefix . 'surveys',
array('id' => $id)
);
}
// 添加问题到问卷
public function add_question($survey_id, $data) {
$defaults = array(
'survey_id' => $survey_id,
'question_text' => '新问题',
'question_type' => 'text',
'options' => '',
'required' => 0,
'sort_order' => 0
);
$data = wp_parse_args($data, $defaults);
$this->db->insert(
$this->table_prefix . 'questions',
$data
);
return $this->db->insert_id;
}
// 提交问卷回答
public function submit_response($survey_id, $responses, $user_id = null) {
$session_id = $this->generate_session_id();
foreach ($responses as $question_id => $answer) {
// 处理多选答案
if (is_array($answer)) {
$answer = json_encode($answer);
}
$this->db->insert(
$this->table_prefix . 'responses',
array(
'survey_id' => $survey_id,
'question_id' => $question_id,
'answer' => $answer,
'user_id' => $user_id,
'session_id' => $session_id
)
);
}
return true;
}
// 获取问卷统计
public function get_survey_stats($survey_id) {
$questions = $this->get_survey_questions($survey_id);
$stats = array();
foreach ($questions as $question) {
$answers = $this->db->get_results(
$this->db->prepare(
"SELECT answer FROM {$this->table_prefix}responses
WHERE survey_id = %d AND question_id = %d",
$survey_id,
$question->id
)
);
$question_stats = array(
'question' => $question->question_text,
'type' => $question->question_type,
'total_responses' => count($answers),
'answers' => array()
);
// 根据问题类型统计答案
if ($question->question_type === 'radio' || $question->question_type === 'checkbox') {
$options = json_decode($question->options, true);
$counts = array();
foreach ($options as $option) {
$counts[$option] = 0;
}
foreach ($answers as $answer) {
if ($question->question_type === 'checkbox') {
$user_answers = json_decode($answer->answer, true);
if (is_array($user_answers)) {
foreach ($user_answers as $user_answer) {
if (isset($counts[$user_answer])) {
$counts[$user_answer]++;
}
}
}
} else {
if (isset($counts[$answer->answer])) {
$counts[$answer->answer]++;
}
}
}
$question_stats['answers'] = $counts;
} elseif ($question->question_type === 'rating') {
$ratings = array();
foreach ($answers as $answer) {
$ratings[] = intval($answer->answer);
}
if (!empty($ratings)) {
$question_stats['answers'] = array(
'average' => round(array_sum($ratings) / count($ratings), 2),
'min' => min($ratings),
'max' => max($ratings),
'distribution' => array_count_values($ratings)
);
}
}
$stats[] = $question_stats;
}
return $stats;
}
private function generate_session_id() {
return md5(uniqid(rand(), true) . $_SERVER['REMOTE_ADDR']);
}
}
第四章:后台管理界面开发
4.1 管理类与菜单创建
创建includes/class-admin.php文件,实现后台管理功能:
<?php
class CST_Admin {
private $survey;
public function __construct() {
$this->survey = new CST_Survey();
// 添加管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 加载脚本和样式
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
// 处理表单提交
add_action('admin_post_cst_save_survey', array($this, 'save_survey'));
add_action('admin_post_cst_delete_survey', array($this, 'delete_survey'));
}
第四章:后台管理界面开发(续)
4.1 管理类与菜单创建(续)
public function add_admin_menu() {
// 主菜单
add_menu_page(
'问卷调查工具',
'问卷调查',
'manage_options',
'custom-survey-tool',
array($this, 'surveys_list_page'),
'dashicons-feedback',
30
);
// 子菜单
add_submenu_page(
'custom-survey-tool',
'所有问卷',
'所有问卷',
'manage_options',
'custom-survey-tool',
array($this, 'surveys_list_page')
);
add_submenu_page(
'custom-survey-tool',
'添加新问卷',
'添加新问卷',
'manage_options',
'cst-add-survey',
array($this, 'add_survey_page')
);
add_submenu_page(
'custom-survey-tool',
'问卷统计',
'问卷统计',
'manage_options',
'cst-survey-stats',
array($this, 'survey_stats_page')
);
add_submenu_page(
'custom-survey-tool',
'插件设置',
'设置',
'manage_options',
'cst-settings',
array($this, 'settings_page')
);
}
public function enqueue_admin_scripts($hook) {
// 只在插件页面加载资源
if (strpos($hook, 'custom-survey-tool') === false &&
strpos($hook, 'cst-') === false) {
return;
}
wp_enqueue_style(
'cst-admin-style',
CST_PLUGIN_URL . 'admin/css/admin-style.css',
array(),
CST_VERSION
);
wp_enqueue_script(
'cst-admin-script',
CST_PLUGIN_URL . 'admin/js/admin-script.js',
array('jquery', 'jquery-ui-sortable'),
CST_VERSION,
true
);
// 本地化脚本
wp_localize_script('cst-admin-script', 'cst_admin', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('cst_admin_nonce'),
'confirm_delete' => __('确定要删除这个问卷吗?此操作不可撤销。', 'custom-survey-tool')
));
}
4.2 问卷列表页面
public function surveys_list_page() {
$action = isset($_GET['action']) ? sanitize_text_field($_GET['action']) : 'list';
$survey_id = isset($_GET['survey_id']) ? intval($_GET['survey_id']) : 0;
switch ($action) {
case 'edit':
$this->edit_survey_page($survey_id);
break;
case 'view':
$this->view_responses_page($survey_id);
break;
default:
$this->display_surveys_list();
}
}
private function display_surveys_list() {
$surveys = $this->survey->get_all_surveys();
?>
<div class="wrap cst-admin">
<h1 class="wp-heading-inline">问卷调查</h1>
<a href="<?php echo admin_url('admin.php?page=cst-add-survey'); ?>" class="page-title-action">
添加新问卷
</a>
<?php if (isset($_GET['message'])): ?>
<div class="notice notice-<?php echo sanitize_text_field($_GET['type'] ?? 'success'); ?> is-dismissible">
<p><?php echo esc_html($_GET['message']); ?></p>
</div>
<?php endif; ?>
<div class="tablenav top">
<div class="alignleft actions">
<select name="status_filter" id="status_filter">
<option value="">所有状态</option>
<option value="draft">草稿</option>
<option value="published">已发布</option>
<option value="archived">已归档</option>
</select>
<button class="button action" id="filter_action">筛选</button>
</div>
<br class="clear">
</div>
<table class="wp-list-table widefat fixed striped surveys">
<thead>
<tr>
<th scope="col" class="column-id">ID</th>
<th scope="col" class="column-title">问卷标题</th>
<th scope="col" class="column-status">状态</th>
<th scope="col" class="column-questions">问题数</th>
<th scope="col" class="column-responses">回答数</th>
<th scope="col" class="column-date">创建时间</th>
<th scope="col" class="column-actions">操作</th>
</tr>
</thead>
<tbody>
<?php if (empty($surveys)): ?>
<tr>
<td colspan="7" class="no-items">暂无问卷,请点击"添加新问卷"创建第一个问卷。</td>
</tr>
<?php else: ?>
<?php foreach ($surveys as $survey):
$questions_count = $this->survey->get_questions_count($survey->id);
$responses_count = $this->survey->get_responses_count($survey->id);
?>
<tr>
<td class="column-id"><?php echo $survey->id; ?></td>
<td class="column-title">
<strong>
<a href="<?php echo admin_url('admin.php?page=custom-survey-tool&action=edit&survey_id=' . $survey->id); ?>">
<?php echo esc_html($survey->title); ?>
</a>
</strong>
<div class="row-actions">
<span class="edit">
<a href="<?php echo admin_url('admin.php?page=custom-survey-tool&action=edit&survey_id=' . $survey->id); ?>">编辑</a> |
</span>
<span class="view">
<a href="<?php echo admin_url('admin.php?page=cst-survey-stats&survey_id=' . $survey->id); ?>">统计</a> |
</span>
<span class="duplicate">
<a href="#" class="duplicate-survey" data-id="<?php echo $survey->id; ?>">复制</a> |
</span>
<span class="trash">
<a href="<?php echo wp_nonce_url(admin_url('admin-post.php?action=cst_delete_survey&survey_id=' . $survey->id), 'cst_delete_survey'); ?>"
class="submitdelete" onclick="return confirm('确定要删除这个问卷吗?')">删除</a>
</span>
</div>
</td>
<td class="column-status">
<span class="status-badge status-<?php echo $survey->status; ?>">
<?php
$status_labels = array(
'draft' => '草稿',
'published' => '已发布',
'archived' => '已归档'
);
echo $status_labels[$survey->status] ?? $survey->status;
?>
</span>
</td>
<td class="column-questions"><?php echo $questions_count; ?></td>
<td class="column-responses"><?php echo $responses_count; ?></td>
<td class="column-date"><?php echo date('Y-m-d H:i', strtotime($survey->created_at)); ?></td>
<td class="column-actions">
<a href="<?php echo admin_url('admin.php?page=custom-survey-tool&action=edit&survey_id=' . $survey->id); ?>"
class="button button-small">编辑</a>
<a href="<?php echo admin_url('admin.php?page=cst-survey-stats&survey_id=' . $survey->id); ?>"
class="button button-small">查看统计</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<?php
}
4.3 问卷编辑页面
private function edit_survey_page($survey_id) {
$survey = $this->survey->get_survey($survey_id);
$questions = $this->survey->get_survey_questions($survey_id);
if (!$survey) {
wp_die('问卷不存在');
}
?>
<div class="wrap cst-admin">
<h1>编辑问卷: <?php echo esc_html($survey->title); ?></h1>
<form method="post" action="<?php echo admin_url('admin-post.php'); ?>" id="survey-form">
<input type="hidden" name="action" value="cst_save_survey">
<input type="hidden" name="survey_id" value="<?php echo $survey_id; ?>">
<?php wp_nonce_field('cst_save_survey', 'cst_nonce'); ?>
<div id="poststuff">
<div id="post-body" class="metabox-holder columns-2">
<!-- 主内容区 -->
<div id="post-body-content">
<div class="postbox">
<h2 class="hndle">问卷基本信息</h2>
<div class="inside">
<table class="form-table">
<tr>
<th><label for="survey_title">问卷标题</label></th>
<td>
<input type="text" id="survey_title" name="survey_title"
value="<?php echo esc_attr($survey->title); ?>"
class="regular-text" required>
</td>
</tr>
<tr>
<th><label for="survey_description">问卷描述</label></th>
<td>
<textarea id="survey_description" name="survey_description"
rows="3" class="large-text"><?php echo esc_textarea($survey->description); ?></textarea>
<p class="description">显示在问卷开头的描述文字</p>
</td>
</tr>
<tr>
<th><label for="survey_status">状态</label></th>
<td>
<select id="survey_status" name="survey_status">
<option value="draft" <?php selected($survey->status, 'draft'); ?>>草稿</option>
<option value="published" <?php selected($survey->status, 'published'); ?>>已发布</option>
<option value="archived" <?php selected($survey->status, 'archived'); ?>>已归档</option>
</select>
</td>
</tr>
</table>
</div>
</div>
<!-- 问题管理区域 -->
<div class="postbox">
<h2 class="hndle">问卷问题</h2>
<div class="inside">
<div id="questions-container" class="sortable-questions">
<?php if (empty($questions)): ?>
<p class="no-questions">暂无问题,点击下方"添加问题"按钮开始添加。</p>
<?php else: ?>
<?php foreach ($questions as $index => $question): ?>
<?php $this->render_question_editor($question, $index); ?>
<?php endforeach; ?>
<?php endif; ?>
</div>
<div class="add-question-section">
<button type="button" id="add-question" class="button button-primary">
<span class="dashicons dashicons-plus"></span> 添加问题
</button>
<div class="question-type-selector" style="display: none;">
<select id="new-question-type">
<option value="text">单行文本</option>
<option value="textarea">多行文本</option>
<option value="radio">单选题</option>
<option value="checkbox">多选题</option>
<option value="select">下拉选择</option>
<option value="rating">评分题</option>
<option value="date">日期选择</option>
<option value="email">邮箱地址</option>
</select>
<button type="button" id="confirm-add-question" class="button">确认添加</button>
<button type="button" id="cancel-add-question" class="button button-link">取消</button>
</div>
</div>
</div>
</div>
</div>
<!-- 侧边栏 -->
<div id="postbox-container-1" class="postbox-container">
<div class="postbox">
<h2 class="hndle">发布</h2>
<div class="inside">
<div class="submitbox">
<div id="major-publishing-actions">
<div id="publishing-action">
<span class="spinner"></span>
<input type="submit" name="save_survey"
value="保存问卷" class="button button-primary button-large">
</div>
<div class="clear"></div>
</div>
</div>
</div>
</div>
<div class="postbox">
<h2 class="hndle">问卷短码</h2>
<div class="inside">
<p>将以下短码插入到文章或页面中显示此问卷:</p>
<input type="text" value="[custom_survey id='<?php echo $survey_id; ?>']"
class="large-text code" readonly onclick="this.select();">
<p class="description">复制此短码并粘贴到任何文章或页面中</p>
</div>
</div>
<div class="postbox">
<h2 class="hndle">问卷设置</h2>
<div class="inside">
<table class="form-table">
<tr>
<th><label for="allow_anonymous">允许匿名提交</label></th>
<td>
<input type="checkbox" id="allow_anonymous" name="allow_anonymous" value="1" checked>
</td>
</tr>
<tr>
<th><label for="limit_one_response">限制每人提交一次</label></th>
<td>
<input type="checkbox" id="limit_one_response" name="limit_one_response" value="1">
</td>
</tr>
<tr>
<th><label for="show_progress">显示进度条</label></th>
<td>
<input type="checkbox" id="show_progress" name="show_progress" value="1" checked>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<?php
}
private function render_question_editor($question, $index) {
$options = json_decode($question->options, true);
?>
<div class="question-editor" data-index="<?php echo $index; ?>" data-id="<?php echo $question->id; ?>">
<div class="question-header">
<span class="question-number">问题 <?php echo $index + 1; ?></span>
<span class="question-type-badge"><?php echo $this->get_question_type_label($question->question_type); ?></span>
<button type="button" class="delete-question" title="删除问题">
<span class="dashicons dashicons-trash"></span>
</button>
<button type="button" class="toggle-question" title="展开/收起">
<span class="dashicons dashicons-arrow-down"></span>
</button>
</div>
<div class="question-body">
<div class="question-main">
<input type="hidden" name="questions[<?php echo $index; ?>][id]" value="<?php echo $question->id; ?>">
<input type="hidden" name="questions[<?php echo $index; ?>][type]" value="<?php echo $question->question_type; ?>">
<div class="form-field">
<label>问题内容</label>
<input type="text" name="questions[<?php echo $index; ?>][text]"
value="<?php echo esc_attr($question->question_text); ?>"
class="regular-text question-text" required>
</div>
<div class="form-field">
<label>
<input type="checkbox" name="questions[<?php echo $index; ?>][required]" value="1"
<?php checked($question->required, 1); ?>> 必填问题
</label>
</div>
<!-- 选项配置区域(根据问题类型显示) -->
<div class="question-options" data-type="<?php echo $question->question_type; ?>">
<?php $this->render_question_options($question->question_type, $options, $index); ?>
</div>
</div>
</div>
</div>
<?php
}
private function render_question_options($type, $options, $index) {
switch ($type) {
case 'radio':
case 'checkbox':
case 'select':
?>
<div class="form-field">
<label>选项(每行一个)</label>
<textarea name="questions[<?php echo $index; ?>][options]"
rows="5" class="large-text"><?php
if (is_array($options)) {
echo implode("n", $options);
}
?></textarea>
<p class="description">每个选项单独一行</p>
</div>
<?php
break;
case 'rating':
$min = $options['min'] ?? 1;
$max = $options['max'] ?? 5;
$labels = $options['labels'] ?? array();
?>
