完整的WordPress表单生成插件,支持可视化创建和管理表单-资源论坛-小武站

完整的WordPress表单生成插件,支持可视化创建和管理表单

这个完整版本的表单生成器插件包含了以下关键改进:

 

  1. 完善的错误处理机制:使用数据库事务确保数据一致性,任何步骤失败都会回滚操作,避免部分数据入库。
  2. 增强的安全性
    • 所有用户输入都经过严格清洗和验证
    • 使用wp_verify_nonce进行安全验证,替代了可能导致问题check_admin_referrer
    • 明确指定数据库字段格式,防止 SQL 注入风险
    • 详细的错误提示信息,帮助用户快速定位问题
    • 表单验证失败时保留已输入的数据,避免重复填写
    • 清晰的操作指引和提示信息
  3. 功能完整性

 

安装方法与之前相同,将代码保存为wp-form-builder.PHP并放在wp-content/plugins/wp-form-builder/目录下,然后在 WordPress 后台激活即可。如果遇到任何问题,可以根据错误提示排查或提供具体错误信息以便进一步调试

<?PHP
/*
Plugin Name: 简易表单生成器
Plugin URI: https://example.com/
DescrIPtion: 可视化表单创建工具,支持多种字段类型和数据管理
Version: 1.0
Author: Your Name
Author URI: https://example.com/
License: GPL2
*/

if (!defined('ABSPATH')) {
    exit;
}

// 插件常量
define('WPFB_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WPFB_PLUGIN_URL', plugin_dir_url(__FILE__));
define('WPFB_DB_VERSION', '1.0');

// 激活插件时创建数据库表
register_activation_hook(__FILE__, 'wpfb_activate');
function wpfb_activate() {
    global $wpdb;
    
    // 创建表单表
    $forms_table = $wpdb->prefix . 'wpfb_forms';
    // 创建表单字段表
    $fields_table = $wpdb->prefix . 'wpfb_fields';
    // 创建表单提交数据表
    $entries_table = $wpdb->prefix . 'wpfb_entries';
    // 创建表单提交数据详情表
    $entry_detAIls_table = $wpdb->prefix . 'wpfb_entry_details';
    
    $charset_collate = $wpdb->get_charset_collate();
    
    // 表单表SQL
    $sql_forms = "CREATE TABLE $forms_table (
        id medIUmint(9) NOT NULL AUTO_INCREMENT,
        name varchar(255) NOT NULL,
        descrIPtion text,
        settings text NOT NULL,
        created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY  (id)
    ) $charset_collate;";
    
    // 表单字段表SQL
    $sql_fields = "CREATE TABLE $fields_table (
        id medIUmint(9) NOT NULL AUTO_INCREMENT,
        form_id mediumint(9) NOT NULL,
        type varchar(50) NOT NULL,
        label varchar(255) NOT NULL,
        name varchar(100) NOT NULL,
        placeholder text,
        default_value text,
        options text,
        is_required tinyint(1) NOT NULL DEFAULT 0,
        validation_rule varchar(100),
        CSS_class varchar(255),
        sort_order medIUmint(9) NOT NULL DEFAULT 0,
        PRIMARY KEY  (id),
        KEY form_id (form_id)
    ) $charset_collate;";
    
    // 表单提交数据表SQL
    $sql_entries = "CREATE TABLE $entries_table (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        form_id mediumint(9) NOT NULL,
        user_id bigint(20) DEFAULT NULL,
        IP_address varchar(45) NOT NULL,
        created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY  (id),
        KEY form_id (form_id),
        KEY created_at (created_at)
    ) $charset_collate;";
    
    // 表单提交数据详情表SQL
    $sql_entry_detAIls = "CREATE TABLE $entry_details_table (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        entry_id mediumint(9) NOT NULL,
        field_id mediumint(9) NOT NULL,
        field_name varchar(100) NOT NULL,
        value longtext NOT NULL,
        PRIMARY KEY  (id),
        KEY entry_id (entry_id),
        KEY field_id (field_id)
    ) $charset_collate;";
    
    require_once(ABSPATH . 'wp-admin/includes/upgrade.PHP');
    dbDelta($sql_forms);
    dbDelta($sql_fields);
    dbDelta($sql_entries);
    dbDelta($sql_entry_detAIls);
    
    add_option('wpfb_db_version', WPFB_DB_VERSION);
    
    // 添加默认设置
    add_option('wpfb_settings', array(
        'default_email' => get_option('admin_email'),
        'email_subject' => '新的表单提交 - {form_name}',
        'email_template' => "您有一个新的表单提交:\n\n{form_data}\n\n提交时间:{submission_date}"
    ));
}

// 添加管理菜单
add_action('admin_menu', 'wpfb_add_admin_menu');
function wpfb_add_admin_menu() {
    add_menu_page(
        '表单生成器',
        '表单生成器',
        'manage_options',
        'wp-form-builder',
        'wpfb_render_forms_list',
        'dashicons-welcome-write-blog',
        25
    );
    
    add_submenu_page(
        'wp-form-builder',
        '所有表单',
        '所有表单',
        'manage_options',
        'wp-form-builder',
        'wpfb_render_forms_list'
    );
    
    add_submenu_page(
        'wp-form-builder',
        '添加新表单',
        '添加新表单',
        'manage_options',
        'wp-form-builder-add',
        'wpfb_render_form_Editor'
    );
    
    add_submenu_page(
        'wp-form-builder',
        '表单设置',
        '设置',
        'manage_options',
        'wp-form-builder-settings',
        'wpfb_render_settings'
    );
}

// 添加表单提交查看页面
add_action('admin_menu', 'wpfb_add_entries_menu');
function wpfb_add_entries_menu() {
    add_submenu_page(
        null, // 不在菜单中显示,通过链接访问
        '表单提交',
        '表单提交',
        'manage_options',
        'wp-form-builder-entries',
        'wpfb_render_entries_list'
    );
}

// 注册短代码
add_shortcode('wp_form', 'wpfb_render_form_shortcode');
function wpfb_render_form_shortcode($atts) {
    $atts = shortcode_atts(array(
        'id' => 0
    ), $atts);
    
    $form_id = intval($atts['id']);
    if ($form_id <= 0) {
        return '<div class="wpfb-error">表单ID无效</div>';
    }
    
    // 检查表单是否存在
    global $wpdb;
    $forms_table = $wpdb->prefix . 'wpfb_forms';
    $form = $wpdb->get_row(
        $wpdb->prepare("SELECT * FROM $forms_table WHERE id = %d", $form_id)
    );
    
    if (!$form) {
        return '<div class="wpfb-error">表单不存在</div>';
    }
    
    // 获取表单字段
    $fields_table = $wpdb->prefix . 'wpfb_fields';
    $fields = $wpdb->get_results(
        $wpdb->prepare("SELECT * FROM $fields_table WHERE form_id = %d ORDER BY sort_order ASC", $form_id)
    );
    
    if (empty($fields)) {
        return '<div class="wpfb-error">表单没有添加任何字段</div>';
    }
    
    // 处理表单提交
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['wpfb_form_id']) && $_POST['wpfb_form_id'] == $form_id) {
        return wpfb_Process_form_submission($form_id, $form, $fields);
    }
    
    // 渲染表单
    ob_start();
    wpfb_render_form_HTML($form_id, $fields);
    return ob_get_clean();
}

// 渲染表单HTML
function wpfb_render_form_html($form_id, $fields) {
    $form_settings = maybe_unserialize(get_option('wpfb_settings'));
    ?>
    <div class="wpfb-form">
        <form method="post" enctype="multipart/form-data" class="wpfb-form-element">
            <?php wp_nonce_field('wpfb_form_submit_' . $form_id, 'wpfb_nonce'); ?>
            <input type="hidden" name="wpfb_form_id" value="<?php echo esc_attr($form_id); ?>">
            
            <?php foreach ($fields as $field) : ?>
                <?php $field_options = maybe_unserialize($field->options); ?>
                <div class="wpfb-field wpfb-field-<?php echo esc_attr($field->type); ?> <?php echo esc_attr($field->CSS_class); ?>">
                    <label for="wpfb-field-<?php echo esc_attr($field->id); ?>">
                        <?php echo esc_html($field->label); ?>
                        <?php if ($field->is_required) : ?>
                            <span class="wpfb-required">*</span>
                        <?php endif; ?>
                    </label>
                    
                    <?php switch ($field->type) :
                        case 'text':
                        case 'email':
                        case 'url':
                        case 'number':
                        case 'tel': ?>
                            <input 
                                type="<?php echo esc_attr($field->type); ?>" 
                                id="wpfb-field-<?php echo esc_attr($field->id); ?>" 
                                name="wpfb_fields[<?php echo esc_attr($field->id); ?>]" 
                                placeholder="<?php echo esc_attr($field->placeholder); ?>" 
                                value="<?php echo esc_attr($field->default_value); ?>"
                                class="wpfb-input"
                                <?php if ($field->is_required) echo 'required'; ?>
                            >
                            <?php break;
                            
                        case 'textarea': ?>
                            <textarea 
                                id="wpfb-field-<?php echo esc_attr($field->id); ?>" 
                                name="wpfb_fields[<?php echo esc_attr($field->id); ?>]" 
                                placeholder="<?php echo esc_attr($field->placeholder); ?>"
                                class="wpfb-textarea"
                                <?php if ($field->is_required) echo 'required'; ?>
                                rows="4"><?php echo esc_textarea($field->default_value); ?></textarea>
                            <?php break;
                            
                        case 'select': ?>
                            <select 
                                id="wpfb-field-<?php echo esc_attr($field->id); ?>" 
                                name="wpfb_fields[<?php echo esc_attr($field->id); ?>]"
                                class="wpfb-select"
                                <?php if ($field->is_required) echo 'required'; ?>
                            >
                                <?php if (!empty($field_options['include_blank'])) : ?>
                                    <option value="">请选择</option>
                                <?php endif; ?>
                                <?php if (!empty($field_options['options'])) :
                                    foreach ($field_options['options'] as $option) : ?>
                                        <option value="<?php echo esc_attr($option['value']); ?>" 
                                            <?php echo $field->default_value == $option['value'] ? 'selected' : ''; ?>>
                                            <?php echo esc_html($option['label']); ?>
                                        </option>
                                    <?php endforeach;
                                endif; ?>
                            </select>
                            <?php break;
                            
                        case 'radio': ?>
                            <div class="wpfb-radio-group">
                                <?php if (!empty($field_options['options'])) :
                                    foreach ($field_options['options'] as $option) : ?>
                                        <label class="wpfb-radio-label">
                                            <input 
                                                type="radio" 
                                                name="wpfb_fields[<?php echo esc_attr($field->id); ?>]" 
                                                value="<?php echo esc_attr($option['value']); ?>"
                                                <?php echo $field->default_value == $option['value'] ? 'checked' : ''; ?>
                                                <?php if ($field->is_required) echo 'required'; ?>
                                            >
                                            <?php echo esc_html($option['label']); ?>
                                        </label>
                                    <?php endforeach;
                                endif; ?>
                            </div>
                            <?php break;
                            
                        case 'checkbox': ?>
                            <div class="wpfb-checkbox-group">
                                <?php if (!empty($field_options['options'])) :
                                    foreach ($field_options['options'] as $option) : 
                                        $checked = false;
                                        if (!empty($field->default_value)) {
                                            $checked = in_array($option['value'], (array)maybe_unserialize($field->default_value));
                                        }
                                        ?>
                                        <label class="wpfb-checkbox-label">
                                            <input 
                                                type="checkbox" 
                                                name="wpfb_fields[<?php echo esc_attr($field->id); ?>][]" 
                                                value="<?php echo esc_attr($option['value']); ?>"
                                                <?php echo $checked ? 'checked' : ''; ?>
                                            >
                                            <?php echo esc_html($option['label']); ?>
                                        </label>
                                    <?php endforeach;
                                endif; ?>
                                <?php if ($field->is_required) : ?>
                                    <input type="hidden" name="wpfb_fields[<?php echo esc_attr($field->id); ?>]_required" value="1">
                                <?php endif; ?>
                            </div>
                            <?php break;
                            
                        case 'file': ?>
                            <input 
                                type="file" 
                                id="wpfb-field-<?php echo esc_attr($field->id); ?>" 
                                name="wpfb_fields[<?php echo esc_attr($field->id); ?>]"
                                class="wpfb-file"
                                <?php if ($field->is_required) echo 'required'; ?>
                                <?php if (!empty($field_options['allowed_types'])) :
                                    $accept = implode(',', $field_options['allowed_types']);
                                    echo 'accept="' . esc_attr($accept) . '"';
                                endif; ?>
                            >
                            <?php if (!empty($field_options['allowed_types'])) : ?>
                                <div class="wpfb-file-info">
                                    允许的文件类型: <?php echo esc_html(implode(', ', $field_options['allowed_types'])); ?>
                                </div>
                            <?php endif; ?>
                            <?php break;
                            
                        case 'date': ?>
                            <input 
                                type="date" 
                                id="wpfb-field-<?php echo esc_attr($field->id); ?>" 
                                name="wpfb_fields[<?php echo esc_attr($field->id); ?>]" 
                                value="<?php echo esc_attr($field->default_value); ?>"
                                class="wpfb-input"
                                <?php if ($field->is_required) echo 'required'; ?>
                            >
                            <?php break;
                    endswitch; ?>
                    
                    <?php if (!empty($field->validation_rule)) : ?>
                        <input type="hidden" class="wpfb-validation-rule" value="<?php echo esc_attr($field->validation_rule); ?>">
                    <?php endif; ?>
                </div>
            <?php endforeach; ?>
            
            <div class="wpfb-submit">
                <button type="submit" class="wpfb-submit-button"><?php echo esc_html('提交', 'wp-form-builder'); ?></button>
            </div>
        </form>
    </div>
    
    <style>
    .wpfb-form {
        max-width: 600px;
        margin: 20px auto;
    }
    
    .wpfb-field {
        margin-bottom: 20px;
    }
    
    .wpfb-field label {
        display: block;
        margin-bottom: 8px;
        font-weight: 600;
    }
    
    .wpfb-required {
        color: #dc3232;
    }
    
    .wpfb-input, .wpfb-textarea, .wpfb-select {
        width: 100%;
        padding: 8px 12px;
        border: 1px solid #ddd;
        border-radius: 4px;
        font-size: 16px;
    }
    
    .wpfb-textarea {
        resize: vertical;
    }
    
    .wpfb-radio-group, .wpfb-checkbox-group {
        display: flex;
        flex-direction: column;
        gap: 8px;
    }
    
    .wpfb-radio-label, .wpfb-checkbox-label {
        display: flex;
        align-items: center;
        gap: 8px;
        font-weight: normal;
    }
    
    .wpfb-submit-button {
        background: #007cba;
        color: white;
        border: none;
        padding: 10px 20px;
        border-radius: 4px;
        font-size: 16px;
        cursor: pointer;
    }
    
    .wpfb-submit-button:hover {
        background: #006ba1;
    }
    
    .wpfb-success {
        background: #46b450;
        color: white;
        padding: 15px;
        border-radius: 4px;
        margin-bottom: 20px;
    }
    
    .wpfb-error {
        background: #dc3232;
        color: white;
        padding: 15px;
        border-radius: 4px;
        margin-bottom: 20px;
    }
    
    .wpfb-file-info {
        margin-top: 8px;
        font-size: 14px;
        color: #666;
    }
    </style>
    
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        const form = document.querySelector('.wpfb-form-element');
        if (!form) return;
        
        form.addEventListener('submit', function(e) {
            let isValid = true;
            
            // 检查必填的复选框组
            document.querySelectorAll('.wpfb-field-checkbox').forEach(field => {
                const requiredInput = field.querySelector('input[name$="_required"]');
                if (requiredInput) {
                    const checkboxes = field.querySelectorAll('input[type="checkbox"]');
                    const checked = Array.from(checkboxes).some(checkbox => checkbox.checked);
                    
                    if (!checked) {
                        isValid = false;
                        alert('请至少选择一个' + field.querySelector('label').textContent.replace('*', ''));
                    }
                }
            });
            
            if (!isValid) {
                e.preventDefault();
            }
        });
    });
    </script>
    <?php
}

// 处理表单提交
function wpfb_Process_form_submission($form_id, $form, $fields) {
    // 验证nonce
    if (!isset($_POST['wpfb_nonce']) || !wp_verify_nonce($_POST['wpfb_nonce'], 'wpfb_form_submit_' . $form_id)) {
        return '<div class="wpfb-error">安全验证失败,请重试</div>';
    }
    
    // 验证字段数据
    $field_data = isset($_POST['wpfb_fields']) ? $_POST['wpfb_fields'] : array();
    $uploaded_files = isset($_FILES['wpfb_fields']) ? $_FILES['wpfb_fields'] : array();
    
    // 保存表单提交
    global $wpdb;
    $entries_table = $wpdb->prefix . 'wpfb_entries';
    $entry_details_table = $wpdb->prefix . 'wpfb_entry_details';
    
    // 获取用户ID和IP
    $user_id = get_current_user_id();
    $ip_address = wpfb_get_ip_address();
    
    // 插入主记录
    $entry_id = $wpdb->insert(
        $entries_table,
        array(
            'form_id' => $form_id,
            'user_id' => $user_id ? $user_id : null,
            'ip_address' => $ip_address
        )
    );
    
    $entry_id = $wpdb->insert_id;
    
    // 处理每个字段
    $form_data = array();
    
    foreach ($fields as $field) {
        $field_value = '';
        
        // 处理普通字段
        if (isset($field_data[$field->id])) {
            if (is_array($field_data[$field->id])) {
                $field_value = implode(', ', $field_data[$field->id]);
            } else {
                $field_value = sanitize_text_field($field_data[$field->id]);
            }
        }
        
        // 处理文件上传
        if ($field->type == 'file' && isset($uploaded_files['name'][$field->id]) && $uploaded_files['name'][$field->id]) {
            $field_value = wpfb_handle_file_upload($field->id, $uploaded_files);
        }
        
        // 验证必填字段
        if ($field->is_required && empty($field_value)) {
            // 删除已插入的记录
            $wpdb->delete($entries_table, array('id' => $entry_id));
            return '<div class="wpfb-error">"' . esc_html($field->label) . '" 是必填项,请填写</div>';
        }
        
        // 验证字段格式
        if (!empty($field->validation_rule) && !empty($field_value)) {
            if (!wpfb_validate_field($field_value, $field->validation_rule)) {
                // 删除已插入的记录
                $wpdb->delete($entries_table, array('id' => $entry_id));
                return '<div class="wpfb-error">"' . esc_html($field->label) . '" 格式不正确</div>';
            }
        }
        
        // 保存字段值
        $wpdb->insert(
            $entry_details_table,
            array(
                'entry_id' => $entry_id,
                'field_id' => $field->id,
                'field_name' => $field->name,
                'value' => $field_value
            )
        );
        
        $form_data[$field->label] = $field_value;
    }
    
    // 发送邮件通知
    wpfb_send_notification_email($form, $form_data);
    
    // 获取表单设置
    $form_settings = maybe_unserialize($form->settings);
    
    // 显示成功消息或跳转
    if (!empty($form_settings['success_redirect'])) {
        wp_redirect($form_settings['success_redirect']);
        exit;
    } else {
        $success_message = !empty($form_settings['success_message']) 
            ? $form_settings['success_message'] 
            : '表单提交成功,感谢您的反馈!';
        
        return '<div class="wpfb-success">' . wpautop(wp_kses_post($success_message)) . '</div>';
    }
}

// 处理文件上传
function wpfb_handle_file_upload($field_id, $files) {
    // 创建上传目录
    $upload_dir = wp_upload_dir();
    $target_dir = $upload_dir['basedir'] . '/wp-form-builder/';
    
    if (!file_exists($target_dir)) {
        mkdir($target_dir, 0755, true);
    }
    
    $file_name = $files['name'][$field_id];
    $file_tmp = $files['tmp_name'][$field_id];
    $file_size = $files['size'][$field_id];
    $file_error = $files['error'][$field_id];
    
    // 检查错误
    if ($file_error !== UPLOAD_ERR_OK) {
        return '上传错误: ' . $file_error;
    }
    
    // 生成唯一文件名
    $file_ext = pathinfo($file_name, PATHINFO_EXTENSION);
    $unique_name = uniqid() . '.' . $file_ext;
    $target_path = $target_dir . $unique_name;
    
    // 移动文件
    if (move_uploaded_file($file_tmp, $target_path)) {
        // 返回相对URL
        return $upload_dir['baseurl'] . '/wp-form-builder/' . $unique_name;
    } else {
        return '文件上传失败';
    }
}

// 字段验证
function wpfb_validate_field($value, $rule) {
    switch ($rule) {
        case 'email':
            return is_email($value);
        case 'url':
            return filter_var($value, FILTER_VALIDATE_URL) !== false;
        case 'number':
            return is_numeric($value);
        case 'phone':
            // 简单的手机号验证
            return preg_match('/^[\d\+\-\(\) ]+$/', $value);
        case 'custom':
            // 可以添加自定义正则验证
            return true;
        default:
            return true;
    }
}

// 发送通知邮件
function wpfb_send_notification_email($form, $form_data) {
    $settings = get_option('wpfb_settings');
    $to = $settings['default_email'];
    
    // 替换邮件主题变量
    $subject = str_replace('{form_name}', $form->name, $settings['email_subject']);
    
    // 准备表单数据文本
    $form_data_text = '';
    foreach ($form_data as $label => $value) {
        $form_data_text .= $label . ': ' . $value . "\n";
    }
    
    // 替换邮件内容变量
    $message = str_replace(
        array('{form_name}', '{form_data}', '{submission_date}'),
        array($form->name, $form_data_text, date('Y-m-d H:i:s')),
        $settings['email_template']
    );
    
    // 发送邮件
    wp_mail($to, $subject, $message);
}

// 获取用户IP地址
function wpfb_get_ip_address() {
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        return sanitize_text_field($_SERVER['HTTP_CLIENT_IP']);
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        return sanitize_text_field(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]);
    } else {
        return sanitize_text_field($_SERVER['REMOTE_ADDR'] ?? 'unknown');
    }
}

// 渲染表单列表页面
function wpfb_render_forms_list() {
    global $wpdb;
    $forms_table = $wpdb->prefix . 'wpfb_forms';
    
    // 处理删除表单
    if (isset($_GET['action']) && $_GET['action'] == 'delete' && isset($_GET['id']) && wp_verify_nonce($_GET['nonce'], 'wpfb_delete_form')) {
        $form_id = intval($_GET['id']);
        
        // 删除表单及其相关数据
        $fields_table = $wpdb->prefix . 'wpfb_fields';
        $entries_table = $wpdb->prefix . 'wpfb_entries';
        $entry_details_table = $wpdb->prefix . 'wpfb_entry_details';
        
        $wpdb->delete($entry_details_table, array('field_id' => $form_id), array('%d'));
        $wpdb->delete($entries_table, array('form_id' => $form_id), array('%d'));
        $wpdb->delete($fields_table, array('form_id' => $form_id), array('%d'));
        $wpdb->delete($forms_table, array('id' => $form_id), array('%d'));
        
        echo '<div class="notice notice-success"><p>表单已成功删除</p></div>';
    }
    
    // 获取所有表单
    $forms = $wpdb->get_results("SELECT * FROM $forms_table ORDER BY created_at DESC");
    
    ?>
    <div class="wrap">
        <h1 class="wp-heading-inline">所有表单</h1>
        <a href="?page=wp-form-builder-add" class="page-title-action">添加新表单</a>
        
        <hr class="wp-header-end">
        
        <?php if (!empty($forms)) : ?>
            <table class="wp-list-table widefat fixed striped">
                <thead>
                    <tr>
                        <th>表单名称</th>
                        <th>创建日期</th>
                        <th>最后更新</th>
                        <th>短代码</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($forms as $form) : ?>
                        <tr>
                            <td>
                                <strong><?php echo esc_html($form->name); ?></strong>
                                <div class="row-actions">
                                    <span class="edit"><a href="?page=wp-form-builder-add&form_id=<?php echo $form->id; ?>">编辑</a> | </span>
                                    <span class="entries"><a href="?page=wp-form-builder-entries&form_id=<?php echo $form->id; ?>">查看提交 (<?php echo wpfb_get_entry_count($form->id); ?>)</a> | </span>
                                    <span class="delete"><a href="?page=wp-form-builder&action=delete&id=<?php echo $form->id; ?>&nonce=<?php echo wp_create_nonce('wpfb_delete_form'); ?>" class="delete" onclick="return confirm('确定要删除这个表单吗?相关数据也会被删除。')">删除</a></span>
                                </div>
                            </td>
                            <td><?php echo date('Y-m-d', strtotime($form->created_at)); ?></td>
                            <td><?php echo date('Y-m-d', strtotime($form->updated_at)); ?></td>
                            <td><code>[wp_form id="<?php echo $form->id; ?>"]</code></td>
                            <td>
                                <a href="?page=wp-form-builder-add&form_id=<?php echo $form->id; ?>" class="button button-small">编辑</a>
                                <a href="?page=wp-form-builder-entries&form_id=<?php echo $form->id; ?>" class="button button-small">查看提交</a>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
        <?php else : ?>
            <div class="notice notice-info">
                <p>还没有创建任何表单。<a href="?page=wp-form-builder-add">点击这里创建第一个表单</a></p>
            </div>
        <?php endif; ?>
    </div>
    <?php
}

// 获取表单提交数量
function wpfb_get_entry_count($form_id) {
    global $wpdb;
    $entries_table = $wpdb->prefix . 'wpfb_entries';
    
    return $wpdb->get_var(
        $wpdb->prepare("SELECT COUNT(*) FROM $entries_table WHERE form_id = %d", $form_id)
    );
}

// 渲染表单编辑器
function wpfb_render_form_editor() {
    global $wpdb;
    $forms_table = $wpdb->prefix . 'wpfb_forms';
    $fields_table = $wpdb->prefix . 'wpfb_fields';
    
    $form_id = isset($_GET['form_id']) ? intval($_GET['form_id']) : 0;
    $form = null;
    $fields = array();
    
    // 加载现有表单
    if ($form_id > 0) {
        $form = $wpdb->get_row(
            $wpdb->prepare("SELECT * FROM $forms_table WHERE id = %d", $form_id)
        );
        
        if ($form) {
            $form->settings = maybe_unserialize($form->settings);
            $fields = $wpdb->get_results(
                $wpdb->prepare("SELECT * FROM $fields_table WHERE form_id = %d ORDER BY sort_order ASC", $form_id)
            );
        } else {
            echo '<div class="notice notice-error"><p>表单不存在</p></div>';
            $form_id = 0;
        }
    }
    
    // 保存表单逻辑 - 增加错误处理和严格验证
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['wpfb_save_form']) && isset($_POST['wpfb_nonce'])) {
        // 安全验证
        if (!wp_verify_nonce($_POST['wpfb_nonce'], 'wpfb_save_form')) {
            wp_die('安全验证失败,请刷新页面重试。');
        }

        // 1. 严格验证必填字段,避免空值入库
        if (empty($_POST['form_name'])) {
            echo '<div class="notice notice-error"><p>表单名称不能为空</p></div>';
            // 不执行后续保存逻辑
            // 继续执行以保持表单数据
        } else {
            // 2. 数据清洗
            $form_name = sanitize_text_field($_POST['form_name']);
            $form_description = sanitize_textarea_field($_POST['form_description'] ?? '');
            $form_settings = array(
                'success_message' => wp_kses_post($_POST['success_message'] ?? '表单提交成功!'),
                'success_redirect' => esc_url_raw($_POST['success_redirect'] ?? ''),
                'send_email' => isset($_POST['send_email']) ? 1 : 0,
                'email_to' => sanitize_email($_POST['email_to'] ?? get_option('admin_email'))
            );

            // 3. 数据库操作增加错误处理
            $save_success = false;

            // 开始事务
            $wpdb->query('START TRANSACTION');

            try {
                // 保存表单基本信息
                if ($form_id > 0) {
                    // 更新现有表单
                    $updated = $wpdb->update(
                        $forms_table,
                        array(
                            'name' => $form_name,
                            'description' => $form_description,
                            'settings' => maybe_serialize($form_settings),
                            'updated_at' => current_time('MySQL')
                        ),
                        array('id' => $form_id),
                        array('%s', '%s', '%s', '%s'),
                        array('%d')
                    );

                    if ($updated === false) {
                        throw new Exception('更新表单失败:' . $wpdb->last_error);
                    }
                } else {
                    // 创建新表单
                    $inserted = $wpdb->insert(
                        $forms_table,
                        array(
                            'name' => $form_name,
                            'description' => $form_description,
                            'settings' => maybe_serialize($form_settings),
                            'created_at' => current_time('mysql'),
                            'updated_at' => current_time('mysql')
                        ),
                        array('%s', '%s', '%s', '%s', '%s')
                    );

                    if ($inserted === false) {
                        throw new Exception('创建表单失败:' . $wpdb->last_error);
                    }
                    $form_id = $wpdb->insert_id;

                    if (empty($form_id)) {
                        throw new Exception('无法获取新表单ID');
                    }
                }

                // 删除现有字段
                $deleted = $wpdb->delete(
                    $fields_table,
                    array('form_id' => $form_id),
                    array('%d')
                );

                if ($deleted === false) {
                    throw new Exception('删除旧字段失败:' . $wpdb->last_error);
                }

                // 保存新字段
                if (isset($_POST['fields']) && is_array($_POST['fields']) && !empty($_POST['fields'])) {
                    foreach ($_POST['fields'] as $index => $field_data) {
                        if (empty($field_data['label'])) {
                            throw new Exception('字段标签不能为空(第' . ($index + 1) . '个字段)');
                        }

                        $field_type = sanitize_text_field($field_data['type'] ?? 'text');
                        $field_label = sanitize_text_field($field_data['label']);
                        $field_name = sanitize_title($field_label);
                        $field_placeholder = sanitize_text_field($field_data['placeholder'] ?? '');
                        $field_default = sanitize_text_field($field_data['default_value'] ?? '');
                        $field_is_required = isset($field_data['is_required']) ? 1 : 0;
                        $field_validation = sanitize_text_field($field_data['validation'] ?? '');
                        $field_CSS = sanitize_text_field($field_data['css_class'] ?? '');

                        // 处理字段选项
                        $field_options = array();
                        switch ($field_type) {
                            case 'select':
                            case 'radio':
                            case 'checkbox':
                                $field_options['include_blank'] = isset($field_data['include_blank']) ? 1 : 0;
                                $field_options['options'] = array();

                                if (isset($field_data['options']) && is_array($field_data['options'])) {
                                    foreach ($field_data['options'] as $option) {
                                        if (!empty($option['label'])) {
                                            $field_options['options'][] = array(
                                                'label' => sanitize_text_field($option['label']),
                                                'value' => !empty($option['value']) ? sanitize_text_field($option['value']) : sanitize_title($option['label'])
                                            );
                                        }
                                    }
                                }

                                if (empty($field_options['options'])) {
                                    throw new Exception('“' . $field_label . '”字段至少需要添加一个选项');
                                }
                                break;

                            case 'file':
                                $field_options['allowed_types'] = isset($field_data['allowed_types']) ? array_map('sanitize_text_field', $field_data['allowed_types']) : array('image/*');
                                break;
                        }

                        // 插入字段
                        $field_inserted = $wpdb->insert(
                            $fields_table,
                            array(
                                'form_id' => $form_id,
                                'type' => $field_type,
                                'label' => $field_label,
                                'name' => $field_name,
                                'placeholder' => $field_placeholder,
                                'default_value' => $field_default,
                                'options' => maybe_serialize($field_options),
                                'is_required' => $field_is_required,
                                'validation_rule' => $field_validation,
                                'css_class' => $field_css,
                                'sort_order' => (int)$index
                            ),
                            array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%s', '%d')
                        );

                        if ($field_inserted === false) {
                            throw new Exception('保存“' . $field_label . '”字段失败:' . $wpdb->last_error);
                        }
                    }
                }

                // 所有操作成功,提交事务
                $wpdb->query('COMMIT');
                $save_success = true;
                echo '<div class="notice notice-success"><p>表单已成功保存</p></div>';

            } catch (Exception $e) {
                // 操作失败,回滚事务
                $wpdb->query('ROLLBACK');
                echo '<div class="notice notice-error"><p>保存失败:' . esc_HTML($e->getMessage()) . '</p></div>';
            }

            // 重新加载数据
            if ($save_success && $form_id > 0) {
                $form = $wpdb->get_row(
                    $wpdb->prepare("SELECT * FROM $forms_table WHERE id = %d", $form_id)
                );
                if ($form) {
                    $form->settings = maybe_unserialize($form->settings);
                    $fields = $wpdb->get_results(
                        $wpdb->prepare("SELECT * FROM $fields_table WHERE form_id = %d ORDER BY sort_order ASC", $form_id)
                    );
                } else {
                    echo '<div class="notice notice-warning"><p>表单保存成功,但加载数据时出错</p></div>';
                }
            }
        }
    }
    
    // 可用的字段类型
    $field_types = array(
        'text' => '单行文本',
        'textarea' => '多行文本',
        'email' => '邮箱',
        'url' => '网址',
        'number' => '数字',
        'tel' => '电话',
        'select' => '下拉选择',
        'radio' => '单选按钮',
        'checkbox' => '复选框',
        'file' => '文件上传',
        'date' => '日期'
    );
    
    // 可用的验证规则
    $validation_rules = array(
        '' => '无验证',
        'email' => '邮箱格式',
        'url' => '网址格式',
        'number' => '数字格式',
        'phone' => '电话格式'
    );
    
    ?>
    <div class="wrap">
        <h1><?php echo $form_id > 0 ? '编辑表单' : '添加新表单'; ?></h1>
        
        <form method="post" action="">
            <?php wp_nonce_field('wpfb_save_form', 'wpfb_nonce'); ?>
            <input type="hidden" name="form_id" value="<?php echo esc_attr($form_id); ?>">
            
            <div id="poststuff">
                <div id="post-body" class="metabox-holder columns-2">
                    <div id="post-body-content">
                        <!-- 表单基本信息 -->
                        <div class="postbox">
                            <h2 class="hndle"><span>表单基本信息</span></h2>
                            <div class="inside">
                                <table class="form-table">
                                    <tr>
                                        <th scope="row"><label for="form_name">表单名称</label></th>
                                        <td>
                                            <input type="text" id="form_name" name="form_name" 
                                                value="<?php echo $form ? esc_attr($form->name) : ''; ?>" 
                                                class="regular-text" required>
                                            <p class="description">输入表单的名称,将显示在管理界面中</p>
                                        </td>
                                    </tr>
                                    <tr>
                                        <th scope="row"><label for="form_description">表单描述</label></th>
                                        <td>
                                            <textarea id="form_description" name="form_description" 
                                                rows="3" class="regular-text"><?php echo $form ? esc_textarea($form->description) : ''; ?></textarea>
                                            <p class="description">可选,输入表单的描述信息</p>
                                        </td>
                                    </tr>
                                </table>
                            </div>
                        </div>
                        
                        <!-- 表单字段 -->
                        <div class="postbox">
                            <h2 class="hndle">
                                <span>表单字段</span>
                                <button type="button" id="add-field" class="button button-small" style="margin-left: 10px;">添加字段</button>
                            </h2>
                            <div class="inside">
                                <p>添加和配置表单字段。</p>
                                
                                <div id="form-fields">
                                    <?php if (!empty($fields)) :
                                        foreach ($fields as $index => $field) :
                                            $field_options = maybe_unserialize($field->options); ?>
                                            <div class="form-field-item postbox" data-field-type="<?php echo esc_attr($field->type); ?>">
                                                <h3 class="hndle">
                                                    <span class="field-label"><?php echo esc_html($field->label ?: '未命名字段'); ?></span>
                                                    <span class="field-type badge"><?php echo esc_html($field_types[$field->type] ?? $field->type); ?></span>
                                                    <button type="button" class="remove-field button button-link-delete">删除</button>
                                                </h3>
                                                <div class="inside">
                                                    <input type="hidden" name="fields[<?php echo $index; ?>][type]" value="<?php echo esc_attr($field->type); ?>">
                                                    
                                                    <table class="form-table">
                                                        <tr>
                                                            <th scope="row"><label for="fields[<?php echo $index; ?>][label]">字段标签</label></th>
                                                            <td>
                                                                <input type="text" name="fields[<?php echo $index; ?>][label]" 
                                                                    value="<?php echo esc_attr($field->label); ?>" 
                                                                    class="regular-text field-label-input" required>
                                                            </td>
                                                        </tr>
                                                        <tr>
                                                            <th scope="row"><label for="fields[<?php echo $index; ?>][placeholder]">占位文本</label></th>
                                                            <td>
                                                                <input type="text" name="fields[<?php echo $index; ?>][placeholder]" 
                                                                    value="<?php echo esc_attr($field->placeholder); ?>" 
                                                                    class="regular-text">
                                                            </td>
                                                        </tr>
                                                        <tr>
                                                            <th scope="row"><label for="fields[<?php echo $index; ?>][default_value]">默认值</label></th>
                                                            <td>
                                                                <input type="text" name="fields[<?php echo $index; ?>][default_value]" 
                                                                    value="<?php echo esc_attr($field->default_value); ?>" 
                                                                    class="regular-text">
                                                                <p class="description">复选框的默认值需要以逗号分隔</p>
                                                            </td>
                                                        </tr>
                                                        <tr>
                                                            <th scope="row">验证规则</th>
                                                            <td>
                                                                <select name="fields[<?php echo $index; ?>][validation]" class="regular-text">
                                                                    <?php foreach ($validation_rules as $value => $label) : ?>
                                                                        <option value="<?php echo esc_attr($value); ?>" 
                                                                            <?php echo $field->validation_rule == $value ? 'selected' : ''; ?>>
                                                                            <?php echo esc_html($label); ?>
                                                                        </option>
                                                                    <?php endforeach; ?>
                                                                </select>
                                                            </td>
                                                        </tr>
                                                        <tr>
                                                            <th scope="row">CSS类</th>
                                                            <td>
                                                                <input type="text" name="fields[<?php echo $index; ?>][css_class]" 
                                                                    value="<?php echo esc_attr($field->css_class); ?>" 
                                                                    class="regular-text">
                                                                <p class="description">添加自定义CSS类,用于样式调整</p>
                                                            </td>
                                                        </tr>
                                                        <tr>
                                                            <th scope="row">必填项</th>
                                                            <td>
                                                                <label>
                                                                    <input type="checkbox" name="fields[<?php echo $index; ?>][is_required]" 
                                                                        <?php echo $field->is_required ? 'checked' : ''; ?>>
                                                                    设为必填项
                                                                </label>
                                                            </td>
                                                        </tr>
                                                        
                                                        <?php switch ($field->type) :
                                                            case 'select':
                                                            case 'radio':
                                                            case 'checkbox': ?>
                                                                <tr>
                                                                    <th scope="row">选项设置</th>
                                                                    <td>
                                                                        <label>
                                                                            <input type="checkbox" name="fields[<?php echo $index; ?>][include_blank]" 
                                                                                <?php echo !empty($field_options['include_blank']) ? 'checked' : ''; ?>>
                                                                            包含空选项(仅下拉选择)
                                                                        </label>
                                                                        
                                                                        <div class="field-options">
                                                                            <p>选项</p>
                                                                            
                                                                            <div class="options-container">
                                                                                <?php if (!empty($field_options['options'])) :
                                                                                    foreach ($field_options['options'] as $option) : ?>
                                                                                        <div class="option-row">
                                                                                            <input type="text" name="fields[<?php echo $index; ?>][options][][label]" 
                                                                                                value="<?php echo esc_attr($option['label']); ?>" 
                                                                                                placeholder="标签" class="regular-text">
                                                                                            <input type="text" name="fields[<?php echo $index; ?>][options][][value]" 
                                                                                                value="<?php echo esc_attr($option['value']); ?>" 
                                                                                                placeholder="值(可选)" class="regular-text">
                                                                                            <button type="button" class="remove-option button button-link-delete">删除</button>
                                                                                        </div>
                                                                                    <?php endforeach;
                                                                                else : ?>
                                                                                    <div class="option-row">
                                                                                        <input type="text" name="fields[<?php echo $index; ?>][options][][label]" 
                                                                                            placeholder="标签" class="regular-text">
                                                                                        <input type="text" name="fields[<?php echo $index; ?>][options][][value]" 
                                                                                            placeholder="值(可选)" class="regular-text">
                                                                                        <button type="button" class="remove-option button button-link-delete">删除</button>
                                                                                    </div>
                                                                                <?php endif; ?>
                                                                            </div>
                                                                            
                                                                            <button type="button" class="add-option button">添加选项</button>
                                                                        </div>
                                                                    </td>
                                                                </tr>
                                                                <?php break;
                                                                
                                                            case 'file': ?>
                                                                <tr>
                                                                    <th scope="row">文件设置</th>
                                                                    <td>
                                                                        <p>允许的文件类型:</p>
                                                                        <div class="file-types">
                                                                            <label>
                                                                                <input type="checkbox" name="fields[<?php echo $index; ?>][allowed_types][]" 
                                                                                    value="image/*" <?php echo empty($field_options['allowed_types']) || in_array('image/*', $field_options['allowed_types']) ? 'checked' : ''; ?>>
                                                                                图片文件
                                                                            </label>
                                                                            <label>
                                                                                <input type="checkbox" name="fields[<?php echo $index; ?>][allowed_types][]" 
                                                                                    value="APPlication/pdf" <?php echo !empty($field_options['allowed_types']) && in_array('application/pdf', $field_options['allowed_types']) ? 'checked' : ''; ?>>
                                                                                PDF文件
                                                                            </label>
                                                                            <label>
                                                                                <input type="checkbox" name="fields[<?php echo $index; ?>][allowed_types][]" 
                                                                                    value="application/msword,application/vnd.openXMLformats-Officedocument.wordProcessingml.document" <?php echo !empty($field_options['allowed_types']) && in_array('APPlication/msword,application/vnd.openXMLformats-officedocument.wordprocessingml.document', $field_options['allowed_types']) ? 'checked' : ''; ?>>
                                                                                Word文件
                                                                            </label>
                                                                        </div>
                                                                    </td>
                                                                </tr>
                                                                <?php break;
                                                        endswitch; ?>
                                                    </table>
                                                </div>
                                            </div>
                                        <?php endforeach;
                                    else : ?>
                                        <div class="form-field-placeholder">
                                            点击"添加字段"按钮开始创建表单字段
                                        </div>
                                    <?php endif; ?>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <div id="postbox-container-1" class="postbox-container">
                        <!-- 表单设置 -->
                        <div class="postbox">
                            <h2 class="hndle"><span>提交设置</span></h2>
                            <div class="inside">
                                <table class="form-table">
                                    <tr>
                                        <th scope="row"><label for="success_message">成功消息</label></th>
                                        <td>
                                            <textarea id="success_message" name="success_message" 
                                                rows="3" class="regular-text"><?php echo $form && isset($form->settings['success_message']) ? esc_textarea($form->settings['success_message']) : '表单提交成功,感谢您的反馈!'; ?></textarea>
                                            <p class="description">用户提交表单后显示的消息</p>
                                        </td>
                                    </tr>
                                    <tr>
                                        <th scope="row"><label for="success_redirect">跳转URL</label></th>
                                        <td>
                                            <input type="url" id="success_redirect" name="success_redirect" 
                                                value="<?php echo $form && isset($form->settings['success_redirect']) ? esc_attr($form->settings['success_redirect']) : ''; ?>" 
                                                class="regular-text">
                                            <p class="description">可选,提交后跳转的URL,留空则显示成功消息</p>
                                        </td>
                                    </tr>
                                    <tr>
                                        <th scope="row"><label for="send_email">邮件通知</label></th>
                                        <td>
                                            <label>
                                                <input type="checkbox" id="send_email" name="send_email" 
                                                    <?php echo $form && isset($form->settings['send_email']) && $form->settings['send_email'] ? 'checked' : 'checked'; ?>>
                                                提交后发送邮件通知
                                            </label>
                                        </td>
                                    </tr>
                                    <tr>
                                        <th scope="row"><label for="email_to">接收邮箱</label></th>
                                        <td>
                                            <input type="email" id="email_to" name="email_to" 
                                                value="<?php echo $form && isset($form->settings['email_to']) ? esc_attr($form->settings['email_to']) : get_option('admin_email'); ?>" 
                                                class="regular-text">
                                            <p class="description">接收表单提交通知的邮箱地址</p>
                                        </td>
                                    </tr>
                                </table>
                            </div>
                        </div>
                        
                        <!-- 发布区域 -->
                        <div class="postbox">
                            <h2 class="hndle"><span>保存表单</span></h2>
                            <div class="inside">
                                <p class="submit">
                                    <button type="submit" name="wpfb_save_form" class="button button-primary button-large">保存表单</button>
                                    <?php if ($form_id > 0) : ?>
                                        <a href="?page=wp-form-builder" class="button button-secondary">返回列表</a>
                                    <?php endif; ?>
                                </p>
                                
                                <?php if ($form_id > 0) : ?>
                                    <div class="shortcode-info">
                                        <h4>表单短代码</h4>
                                        <p>使用以下短代码在文章或页面中显示表单:</p>
                                        <code>[wp_form id="<?php echo $form_id; ?>"]</code>
                                    </div>
                                <?php endif; ?>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </form>
    </div>
    
    <style>
    .form-field-item {
        margin-bottom: 15px;
    }
    
    .form-field-item .hndle {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
    
    .form-field-placeholder {
        padding: 20px;
        text-align: center;
        color: #666;
        border: 1px dashed #ccc;
        margin: 10px 0;
    }
    
    .field-type {
        font-size: 11px;
        padding: 2px 8px;
        border-radius: 4px;
        background: #f0f0f1;
        color: #3c434a;
        margin-left: 10px;
    }
    
    .option-row {
        display: flex;
        gap: 10px;
        margin-bottom: 10px;
        align-items: center;
    }
    
    .option-row input:first-child {
        flex: 2;
    }
    
    .option-row input:last-child {
        flex: 2;
    }
    
    .file-types {
        display: flex;
        flex-direction: column;
        gap: 8px;
        margin-top: 10px;
    }
    
    .shortcode-info {
        padding: 10px;
        background: #f0f0f1;
        border-radius: 4px;
        margin-top: 15px;
    }
    
    .shortcode-info code {
        display: block;
        padding: 8px;
        background: #fff;
        border: 1px solid #ddd;
        border-radius: 4px;
        margin-top: 5px;
        word-break: break-all;
    }
    </style>
    
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        // 字段计数器
        let fieldCounter = <?php echo count($fields); ?>;
        
        // 添加新字段
        document.getElementById('add-field').addEventListener('click', function() {
            const fieldTypes = <?php echo json_encode($field_types); ?>;
            const validationRules = <?php echo json_encode($validation_rules); ?>;
            
            // 显示字段类型选择对话框
            const fieldType = prompt('请选择字段类型:\n' + Object.values(fieldTypes).join('\n'));
            
            if (!fieldType) return;
            
            // 找到对应的字段类型值
            let fieldTypeKey = '';
            for (const key in fieldTypes) {
                if (fieldTypes[key] === fieldType) {
                    fieldTypeKey = key;
                    break;
                }
            }
            
            if (!fieldTypeKey) {
                alert('无效的字段类型');
                return;
            }
            
            // 创建新字段HTML
            const fieldIndex = fieldCounter++;
            let fieldHtml = `
            <div class="form-field-item postbox" data-field-type="${fieldTypeKey}">
                <h3 class="hndle">
                    <span class="field-label">未命名字段</span>
                    <span class="field-type badge">${fieldType}</span>
                    <button type="button" class="remove-field button button-link-delete">删除</button>
                </h3>
                <div class="inside">
                    <input type="hidden" name="fields[${fieldIndex}][type]" value="${fieldTypeKey}">
                    
                    <table class="form-table">
                        <tr>
                            <th scope="row"><label for="fields[${fieldIndex}][label]">字段标签</label></th>
                            <td>
                                <input type="text" name="fields[${fieldIndex}][label]" 
                                    value="" class="regular-text field-label-input" required>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row"><label for="fields[${fieldIndex}][placeholder]">占位文本</label></th>
                            <td>
                                <input type="text" name="fields[${fieldIndex}][placeholder]" 
                                    value="" class="regular-text">
                            </td>
                        </tr>
                        <tr>
                            <th scope="row"><label for="fields[${fieldIndex}][default_value]">默认值</label></th>
                            <td>
                                <input type="text" name="fields[${fieldIndex}][default_value]" 
                                    value="" class="regular-text">
                                <p class="description">复选框的默认值需要以逗号分隔</p>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row">验证规则</th>
                            <td>
                                <select name="fields[${fieldIndex}][validation]" class="regular-text">
            `;
            
            // 添加验证规则选项
            for (const ruleValue in validationRules) {
                fieldHtml += `<option value="${ruleValue}">${validationRules[ruleValue]}</option>`;
            }
            
            fieldHtml += `
                                </select>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row">CSS类</th>
                            <td>
                                <input type="text" name="fields[${fieldIndex}][css_class]" 
                                    value="" class="regular-text">
                                <p class="description">添加自定义CSS类,用于样式调整</p>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row">必填项</th>
                            <td>
                                <label>
                                    <input type="checkbox" name="fields[${fieldIndex}][is_required]">
                                    设为必填项
                                </label>
                            </td>
                        </tr>
            `;
            
            // 添加特定字段类型的设置
            switch (fieldTypeKey) {
                case 'select':
                case 'radio':
                case 'checkbox':
                    fieldHtml += `
                        <tr>
                            <th scope="row">选项设置</th>
                            <td>
                                <label>
                                    <input type="checkbox" name="fields[${fieldIndex}][include_blank]" 
                                        ${fieldTypeKey === 'select' ? 'checked' : 'disabled'}>
                                    包含空选项(仅下拉选择)
                                </label>
                                
                                <div class="field-options">
                                    <p>选项</p>
                                    
                                    <div class="options-container">
                                        <div class="option-row">
                                            <input type="text" name="fields[${fieldIndex}][options][][label]" 
                                                placeholder="标签" class="regular-text">
                                            <input type="text" name="fields[${fieldIndex}][options][][value]" 
                                                placeholder="值(可选)" class="regular-text">
                                            <button type="button" class="remove-option button button-link-delete">删除</button>
                                        </div>
                                    </div>
                                    
                                    <button type="button" class="add-option button">添加选项</button>
                                </div>
                            </td>
                        </tr>
                    `;
                    break;
                    
                case 'file':
                    fieldHtml += `
                        <tr>
                            <th scope="row">文件设置</th>
                            <td>
                                <p>允许的文件类型:</p>
                                <div class="file-types">
                                    <label>
                                        <input type="checkbox" name="fields[${fieldIndex}][allowed_types][]" 
                                            value="image/*" checked>
                                        图片文件
                                    </label>
                                    <label>
                                        <input type="checkbox" name="fields[${fieldIndex}][allowed_types][]" 
                                            value="APPlication/pdf">
                                        PDF文件
                                    </label>
                                    <label>
                                        <input type="checkbox" name="fields[${fieldIndex}][allowed_types][]" 
                                            value="application/msword,application/vnd.openXMLformats-officedocument.wordprocessingml.document">
                                        Word文件
                                    </label>
                                </div>
                            </td>
                        </tr>
                    `;
                    break;
            }
            
            fieldHtml += `
                    </table>
                </div>
            </div>
            `;
            
            // 添加到字段容器
            const fieldsContainer = document.getElementById('form-fields');
            const placeholder = fieldsContainer.querySelector('.form-field-placeholder');
            
            if (placeholder) {
                fieldsContainer.innerHTML = fieldHtml;
            } else {
                fieldsContainer.insertAdjacentHTML('beforeend', fieldHtml);
            }
            
            // 绑定新添加元素的事件
            bindFieldEvents();
        });
        
        // 绑定字段事件
        function bindFieldEvents() {
            // 删除字段
            document.querySelectorAll('.remove-field').forEach(button => {
                button.addEventListener('click', function() {
                    if (confirm('确定要删除这个字段吗?')) {
                        this.closest('.form-field-item').remove();
                        
                        // 检查是否还有字段
                        checkFieldsPlaceholder();
                    }
                });
            });
            
            // 更新字段标签显示
            document.querySelectorAll('.field-label-input').forEach(input => {
                input.addEventListener('input', function() {
                    const label = this.value || '未命名字段';
                    this.closest('.form-field-item').querySelector('.field-label').textContent = label;
                });
            });
            
            // 添加选项
            document.querySelectorAll('.add-option').forEach(button => {
                button.addEventListener('click', function() {
                    const container = this.parentElement.querySelector('.options-container');
                    
                    const fieldIndex = this.closest('.form-field-item').querySelector('input[name$="[type]"]').name.match(/fields\[(\d+)\]/)[1];
                    
                    const optionHtml = `
                    <div class="option-row">
                        <input type="text" name="fields[${fieldIndex}][options][][label]" 
                            placeholder="标签" class="regular-text">
                        <input type="text" name="fields[${fieldIndex}][options][][value]" 
                            placeholder="值(可选)" class="regular-text">
                        <button type="button" class="remove-option button button-link-delete">删除</button>
                    </div>
                    `;
                    
                    container.insertAdjacentHTML('beforeend', optionHtml);
                    
                    // 绑定删除选项事件
                    container.lastElementChild.querySelector('.remove-option').addEventListener('click', function() {
                        this.closest('.option-row').remove();
                    });
                });
            });
            
            // 删除选项
            document.querySelectorAll('.remove-option').forEach(button => {
                button.addEventListener('click', function() {
                    // 至少保留一个选项
                    const container = this.closest('.options-container');
                    if (container.querySelectorAll('.option-row').length > 1) {
                        this.closest('.option-row').remove();
                    } else {
                        alert('至少需要保留一个选项');
                    }
                });
            });
        }
        
        // 检查是否需要显示占位符
        function checkFieldsPlaceholder() {
            const fieldsContainer = document.getElementById('form-fields');
            const fieldItems = fieldsContainer.querySelectorAll('.form-field-item');
            
            if (fieldItems.length === 0) {
                fieldsContainer.innerHTML = '<div class="form-field-placeholder">点击"添加字段"按钮开始创建表单字段</div>';
            }
        }
        
        // 初始化事件绑定
        bindFieldEvents();
    });
    </script>
    <?php
}

// 渲染表单提交列表
function wpfb_render_entries_list() {
    global $wpdb;
    $entries_table = $wpdb->prefix . 'wpfb_entries';
    $entry_details_table = $wpdb->prefix . 'wpfb_entry_details';
    $forms_table = $wpdb->prefix . 'wpfb_forms';
    $fields_table = $wpdb->prefix . 'wpfb_fields';
    
    $form_id = isset($_GET['form_id']) ? intval($_GET['form_id']) : 0;
    
    if ($form_id <= 0) {
        echo '<div class="wrap"><div class="notice notice-error"><p>表单ID无效</p></div></div>';
        return;
    }
    
    // 获取表单信息
    $form = $wpdb->get_row(
        $wpdb->prepare("SELECT * FROM $forms_table WHERE id = %d", $form_id)
    );
    
    if (!$form) {
        echo '<div class="wrap"><div class="notice notice-error"><p>表单不存在</p></div></div>';
        return;
    }
    
    // 获取表单字段
    $fields = $wpdb->get_results(
        $wpdb->prepare("SELECT id, label, name FROM $fields_table WHERE form_id = %d ORDER BY sort_order ASC", $form_id)
    );
    
    // 处理删除提交
    if (isset($_GET['action']) && $_GET['action'] == 'delete_entry' && isset($_GET['entry_id']) && wp_verify_nonce($_GET['nonce'], 'wpfb_delete_entry')) {
        $entry_id = intval($_GET['entry_id']);
        
        // 删除提交记录
        $wpdb->delete($entry_details_table, array('entry_id' => $entry_id), array('%d'));
        $wpdb->delete($entries_table, array('id' => $entry_id), array('%d'));
        
        echo '<div class="notice notice-success"><p>提交记录已成功删除</p></div>';
    }
    
    // 处理批量删除
    if (isset($_POST['wpfb_bulk_action']) && $_POST['wpfb_bulk_action'] == 'delete' && isset($_POST['entries']) && is_array($_POST['entries'])) {
        // 验证nonce
        if (!wp_verify_nonce($_POST['wpfb_nonce'], 'wpfb_bulk_entries')) {
            wp_die('安全验证失败,请刷新页面重试。');
        }
        
        foreach ($_POST['entries'] as $entry_id) {
            $entry_id = intval($entry_id);
            $wpdb->delete($entry_details_table, array('entry_id' => $entry_id), array('%d'));
            $wpdb->delete($entries_table, array('id' => $entry_id), array('%d'));
        }
        
        echo '<div class="notice notice-success"><p>选中的提交记录已成功删除</p></div>';
    }
    
    // 处理导出
    if (isset($_GET['action']) && $_GET['action'] == 'export_entries' && wp_verify_nonce($_GET['nonce'], 'wpfb_export_entries')) {
        wpfb_export_entries($form_id, $form, $fields);
        exit;
    }
    
    // 获取提交记录
    $entries = $wpdb->get_results(
        $wpdb->prepare("SELECT * FROM $entries_table WHERE form_id = %d ORDER BY created_at DESC", $form_id)
    );
    
    ?>
    <div class="wrap">
        <h1 class="wp-heading-inline">表单提交: <?php echo esc_html($form->name); ?></h1>
        <a href="?page=wp-form-builder" class="page-title-action">返回表单列表</a>
        <a href="?page=wp-form-builder-add&form_id=<?php echo $form_id; ?>" class="page-title-action">编辑表单</a>
        <a href="?page=wp-form-builder-entries&form_id=<?php echo $form_id; ?>&action=export_entries&nonce=<?php echo wp_create_nonce('wpfb_export_entries'); ?>" class="page-title-action">导出CSV</a>
        
        <hr class="wp-header-end">
        
        <?php if (!empty($entries)) : ?>
            <form method="post" action="">
                <?php wp_nonce_field('wpfb_bulk_entries', 'wpfb_nonce'); ?>
                
                <div class="tablenav top">
                    <div class="alignleft actions bulkactions">
                        <select name="wpfb_bulk_action">
                            <option value="">批量操作</option>
                            <option value="delete">删除</option>
                        </select>
                        <input type="submit" class="button action" value="应用">
                    </div>
                    <br class="clear">
                </div>
                
                <table class="wp-list-table widefat fixed striped">
                    <thead>
                        <tr>
                            <th scope="col" class="check-column">
                                <input type="checkbox" id="cb-select-all-1">
                            </th>
                            <th>提交ID</th>
                            <?php foreach ($fields as $field) : ?>
                                <th><?php echo esc_html($field->label); ?></th>
                            <?php endforeach; ?>
                            <th>提交时间</th>
                            <th>IP地址</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($entries as $entry) : 
                            // 获取提交详情
                            $entry_details = $wpdb->get_results(
                                $wpdb->prepare("SELECT field_id, value FROM $entry_details_table WHERE entry_id = %d", $entry->id)
                            );
                            
                            // 构建字段值数组
                            $field_values = array();
                            foreach ($entry_details as $detail) {
                                $field_values[$detail->field_id] = $detail->value;
                            }
                            ?>
                            <tr>
                                <th scope="row" class="check-column">
                                    <input type="checkbox" name="entries[]" value="<?php echo $entry->id; ?>">
                                </th>
                                <td><?php echo $entry->id; ?></td>
                                <?php foreach ($fields as $field) : ?>
                                    <td>
                                        <?php 
                                        $value = isset($field_values[$field->id]) ? $field_values[$field->id] : '';
                                        
                                        // 处理文件链接
                                        if ($value && strpos($value, 'http') === 0) {
                                            echo '<a href="' . esc_url($value) . '" target="_blank">查看文件</a>';
                                        } else {
                                            echo esc_html($value);
                                        }
                                        ?>
                                    </td>
                                <?php endforeach; ?>
                                <td><?php echo date('Y-m-d H:i:s', strtotime($entry->created_at)); ?></td>
                                <td><?php echo esc_html($entry->ip_address); ?></td>
                                <td>
                                    <a href="?page=wp-form-builder-entries&form_id=<?php echo $form_id; ?>&action=delete_entry&entry_id=<?php echo $entry->id; ?>&nonce=<?php echo wp_create_nonce('wpfb_delete_entry'); ?>" class="delete" onclick="return confirm('确定要删除这条记录吗?')">删除</a>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
                
                <div class="tablenav bottom">
                    <div class="alignleft actions bulkactions">
                        <select name="wpfb_bulk_action2">
                            <option value="">批量操作</option>
                            <option value="delete">删除</option>
                        </select>
                        <input type="submit" class="button action" value="应用">
                    </div>
                    <br class="clear">
                </div>
            </form>
        <?php else : ?>
            <div class="notice notice-info">
                <p>这个表单还没有任何提交记录</p>
            </div>
        <?php endif; ?>
    </div>
    <?php
}

// 导出表单提交记录
function wpfb_export_entries($form_id, $form, $fields) {
    global $wpdb;
    $entries_table = $wpdb->prefix . 'wpfb_entries';
    $entry_details_table = $wpdb->prefix . 'wpfb_entry_details';
    
    // 获取所有提交记录
    $entries = $wpdb->get_results(
        $wpdb->prepare("SELECT * FROM $entries_table WHERE form_id = %d ORDER BY created_at DESC", $form_id)
    );
    
    // 设置CSV头部
    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="form-entries-' . $form_id . '-' . date('Ymd') . '.csv"');
    
    $output = fopen('php://output', 'w');
    fprintf($output, chr(0xEF) . chr(0xBB) . chr(0xBF)); // UTF-8 BOM
    
    // 输出表头
    $header = array('提交ID', '提交时间', 'IP地址');
    foreach ($fields as $field) {
        $header[] = $field->label;
    }
    fputcsv($output, $header);
    
    // 输出每条记录
    foreach ($entries as $entry) {
        $entry_details = $wpdb->get_results(
            $wpdb->prepare("SELECT field_id, value FROM $entry_details_table WHERE entry_id = %d", $entry->id)
        );
        
        $field_values = array();
        foreach ($entry_details as $detail) {
            $field_values[$detail->field_id] = $detail->value;
        }
        
        $row = array(
            $entry->id,
            $entry->created_at,
            $entry->ip_address
        );
        
        foreach ($fields as $field) {
            $row[] = isset($field_values[$field->id]) ? $field_values[$field->id] : '';
        }
        
        fputcsv($output, $row);
    }
    
    fclose($output);
}

// 渲染设置页面
function wpfb_render_settings() {
    // 保存设置
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['wpfb_save_settings']) && isset($_POST['wpfb_nonce'])) {
        // 验证nonce
        if (!wp_verify_nonce($_POST['wpfb_nonce'], 'wpfb_save_settings')) {
            wp_die('安全验证失败,请刷新页面重试。');
        }
        
        $settings = array(
            'default_email' => sanitize_email($_POST['default_email']),
            'email_subject' => sanitize_text_field($_POST['email_subject']),
            'email_template' => sanitize_textarea_field($_POST['email_template'])
        );
        
        update_option('wpfb_settings', $settings);
        echo '<div class="notice notice-success"><p>设置已成功保存</p></div>';
    }
    
    $settings = get_option('wpfb_settings');
    ?>
    <div class="wrap">
        <h1>表单生成器设置</h1>
        
        <form method="post" action="">
            <?php wp_nonce_field('wpfb_save_settings', 'wpfb_nonce'); ?>
            
            <table class="form-table">
                <tr>
                    <th scope="row"><label for="default_email">默认通知邮箱</label></th>
                    <td>
                        <input type="email" id="default_email" name="default_email" 
                            value="<?php echo esc_attr($settings['default_email']); ?>" 
                            class="regular-text" required>
                        <p class="description">表单提交通知的默认接收邮箱</p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><label for="email_subject">邮件主题</label></th>
                    <td>
                        <input type="text" id="email_subject" name="email_subject" 
                            value="<?php echo esc_attr($settings['email_subject']); ?>" 
                            class="regular-text" required>
                        <p class="description">可用变量: {form_name} - 表单名称</p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><label for="email_template">邮件内容模板</label></th>
                    <td>
                        <textarea id="email_template" name="email_template" 
                            rows="6" class="regular-text" required><?php echo esc_textarea($settings['email_template']); ?></textarea>
                        <p class="description">可用变量: {form_name} - 表单名称, {form_data} - 表单数据, {submission_date} - 提交时间</p>
                    </td>
                </tr>
            </table>
            
            <p class="submit">
                <button type="submit" name="wpfb_save_settings" class="button button-primary">保存设置</button>
            </p>
        </form>
    </div>
    <?php
}