文章目录
-
- 在当今数字化时代,网站不仅仅是展示信息的平台,更是与用户互动、收集数据、自动化业务流程的重要工具。WordPress作为全球最流行的内容管理系统,拥有超过40%的网站市场份额,其强大的可扩展性使其成为开发各种互联网小工具的理想平台。 然而,许多WordPress用户发现,现有的表单插件和工作流工具要么功能过于复杂,要么无法完全满足特定业务需求。通过WordPress代码二次开发,我们可以创建完全符合需求的自定义表单和工作流自动化工具,将常用互联网小工具功能无缝集成到网站中。 本指南将详细介绍如何通过WordPress程序代码二次开发,实现自定义表单与工作流自动化工具,帮助您提升网站功能性和用户体验。
-
- 在开始开发之前,我们需要理解WordPress的基本架构。WordPress采用MVC(模型-视图-控制器)的变体架构,主要包括: 主题系统:控制网站外观和前端展示 插件系统:扩展WordPress功能 核心文件:WordPress基础功能 数据库:存储所有网站数据
- 为了进行WordPress二次开发,您需要准备以下环境: 本地开发环境:使用XAMPP、MAMP或Local by Flywheel 代码编辑器:推荐VS Code、PHPStorm或Sublime Text 版本控制系统:Git用于代码管理 调试工具:Query Monitor、Debug Bar等WordPress调试插件
- WordPress的钩子(Hooks)系统是扩展功能的核心机制,分为两种类型: 动作(Actions):在特定时间点执行自定义代码 过滤器(Filters):修改数据后再返回 理解并熟练使用钩子系统是开发自定义表单和工作流工具的关键。
-
- 在开始编码之前,首先明确表单需求: 表单类型:联系表单、注册表单、调查问卷、订单表单等 字段类型:文本、邮箱、电话、下拉选择、文件上传等 验证需求:前端和后端验证规则 提交处理:数据存储、邮件通知、重定向等
- 让我们从创建一个简单的表单插件开始: <?php /** * Plugin Name: 自定义表单系统 * Description: 为WordPress创建自定义表单和工作流自动化 * Version: 1.0.0 * Author: 您的名称 */ // 防止直接访问 if (!defined('ABSPATH')) { exit; } // 定义插件常量 define('CUSTOM_FORM_VERSION', '1.0.0'); define('CUSTOM_FORM_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('CUSTOM_FORM_PLUGIN_URL', plugin_dir_url(__FILE__)); // 初始化插件 class Custom_Form_Init { public function __construct() { // 注册激活和停用钩子 register_activation_hook(__FILE__, array($this, 'activate')); register_deactivation_hook(__FILE__, array($this, 'deactivate')); // 初始化插件功能 add_action('init', array($this, 'init')); } public function activate() { // 创建必要的数据库表 $this->create_tables(); // 设置默认选项 update_option('custom_form_version', CUSTOM_FORM_VERSION); } public function deactivate() { // 清理临时数据 } public function init() { // 加载文本域 load_plugin_textdomain('custom-form', false, dirname(plugin_basename(__FILE__)) . '/languages'); // 注册短代码 add_shortcode('custom_form', array($this, 'form_shortcode')); // 处理表单提交 add_action('admin_post_nopriv_custom_form_submit', array($this, 'handle_form_submit')); add_action('admin_post_custom_form_submit', array($this, 'handle_form_submit')); } private function create_tables() { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); $table_name = $wpdb->prefix . 'custom_form_submissions'; $sql = "CREATE TABLE IF NOT EXISTS $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, form_id varchar(50) NOT NULL, form_data longtext NOT NULL, submitted_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL, ip_address varchar(45), user_agent text, status varchar(20) DEFAULT 'pending', PRIMARY KEY (id) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); } public function form_shortcode($atts) { // 解析短代码属性 $atts = shortcode_atts(array( 'id' => 'contact', 'title' => '联系我们' ), $atts, 'custom_form'); // 输出表单HTML ob_start(); include(CUSTOM_FORM_PLUGIN_DIR . 'templates/form-template.php'); return ob_get_clean(); } public function handle_form_submit() { // 验证nonce if (!isset($_POST['custom_form_nonce']) || !wp_verify_nonce($_POST['custom_form_nonce'], 'custom_form_action')) { wp_die('安全验证失败'); } // 处理表单数据 $form_data = array(); foreach ($_POST as $key => $value) { if ($key !== 'custom_form_nonce' && $key !== '_wp_http_referer' && $key !== 'action') { $form_data[sanitize_text_field($key)] = sanitize_text_field($value); } } // 保存到数据库 $this->save_submission($form_data); // 发送邮件通知 $this->send_notification($form_data); // 重定向用户 $redirect_url = isset($_POST['_wp_http_referer']) ? $_POST['_wp_http_referer'] : home_url(); wp_redirect(add_query_arg('form_status', 'success', $redirect_url)); exit; } private function save_submission($data) { global $wpdb; $table_name = $wpdb->prefix . 'custom_form_submissions'; $wpdb->insert( $table_name, array( 'form_id' => 'contact', 'form_data' => json_encode($data), 'ip_address' => $this->get_user_ip(), 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '' ), array('%s', '%s', '%s', '%s') ); } private function send_notification($data) { $to = get_option('admin_email'); $subject = '新的表单提交 - ' . get_bloginfo('name'); $message = "您收到一个新的表单提交:nn"; foreach ($data as $key => $value) { $message .= ucfirst($key) . ": " . $value . "n"; } wp_mail($to, $subject, $message); } private function get_user_ip() { if (!empty($_SERVER['HTTP_CLIENT_IP'])) { return $_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { return $_SERVER['HTTP_X_FORWARDED_FOR']; } else { return $_SERVER['REMOTE_ADDR']; } } } // 初始化插件 new Custom_Form_Init();
- 在插件目录中创建templates/form-template.php: <div class="custom-form-container"> <h3><?php echo esc_html($atts['title']); ?></h3> <?php if (isset($_GET['form_status']) && $_GET['form_status'] === 'success'): ?> <div class="form-success"> <p>表单提交成功!我们会尽快与您联系。</p> </div> <?php endif; ?> <form method="post" action="<?php echo admin_url('admin-post.php'); ?>" class="custom-form"> <input type="hidden" name="action" value="custom_form_submit"> <?php wp_nonce_field('custom_form_action', 'custom_form_nonce'); ?> <div class="form-group"> <label for="name">姓名 *</label> <input type="text" id="name" name="name" required> </div> <div class="form-group"> <label for="email">邮箱 *</label> <input type="email" id="email" name="email" required> </div> <div class="form-group"> <label for="phone">电话</label> <input type="tel" id="phone" name="phone"> </div> <div class="form-group"> <label for="message">留言 *</label> <textarea id="message" name="message" rows="5" required></textarea> </div> <div class="form-group"> <button type="submit">提交</button> </div> </form> </div> <style> .custom-form-container { max-width: 600px; margin: 0 auto; padding: 20px; background: #f9f9f9; border-radius: 8px; } .form-group { margin-bottom: 15px; } .form-group label { display: block; margin-bottom: 5px; font-weight: bold; } .form-group input, .form-group textarea { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; } .form-group button { background: #0073aa; color: white; border: none; padding: 12px 24px; border-radius: 4px; cursor: pointer; font-size: 16px; } .form-group button:hover { background: #005a87; } .form-success { background: #d4edda; color: #155724; padding: 10px; border-radius: 4px; margin-bottom: 20px; } </style>
- 为了确保数据质量,我们需要添加前端和后端验证: // 在表单模板中添加JavaScript验证 <script> document.addEventListener('DOMContentLoaded', function() { const form = document.querySelector('.custom-form'); if (form) { form.addEventListener('submit', function(e) { let isValid = true; const emailField = document.getElementById('email'); const phoneField = document.getElementById('phone'); // 邮箱验证 const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/; if (!emailRegex.test(emailField.value)) { alert('请输入有效的邮箱地址'); emailField.focus(); isValid = false; } // 电话验证(如果填写) if (phoneField.value) { const phoneRegex = /^[ds-+()]{10,}$/; if (!phoneRegex.test(phoneField.value.replace(/s/g, ''))) { alert('请输入有效的电话号码'); phoneField.focus(); isValid = false; } } if (!isValid) { e.preventDefault(); } }); } }); </script> // 在后端处理中添加验证 public function handle_form_submit() { // ... 之前的代码 ... // 验证必填字段 $required_fields = array('name', 'email', 'message'); foreach ($required_fields as $field) { if (empty($_POST[$field])) { wp_die('请填写所有必填字段'); } } // 验证邮箱格式 if (!is_email($_POST['email'])) { wp_die('请输入有效的邮箱地址'); } // ... 后续处理代码 ... }
-
- 工作流自动化是指根据预设规则自动执行一系列操作的过程。在WordPress中,我们可以创建以下类型的工作流: 表单提交后的自动响应 数据验证与处理流程 多步骤审批流程 定时任务与提醒系统 与其他系统的集成工作流
- // 在工作流类中 class Custom_Workflow_Engine { private $workflows = array(); public function __construct() { add_action('init', array($this, 'register_workflows')); add_action('custom_form_submitted', array($this, 'trigger_workflows'), 10, 2); } public function register_workflows() { // 注册默认工作流 $this->workflows['new_contact_form'] = array( 'name' => '新联系表单工作流', 'trigger' => 'custom_form_submitted', 'conditions' => array( array( 'field' => 'form_id', 'operator' => 'equals', 'value' => 'contact' ) ), 'actions' => array( array( 'type' => 'email', 'recipient' => 'admin', 'subject' => '新的联系表单提交', 'template' => 'default_contact_notification' ), array( 'type' => 'email', 'recipient' => 'user', 'field' => 'email', 'subject' => '感谢您的联系', 'template' => 'user_auto_reply' ), array( 'type' => 'database', 'action' => 'update_status', 'status' => 'processed' ) ) ); // 允许其他插件添加工作流 $this->workflows = apply_filters('custom_workflow_registry', $this->workflows); } public function trigger_workflows($form_id, $form_data) { foreach ($this->workflows as $workflow_id => $workflow) { if ($this->check_conditions($workflow['conditions'], $form_id, $form_data)) { $this->execute_actions($workflow['actions'], $form_data); } } } private function check_conditions($conditions, $form_id, $form_data) { foreach ($conditions as $condition) { $field_value = ''; if ($condition['field'] === 'form_id') { $field_value = $form_id; } elseif (isset($form_data[$condition['field']])) { $field_value = $form_data[$condition['field']]; } switch ($condition['operator']) { case 'equals': if ($field_value != $condition['value']) return false; break; case 'contains': if (strpos($field_value, $condition['value']) === false) return false; break; case 'greater_than': if (!is_numeric($field_value) || $field_value <= $condition['value']) return false; break; // 添加更多条件运算符 } } return true; } private function execute_actions($actions, $form_data) { foreach ($actions as $action) { switch ($action['type']) { case 'email': $this->execute_email_action($action, $form_data); break; case 'database': $this->execute_database_action($action, $form_data); break; case 'webhook': $this->execute_webhook_action($action, $form_data); break; // 添加更多动作类型 } } } private function execute_email_action($action, $form_data) { $recipient = ''; if ($action['recipient'] === 'admin') { $recipient = get_option('admin_email'); } elseif ($action['recipient'] === 'user' && isset($action['field'])) { $recipient = isset($form_data[$action['field']]) ? $form_data[$action['field']] : ''; } elseif (filter_var($action['recipient'], FILTER_VALIDATE_EMAIL)) { $recipient = $action['recipient']; } if (empty($recipient)) return; $subject = $this->replace_placeholders($action['subject'], $form_data); $message = $this->get_email_template($action['template'], $form_data); wp_mail($recipient, $subject, $message); } private function replace_placeholders($text, $form_data) { foreach ($form_data as $key => $value) { $text = str_replace('{' . $key . '}', $value, $text); } $text = str_replace('{site_name}', get_bloginfo('name'), $text); $text = str_replace('{site_url}', home_url(), $text); $text = str_replace('{current_date}', date_i18n(get_option('date_format')), $text); return $text; } private function get_email_template($template_name, $form_data) { $templates = array( 'default_contact_notification' => "您收到一个新的联系表单提交:nn{form_data}nn提交时间:{current_date}", message}nn此致,n{site_name}团队" ); $template = isset($templates[$template_name]) ? $templates[$template_name] : $templates['default_contact_notification']; // 格式化表单数据 $form_data_text = ""; foreach ($form_data as $key => $value) { $form_data_text .= ucfirst($key) . ": " . $value . "n"; } $template = str_replace('{form_data}', $form_data_text, $template); return $this->replace_placeholders($template, $form_data); } private function execute_database_action($action, $form_data) { global $wpdb; switch ($action['action']) { case 'update_status': $table_name = $wpdb->prefix . 'custom_form_submissions'; $wpdb->update( $table_name, array('status' => $action['status']), array('id' => $form_data['submission_id']), array('%s'), array('%d') ); break; case 'create_post': $post_data = array( 'post_title' => $this->replace_placeholders($action['title'], $form_data), 'post_content' => $this->replace_placeholders($action['content'], $form_data), 'post_status' => isset($action['status']) ? $action['status'] : 'draft', 'post_type' => isset($action['post_type']) ? $action['post_type'] : 'post', 'post_author' => isset($action['author_id']) ? $action['author_id'] : 1 ); $post_id = wp_insert_post($post_data); // 添加自定义字段 if ($post_id && isset($action['meta_fields'])) { foreach ($action['meta_fields'] as $meta_key => $meta_value) { update_post_meta($post_id, $meta_key, $this->replace_placeholders($meta_value, $form_data)); } } break; } } private function execute_webhook_action($action, $form_data) { if (!isset($action['url']) || empty($action['url'])) { return; } $payload = array( 'form_data' => $form_data, 'site' => array( 'name' => get_bloginfo('name'), 'url' => home_url() ), 'timestamp' => current_time('mysql') ); // 添加自定义数据 if (isset($action['custom_data'])) { $payload['custom'] = $action['custom_data']; } $args = array( 'body' => json_encode($payload), 'headers' => array('Content-Type' => 'application/json'), 'timeout' => 30, 'redirection' => 5, 'blocking' => isset($action['blocking']) ? $action['blocking'] : false, 'sslverify' => false ); // 添加自定义请求头 if (isset($action['headers'])) { $args['headers'] = array_merge($args['headers'], $action['headers']); } wp_remote_post($action['url'], $args); } } // 初始化工作流引擎new Custom_Workflow_Engine(); ### 3.3 创建工作流管理界面 为了让用户能够配置工作流,我们需要创建一个管理界面: // 添加管理菜单class Custom_Workflow_Admin { public function __construct() { add_action('admin_menu', array($this, 'add_admin_menu')); add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts')); } public function add_admin_menu() { add_menu_page( '工作流自动化', '工作流', 'manage_options', 'custom-workflows', array($this, 'workflows_admin_page'), 'dashicons-randomize', 30 ); add_submenu_page( 'custom-workflows', '添加新工作流', '添加新工作流', 'manage_options', 'custom-workflow-add', array($this, 'add_workflow_page') ); add_submenu_page( 'custom-workflows', '工作流日志', '日志', 'manage_options', 'custom-workflow-logs', array($this, 'workflow_logs_page') ); } public function workflows_admin_page() { ?> <div class="wrap"> <h1>工作流自动化</h1> <div class="workflow-list-container"> <table class="wp-list-table widefat fixed striped"> <thead> <tr> <th>工作流名称</th> <th>触发器</th> <th>条件</th> <th>动作</th> <th>状态</th> <th>操作</th> </tr> </thead> <tbody> <?php $workflows = get_option('custom_workflows', array()); if (empty($workflows)) { echo '<tr><td colspan="6">暂无工作流。 <a href="' . admin_url('admin.php?page=custom-workflow-add') . '">创建第一个工作流</a></td></tr>'; } else { foreach ($workflows as $id => $workflow) { ?> <tr> <td><?php echo esc_html($workflow['name']); ?></td> <td><?php echo esc_html($workflow['trigger']); ?></td> <td><?php echo count($workflow['conditions']); ?> 个条件</td> <td><?php echo count($workflow['actions']); ?> 个动作</td> <td> <span class="workflow-status <?php echo $workflow['active'] ? 'active' : 'inactive'; ?>"> <?php echo $workflow['active'] ? '启用' : '禁用'; ?> </span> </td> <td> <a href="<?php echo admin_url('admin.php?page=custom-workflow-add&edit=' . $id); ?>" class="button button-small">编辑</a> <button class="button button-small toggle-workflow" data-id="<?php echo $id; ?>"> <?php echo $workflow['active'] ? '禁用' : '启用'; ?> </button> <button class="button button-small button-link-delete delete-workflow" data-id="<?php echo $id; ?>">删除</button> </td> </tr> <?php } } ?> </tbody> </table> </div> </div> <style> .workflow-status { padding: 3px 8px; border-radius: 3px; font-size: 12px; font-weight: bold; } .workflow-status.active { background: #d4edda; color: #155724; } .workflow-status.inactive { background: #f8d7da; color: #721c24; } </style> <script> jQuery(document).ready(function($) { $('.toggle-workflow').on('click', function() { var workflowId = $(this).data('id'); var button = $(this); $.post(ajaxurl, { action: 'toggle_workflow', workflow_id: workflowId, nonce: '<?php echo wp_create_nonce('workflow_toggle'); ?>' }, function(response) { if (response.success) { location.reload(); } else { alert('操作失败: ' + response.data); } }); }); $('.delete-workflow').on('click', function() { if (!confirm('确定要删除这个工作流吗?此操作不可撤销。')) { return; } var workflowId = $(this).data('id'); var button = $(this); $.post(ajaxurl, { action: 'delete_workflow', workflow_id: workflowId, nonce: '<?php echo wp_create_nonce('workflow_delete'); ?>' }, function(response) { if (response.success) { location.reload(); } else { alert('删除失败: ' + response.data); } }); }); }); </script> <?php } public function add_workflow_page() { $editing = isset($_GET['edit']) ? sanitize_text_field($_GET['edit']) : false; $workflow = $editing ? $this->get_workflow($editing) : false; ?> <div class="wrap"> <h1><?php echo $editing ? '编辑工作流' : '添加新工作流'; ?></h1> <form id="workflow-form" method="post" action="<?php echo admin_url('admin-post.php'); ?>"> <input type="hidden" name="action" value="save_workflow"> <input type="hidden" name="workflow_id" value="<?php echo $editing ? esc_attr($editing) : ''; ?>"> <?php wp_nonce_field('save_workflow_action', 'workflow_nonce'); ?> <div class="workflow-form-section"> <h2>基本信息</h2> <table class="form-table"> <tr> <th><label for="workflow_name">工作流名称</label></th> <td> <input type="text" id="workflow_name" name="workflow_name" value="<?php echo $workflow ? esc_attr($workflow['name']) : ''; ?>" class="regular-text" required> <p class="description">用于识别此工作流的名称</p> </td> </tr> <tr> <th><label for="workflow_trigger">触发器</label></th> <td> <select id="workflow_trigger" name="workflow_trigger" required> <option value="">选择触发器...</option> <option value="custom_form_submitted" <?php selected($workflow && $workflow['trigger'] === 'custom_form_submitted'); ?>> 表单提交 </option> <option value="user_registered" <?php selected($workflow && $workflow['trigger'] === 'user_registered'); ?>> 用户注册 </option> <option value="post_published" <?php selected($workflow && $workflow['trigger'] === 'post_published'); ?>> 文章发布 </option> <option value="scheduled" <?php selected($workflow && $workflow['trigger'] === 'scheduled'); ?>> 定时任务 </option> </select> <p class="description">触发此工作流执行的事件</p> </td> </tr> <tr> <th><label for="workflow_active">状态</label></th> <td> <label> <input type="checkbox" id="workflow_active" name="workflow_active" value="1" <?php checked(!$workflow || $workflow['active']); ?>> 启用此工作流 </label> </td> </tr> </table> </div> <div class="workflow-form-section"> <h2>条件</h2> <div id="conditions-container"> <?php if ($workflow && !empty($workflow['conditions'])) { foreach ($workflow['conditions'] as $index => $condition) { $this->render_condition_row($index, $condition); } } else { $this->render_condition_row(0); } ?> </div> <button type="button" id="add-condition" class="button">添加条件</button> </div> <div class="workflow-form-section"> <h2>动作</h2> <div id="actions-container"> <?php if ($workflow && !empty($workflow['actions'])) { foreach ($workflow['actions'] as $index => $action) { $this->render_action_row($index, $action); } } else { $this->render_action_row(0); } ?> </div> <button type="button" id="add-action" class="button">添加动作</button> </div> <p class="submit"> <button type="submit" class="button button-primary">保存工作流</button> <a href="<?php echo admin_url('admin.php?page=custom-workflows'); ?>" class="button">取消</a> </p> </form> </div> <script> jQuery(document).ready(function($) { var conditionIndex = <?php echo $workflow && !empty($workflow['conditions']) ? count($workflow['conditions']) : 1; ?>; var actionIndex = <?php echo $workflow && !empty($workflow['actions']) ? count($workflow['actions']) : 1; ?>; // 添加条件 $('#add-condition').on('click', function() { $.get('<?php echo admin_url('admin-ajax.php'); ?>', { action: 'get_condition_row', index: conditionIndex, nonce: '<?php echo wp_create_nonce('get_condition_row'); ?>' }, function(response) { if (response.success) { $('#conditions-container').append(response.data); conditionIndex++; } }); }); // 添加动作 $('#add-action').on('click', function() { $.get('<?php echo admin_url('admin-ajax.php'); ?>', { action: 'get_action_row', index: actionIndex, nonce: '<?php echo wp_create_nonce('get_action_row'); ?>' }, function(response) { if (response.success) { $('#actions-container').append(response.data); actionIndex++; } }); }); // 删除行 $(document).on('click', '.remove-row', function() { $(this).closest('.condition-row, .action-row').remove(); }); // 动态显示/隐藏字段 $(document).on('change', '.condition-field, .action-type', function() { var row = $(this).closest('.condition-row, .action-row'); // 根据选择显示/隐藏相关字段 // 这里可以添加更多逻辑 }); }); </script> <style> .workflow-form-section { background: white; padding: 20px; margin-bottom: 20px; border: 1px solid #ccd0d4; border-radius: 4px; } .condition-row, .action-row { background: #f9f9f9; padding: 15px; margin-bottom: 10px; border: 1px solid #ddd; border-radius: 4px; position: relative; } .remove-row { position: absolute; top: 10px; right: 10px; color: #dc3232; text-decoration: none; } .condition-row select, .condition-row input, .action-row select, .action-row input { margin-right: 10px; margin-bottom: 5px; } </style> <?php } private function render_condition_row($index, $condition = array()) { ?> <div class="condition-row"> <a href="#" class="remove-row">删除</a> <select name="conditions[<?php echo $index; ?>][field]" class="condition-field"> <option value="form_id" <?php selected(isset($condition['field']) && $condition['field'] === 'form_id'); ?>>表单ID</option> <option value="email" <?php selected(isset($condition['field']) && $condition['field'] === 'email'); ?>>邮箱地址</option> <option value="custom_field" <?php selected(isset($condition['field']) && $condition['field'] === 'custom_field'); ?>>自定义字段</option> </select> <select name="conditions[<?php echo $index; ?>][operator]"> <option value="equals" <?php selected(isset($condition['operator']) && $condition['operator'] === 'equals'); ?>>等于</option> <option value="contains" <?php selected(isset($condition['operator']) && $condition['operator'] === 'contains'); ?>>包含</option> <option value="not_equals" <?php selected(isset($condition['operator']) && $condition['operator'] === 'not_equals'); ?>>不等于</option> <option value="greater_than" <?php selected(isset($condition['operator']) && $condition['operator'] === 'greater_than'); ?>>大于</option> <option value="less_than" <?php selected(isset($condition['operator']) && $condition['operator'] === 'less_than'); ?>>小于</option> </select> <input type="text" name="conditions[<?php echo $index; ?>][value]" value="<?php echo isset($condition['value']) ? esc_attr($condition['value']) : ''; ?>" placeholder="值" style="width: 200px;"> <?php if (isset($condition['field']) && $condition['field'] === 'custom_field'): ?> <input type="text" name="conditions[<?php echo $index; ?>][custom_field]" value="<?php echo isset($condition['custom_field']) ? esc_attr($condition['custom_field']) : ''; ?>" placeholder="字段名"> <?php endif; ?> </div> <?php } private function render_action_row($index, $action = array()) { $action_type = isset($action['type']) ? $action['type'] : 'email'; ?> <div class="
在当今数字化时代,网站不仅仅是展示信息的平台,更是与用户互动、收集数据、自动化业务流程的重要工具。WordPress作为全球最流行的内容管理系统,拥有超过40%的网站市场份额,其强大的可扩展性使其成为开发各种互联网小工具的理想平台。
然而,许多WordPress用户发现,现有的表单插件和工作流工具要么功能过于复杂,要么无法完全满足特定业务需求。通过WordPress代码二次开发,我们可以创建完全符合需求的自定义表单和工作流自动化工具,将常用互联网小工具功能无缝集成到网站中。
本指南将详细介绍如何通过WordPress程序代码二次开发,实现自定义表单与工作流自动化工具,帮助您提升网站功能性和用户体验。
在开始开发之前,我们需要理解WordPress的基本架构。WordPress采用MVC(模型-视图-控制器)的变体架构,主要包括:
- 主题系统:控制网站外观和前端展示
- 插件系统:扩展WordPress功能
- 核心文件:WordPress基础功能
- 数据库:存储所有网站数据
为了进行WordPress二次开发,您需要准备以下环境:
- 本地开发环境:使用XAMPP、MAMP或Local by Flywheel
- 代码编辑器:推荐VS Code、PHPStorm或Sublime Text
- 版本控制系统:Git用于代码管理
- 调试工具:Query Monitor、Debug Bar等WordPress调试插件
WordPress的钩子(Hooks)系统是扩展功能的核心机制,分为两种类型:
- 动作(Actions):在特定时间点执行自定义代码
- 过滤器(Filters):修改数据后再返回
理解并熟练使用钩子系统是开发自定义表单和工作流工具的关键。
在开始编码之前,首先明确表单需求:
- 表单类型:联系表单、注册表单、调查问卷、订单表单等
- 字段类型:文本、邮箱、电话、下拉选择、文件上传等
- 验证需求:前端和后端验证规则
- 提交处理:数据存储、邮件通知、重定向等
让我们从创建一个简单的表单插件开始:
<?php
/**
* Plugin Name: 自定义表单系统
* Description: 为WordPress创建自定义表单和工作流自动化
* Version: 1.0.0
* Author: 您的名称
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('CUSTOM_FORM_VERSION', '1.0.0');
define('CUSTOM_FORM_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CUSTOM_FORM_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
class Custom_Form_Init {
public function __construct() {
// 注册激活和停用钩子
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 初始化插件功能
add_action('init', array($this, 'init'));
}
public function activate() {
// 创建必要的数据库表
$this->create_tables();
// 设置默认选项
update_option('custom_form_version', CUSTOM_FORM_VERSION);
}
public function deactivate() {
// 清理临时数据
}
public function init() {
// 加载文本域
load_plugin_textdomain('custom-form', false, dirname(plugin_basename(__FILE__)) . '/languages');
// 注册短代码
add_shortcode('custom_form', array($this, 'form_shortcode'));
// 处理表单提交
add_action('admin_post_nopriv_custom_form_submit', array($this, 'handle_form_submit'));
add_action('admin_post_custom_form_submit', array($this, 'handle_form_submit'));
}
private function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'custom_form_submissions';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
form_id varchar(50) NOT NULL,
form_data longtext NOT NULL,
submitted_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
ip_address varchar(45),
user_agent text,
status varchar(20) DEFAULT 'pending',
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
public function form_shortcode($atts) {
// 解析短代码属性
$atts = shortcode_atts(array(
'id' => 'contact',
'title' => '联系我们'
), $atts, 'custom_form');
// 输出表单HTML
ob_start();
include(CUSTOM_FORM_PLUGIN_DIR . 'templates/form-template.php');
return ob_get_clean();
}
public function handle_form_submit() {
// 验证nonce
if (!isset($_POST['custom_form_nonce']) ||
!wp_verify_nonce($_POST['custom_form_nonce'], 'custom_form_action')) {
wp_die('安全验证失败');
}
// 处理表单数据
$form_data = array();
foreach ($_POST as $key => $value) {
if ($key !== 'custom_form_nonce' && $key !== '_wp_http_referer' && $key !== 'action') {
$form_data[sanitize_text_field($key)] = sanitize_text_field($value);
}
}
// 保存到数据库
$this->save_submission($form_data);
// 发送邮件通知
$this->send_notification($form_data);
// 重定向用户
$redirect_url = isset($_POST['_wp_http_referer']) ? $_POST['_wp_http_referer'] : home_url();
wp_redirect(add_query_arg('form_status', 'success', $redirect_url));
exit;
}
private function save_submission($data) {
global $wpdb;
$table_name = $wpdb->prefix . 'custom_form_submissions';
$wpdb->insert(
$table_name,
array(
'form_id' => 'contact',
'form_data' => json_encode($data),
'ip_address' => $this->get_user_ip(),
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''
),
array('%s', '%s', '%s', '%s')
);
}
private function send_notification($data) {
$to = get_option('admin_email');
$subject = '新的表单提交 - ' . get_bloginfo('name');
$message = "您收到一个新的表单提交:nn";
foreach ($data as $key => $value) {
$message .= ucfirst($key) . ": " . $value . "n";
}
wp_mail($to, $subject, $message);
}
private function get_user_ip() {
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
return $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
return $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
return $_SERVER['REMOTE_ADDR'];
}
}
}
// 初始化插件
new Custom_Form_Init();
在插件目录中创建templates/form-template.php:
<div class="custom-form-container">
<h3><?php echo esc_html($atts['title']); ?></h3>
<?php if (isset($_GET['form_status']) && $_GET['form_status'] === 'success'): ?>
<div class="form-success">
<p>表单提交成功!我们会尽快与您联系。</p>
</div>
<?php endif; ?>
<form method="post" action="<?php echo admin_url('admin-post.php'); ?>" class="custom-form">
<input type="hidden" name="action" value="custom_form_submit">
<?php wp_nonce_field('custom_form_action', 'custom_form_nonce'); ?>
<div class="form-group">
<label for="name">姓名 *</label>
<input type="text" id="name" name="name" required>
</div>
<div class="form-group">
<label for="email">邮箱 *</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="phone">电话</label>
<input type="tel" id="phone" name="phone">
</div>
<div class="form-group">
<label for="message">留言 *</label>
<textarea id="message" name="message" rows="5" required></textarea>
</div>
<div class="form-group">
<button type="submit">提交</button>
</div>
</form>
</div>
<style>
.custom-form-container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background: #f9f9f9;
border-radius: 8px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.form-group input,
.form-group textarea {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
.form-group button {
background: #0073aa;
color: white;
border: none;
padding: 12px 24px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
.form-group button:hover {
background: #005a87;
}
.form-success {
background: #d4edda;
color: #155724;
padding: 10px;
border-radius: 4px;
margin-bottom: 20px;
}
</style>
为了确保数据质量,我们需要添加前端和后端验证:
// 在表单模板中添加JavaScript验证
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.querySelector('.custom-form');
if (form) {
form.addEventListener('submit', function(e) {
let isValid = true;
const emailField = document.getElementById('email');
const phoneField = document.getElementById('phone');
// 邮箱验证
const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/;
if (!emailRegex.test(emailField.value)) {
alert('请输入有效的邮箱地址');
emailField.focus();
isValid = false;
}
// 电话验证(如果填写)
if (phoneField.value) {
const phoneRegex = /^[ds-+()]{10,}$/;
if (!phoneRegex.test(phoneField.value.replace(/s/g, ''))) {
alert('请输入有效的电话号码');
phoneField.focus();
isValid = false;
}
}
if (!isValid) {
e.preventDefault();
}
});
}
});
</script>
// 在后端处理中添加验证
public function handle_form_submit() {
// ... 之前的代码 ...
// 验证必填字段
$required_fields = array('name', 'email', 'message');
foreach ($required_fields as $field) {
if (empty($_POST[$field])) {
wp_die('请填写所有必填字段');
}
}
// 验证邮箱格式
if (!is_email($_POST['email'])) {
wp_die('请输入有效的邮箱地址');
}
// ... 后续处理代码 ...
}
工作流自动化是指根据预设规则自动执行一系列操作的过程。在WordPress中,我们可以创建以下类型的工作流:
- 表单提交后的自动响应
- 数据验证与处理流程
- 多步骤审批流程
- 定时任务与提醒系统
- 与其他系统的集成工作流
// 在工作流类中
class Custom_Workflow_Engine {
private $workflows = array();
public function __construct() {
add_action('init', array($this, 'register_workflows'));
add_action('custom_form_submitted', array($this, 'trigger_workflows'), 10, 2);
}
public function register_workflows() {
// 注册默认工作流
$this->workflows['new_contact_form'] = array(
'name' => '新联系表单工作流',
'trigger' => 'custom_form_submitted',
'conditions' => array(
array(
'field' => 'form_id',
'operator' => 'equals',
'value' => 'contact'
)
),
'actions' => array(
array(
'type' => 'email',
'recipient' => 'admin',
'subject' => '新的联系表单提交',
'template' => 'default_contact_notification'
),
array(
'type' => 'email',
'recipient' => 'user',
'field' => 'email',
'subject' => '感谢您的联系',
'template' => 'user_auto_reply'
),
array(
'type' => 'database',
'action' => 'update_status',
'status' => 'processed'
)
)
);
// 允许其他插件添加工作流
$this->workflows = apply_filters('custom_workflow_registry', $this->workflows);
}
public function trigger_workflows($form_id, $form_data) {
foreach ($this->workflows as $workflow_id => $workflow) {
if ($this->check_conditions($workflow['conditions'], $form_id, $form_data)) {
$this->execute_actions($workflow['actions'], $form_data);
}
}
}
private function check_conditions($conditions, $form_id, $form_data) {
foreach ($conditions as $condition) {
$field_value = '';
if ($condition['field'] === 'form_id') {
$field_value = $form_id;
} elseif (isset($form_data[$condition['field']])) {
$field_value = $form_data[$condition['field']];
}
switch ($condition['operator']) {
case 'equals':
if ($field_value != $condition['value']) return false;
break;
case 'contains':
if (strpos($field_value, $condition['value']) === false) return false;
break;
case 'greater_than':
if (!is_numeric($field_value) || $field_value <= $condition['value']) return false;
break;
// 添加更多条件运算符
}
}
return true;
}
private function execute_actions($actions, $form_data) {
foreach ($actions as $action) {
switch ($action['type']) {
case 'email':
$this->execute_email_action($action, $form_data);
break;
case 'database':
$this->execute_database_action($action, $form_data);
break;
case 'webhook':
$this->execute_webhook_action($action, $form_data);
break;
// 添加更多动作类型
}
}
}
private function execute_email_action($action, $form_data) {
$recipient = '';
if ($action['recipient'] === 'admin') {
$recipient = get_option('admin_email');
} elseif ($action['recipient'] === 'user' && isset($action['field'])) {
$recipient = isset($form_data[$action['field']]) ? $form_data[$action['field']] : '';
} elseif (filter_var($action['recipient'], FILTER_VALIDATE_EMAIL)) {
$recipient = $action['recipient'];
}
if (empty($recipient)) return;
$subject = $this->replace_placeholders($action['subject'], $form_data);
$message = $this->get_email_template($action['template'], $form_data);
wp_mail($recipient, $subject, $message);
}
private function replace_placeholders($text, $form_data) {
foreach ($form_data as $key => $value) {
$text = str_replace('{' . $key . '}', $value, $text);
}
$text = str_replace('{site_name}', get_bloginfo('name'), $text);
$text = str_replace('{site_url}', home_url(), $text);
$text = str_replace('{current_date}', date_i18n(get_option('date_format')), $text);
return $text;
}
private function get_email_template($template_name, $form_data) {
$templates = array(
'default_contact_notification' => "您收到一个新的联系表单提交:nn{form_data}nn提交时间:{current_date}",
// 在工作流类中
class Custom_Workflow_Engine {
private $workflows = array();
public function __construct() {
add_action('init', array($this, 'register_workflows'));
add_action('custom_form_submitted', array($this, 'trigger_workflows'), 10, 2);
}
public function register_workflows() {
// 注册默认工作流
$this->workflows['new_contact_form'] = array(
'name' => '新联系表单工作流',
'trigger' => 'custom_form_submitted',
'conditions' => array(
array(
'field' => 'form_id',
'operator' => 'equals',
'value' => 'contact'
)
),
'actions' => array(
array(
'type' => 'email',
'recipient' => 'admin',
'subject' => '新的联系表单提交',
'template' => 'default_contact_notification'
),
array(
'type' => 'email',
'recipient' => 'user',
'field' => 'email',
'subject' => '感谢您的联系',
'template' => 'user_auto_reply'
),
array(
'type' => 'database',
'action' => 'update_status',
'status' => 'processed'
)
)
);
// 允许其他插件添加工作流
$this->workflows = apply_filters('custom_workflow_registry', $this->workflows);
}
public function trigger_workflows($form_id, $form_data) {
foreach ($this->workflows as $workflow_id => $workflow) {
if ($this->check_conditions($workflow['conditions'], $form_id, $form_data)) {
$this->execute_actions($workflow['actions'], $form_data);
}
}
}
private function check_conditions($conditions, $form_id, $form_data) {
foreach ($conditions as $condition) {
$field_value = '';
if ($condition['field'] === 'form_id') {
$field_value = $form_id;
} elseif (isset($form_data[$condition['field']])) {
$field_value = $form_data[$condition['field']];
}
switch ($condition['operator']) {
case 'equals':
if ($field_value != $condition['value']) return false;
break;
case 'contains':
if (strpos($field_value, $condition['value']) === false) return false;
break;
case 'greater_than':
if (!is_numeric($field_value) || $field_value <= $condition['value']) return false;
break;
// 添加更多条件运算符
}
}
return true;
}
private function execute_actions($actions, $form_data) {
foreach ($actions as $action) {
switch ($action['type']) {
case 'email':
$this->execute_email_action($action, $form_data);
break;
case 'database':
$this->execute_database_action($action, $form_data);
break;
case 'webhook':
$this->execute_webhook_action($action, $form_data);
break;
// 添加更多动作类型
}
}
}
private function execute_email_action($action, $form_data) {
$recipient = '';
if ($action['recipient'] === 'admin') {
$recipient = get_option('admin_email');
} elseif ($action['recipient'] === 'user' && isset($action['field'])) {
$recipient = isset($form_data[$action['field']]) ? $form_data[$action['field']] : '';
} elseif (filter_var($action['recipient'], FILTER_VALIDATE_EMAIL)) {
$recipient = $action['recipient'];
}
if (empty($recipient)) return;
$subject = $this->replace_placeholders($action['subject'], $form_data);
$message = $this->get_email_template($action['template'], $form_data);
wp_mail($recipient, $subject, $message);
}
private function replace_placeholders($text, $form_data) {
foreach ($form_data as $key => $value) {
$text = str_replace('{' . $key . '}', $value, $text);
}
$text = str_replace('{site_name}', get_bloginfo('name'), $text);
$text = str_replace('{site_url}', home_url(), $text);
$text = str_replace('{current_date}', date_i18n(get_option('date_format')), $text);
return $text;
}
private function get_email_template($template_name, $form_data) {
$templates = array(
'default_contact_notification' => "您收到一个新的联系表单提交:nn{form_data}nn提交时间:{current_date}",
message}nn此致,n{site_name}团队"
);
$template = isset($templates[$template_name]) ? $templates[$template_name] : $templates['default_contact_notification'];
// 格式化表单数据
$form_data_text = "";
foreach ($form_data as $key => $value) {
$form_data_text .= ucfirst($key) . ": " . $value . "n";
}
$template = str_replace('{form_data}', $form_data_text, $template);
return $this->replace_placeholders($template, $form_data);
}
private function execute_database_action($action, $form_data) {
global $wpdb;
switch ($action['action']) {
case 'update_status':
$table_name = $wpdb->prefix . 'custom_form_submissions';
$wpdb->update(
$table_name,
array('status' => $action['status']),
array('id' => $form_data['submission_id']),
array('%s'),
array('%d')
);
break;
case 'create_post':
$post_data = array(
'post_title' => $this->replace_placeholders($action['title'], $form_data),
'post_content' => $this->replace_placeholders($action['content'], $form_data),
'post_status' => isset($action['status']) ? $action['status'] : 'draft',
'post_type' => isset($action['post_type']) ? $action['post_type'] : 'post',
'post_author' => isset($action['author_id']) ? $action['author_id'] : 1
);
$post_id = wp_insert_post($post_data);
// 添加自定义字段
if ($post_id && isset($action['meta_fields'])) {
foreach ($action['meta_fields'] as $meta_key => $meta_value) {
update_post_meta($post_id, $meta_key, $this->replace_placeholders($meta_value, $form_data));
}
}
break;
}
}
private function execute_webhook_action($action, $form_data) {
if (!isset($action['url']) || empty($action['url'])) {
return;
}
$payload = array(
'form_data' => $form_data,
'site' => array(
'name' => get_bloginfo('name'),
'url' => home_url()
),
'timestamp' => current_time('mysql')
);
// 添加自定义数据
if (isset($action['custom_data'])) {
$payload['custom'] = $action['custom_data'];
}
$args = array(
'body' => json_encode($payload),
'headers' => array('Content-Type' => 'application/json'),
'timeout' => 30,
'redirection' => 5,
'blocking' => isset($action['blocking']) ? $action['blocking'] : false,
'sslverify' => false
);
// 添加自定义请求头
if (isset($action['headers'])) {
$args['headers'] = array_merge($args['headers'], $action['headers']);
}
wp_remote_post($action['url'], $args);
}
}
// 初始化工作流引擎
new Custom_Workflow_Engine();
### 3.3 创建工作流管理界面
为了让用户能够配置工作流,我们需要创建一个管理界面:
// 添加管理菜单
class Custom_Workflow_Admin {
public function __construct() {
add_action('admin_menu', array($this, 'add_admin_menu'));
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
}
public function add_admin_menu() {
add_menu_page(
'工作流自动化',
'工作流',
'manage_options',
'custom-workflows',
array($this, 'workflows_admin_page'),
'dashicons-randomize',
30
);
add_submenu_page(
'custom-workflows',
'添加新工作流',
'添加新工作流',
'manage_options',
'custom-workflow-add',
array($this, 'add_workflow_page')
);
add_submenu_page(
'custom-workflows',
'工作流日志',
'日志',
'manage_options',
'custom-workflow-logs',
array($this, 'workflow_logs_page')
);
}
public function workflows_admin_page() {
?>
<div class="wrap">
<h1>工作流自动化</h1>
<div class="workflow-list-container">
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>工作流名称</th>
<th>触发器</th>
<th>条件</th>
<th>动作</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php
$workflows = get_option('custom_workflows', array());
if (empty($workflows)) {
echo '<tr><td colspan="6">暂无工作流。 <a href="' . admin_url('admin.php?page=custom-workflow-add') . '">创建第一个工作流</a></td></tr>';
} else {
foreach ($workflows as $id => $workflow) {
?>
<tr>
<td><?php echo esc_html($workflow['name']); ?></td>
<td><?php echo esc_html($workflow['trigger']); ?></td>
<td><?php echo count($workflow['conditions']); ?> 个条件</td>
<td><?php echo count($workflow['actions']); ?> 个动作</td>
<td>
<span class="workflow-status <?php echo $workflow['active'] ? 'active' : 'inactive'; ?>">
<?php echo $workflow['active'] ? '启用' : '禁用'; ?>
</span>
</td>
<td>
<a href="<?php echo admin_url('admin.php?page=custom-workflow-add&edit=' . $id); ?>" class="button button-small">编辑</a>
<button class="button button-small toggle-workflow" data-id="<?php echo $id; ?>">
<?php echo $workflow['active'] ? '禁用' : '启用'; ?>
</button>
<button class="button button-small button-link-delete delete-workflow" data-id="<?php echo $id; ?>">删除</button>
</td>
</tr>
<?php
}
}
?>
</tbody>
</table>
</div>
</div>
<style>
.workflow-status {
padding: 3px 8px;
border-radius: 3px;
font-size: 12px;
font-weight: bold;
}
.workflow-status.active {
background: #d4edda;
color: #155724;
}
.workflow-status.inactive {
background: #f8d7da;
color: #721c24;
}
</style>
<script>
jQuery(document).ready(function($) {
$('.toggle-workflow').on('click', function() {
var workflowId = $(this).data('id');
var button = $(this);
$.post(ajaxurl, {
action: 'toggle_workflow',
workflow_id: workflowId,
nonce: '<?php echo wp_create_nonce('workflow_toggle'); ?>'
}, function(response) {
if (response.success) {
location.reload();
} else {
alert('操作失败: ' + response.data);
}
});
});
$('.delete-workflow').on('click', function() {
if (!confirm('确定要删除这个工作流吗?此操作不可撤销。')) {
return;
}
var workflowId = $(this).data('id');
var button = $(this);
$.post(ajaxurl, {
action: 'delete_workflow',
workflow_id: workflowId,
nonce: '<?php echo wp_create_nonce('workflow_delete'); ?>'
}, function(response) {
if (response.success) {
location.reload();
} else {
alert('删除失败: ' + response.data);
}
});
});
});
</script>
<?php
}
public function add_workflow_page() {
$editing = isset($_GET['edit']) ? sanitize_text_field($_GET['edit']) : false;
$workflow = $editing ? $this->get_workflow($editing) : false;
?>
<div class="wrap">
<h1><?php echo $editing ? '编辑工作流' : '添加新工作流'; ?></h1>
<form id="workflow-form" method="post" action="<?php echo admin_url('admin-post.php'); ?>">
<input type="hidden" name="action" value="save_workflow">
<input type="hidden" name="workflow_id" value="<?php echo $editing ? esc_attr($editing) : ''; ?>">
<?php wp_nonce_field('save_workflow_action', 'workflow_nonce'); ?>
<div class="workflow-form-section">
<h2>基本信息</h2>
<table class="form-table">
<tr>
<th><label for="workflow_name">工作流名称</label></th>
<td>
<input type="text" id="workflow_name" name="workflow_name"
value="<?php echo $workflow ? esc_attr($workflow['name']) : ''; ?>"
class="regular-text" required>
<p class="description">用于识别此工作流的名称</p>
</td>
</tr>
<tr>
<th><label for="workflow_trigger">触发器</label></th>
<td>
<select id="workflow_trigger" name="workflow_trigger" required>
<option value="">选择触发器...</option>
<option value="custom_form_submitted" <?php selected($workflow && $workflow['trigger'] === 'custom_form_submitted'); ?>>
表单提交
</option>
<option value="user_registered" <?php selected($workflow && $workflow['trigger'] === 'user_registered'); ?>>
用户注册
</option>
<option value="post_published" <?php selected($workflow && $workflow['trigger'] === 'post_published'); ?>>
文章发布
</option>
<option value="scheduled" <?php selected($workflow && $workflow['trigger'] === 'scheduled'); ?>>
定时任务
</option>
</select>
<p class="description">触发此工作流执行的事件</p>
</td>
</tr>
<tr>
<th><label for="workflow_active">状态</label></th>
<td>
<label>
<input type="checkbox" id="workflow_active" name="workflow_active" value="1"
<?php checked(!$workflow || $workflow['active']); ?>>
启用此工作流
</label>
</td>
</tr>
</table>
</div>
<div class="workflow-form-section">
<h2>条件</h2>
<div id="conditions-container">
<?php
if ($workflow && !empty($workflow['conditions'])) {
foreach ($workflow['conditions'] as $index => $condition) {
$this->render_condition_row($index, $condition);
}
} else {
$this->render_condition_row(0);
}
?>
</div>
<button type="button" id="add-condition" class="button">添加条件</button>
</div>
<div class="workflow-form-section">
<h2>动作</h2>
<div id="actions-container">
<?php
if ($workflow && !empty($workflow['actions'])) {
foreach ($workflow['actions'] as $index => $action) {
$this->render_action_row($index, $action);
}
} else {
$this->render_action_row(0);
}
?>
</div>
<button type="button" id="add-action" class="button">添加动作</button>
</div>
<p class="submit">
<button type="submit" class="button button-primary">保存工作流</button>
<a href="<?php echo admin_url('admin.php?page=custom-workflows'); ?>" class="button">取消</a>
</p>
</form>
</div>
<script>
jQuery(document).ready(function($) {
var conditionIndex = <?php echo $workflow && !empty($workflow['conditions']) ? count($workflow['conditions']) : 1; ?>;
var actionIndex = <?php echo $workflow && !empty($workflow['actions']) ? count($workflow['actions']) : 1; ?>;
// 添加条件
$('#add-condition').on('click', function() {
$.get('<?php echo admin_url('admin-ajax.php'); ?>', {
action: 'get_condition_row',
index: conditionIndex,
nonce: '<?php echo wp_create_nonce('get_condition_row'); ?>'
}, function(response) {
if (response.success) {
$('#conditions-container').append(response.data);
conditionIndex++;
}
});
});
// 添加动作
$('#add-action').on('click', function() {
$.get('<?php echo admin_url('admin-ajax.php'); ?>', {
action: 'get_action_row',
index: actionIndex,
nonce: '<?php echo wp_create_nonce('get_action_row'); ?>'
}, function(response) {
if (response.success) {
$('#actions-container').append(response.data);
actionIndex++;
}
});
});
// 删除行
$(document).on('click', '.remove-row', function() {
$(this).closest('.condition-row, .action-row').remove();
});
// 动态显示/隐藏字段
$(document).on('change', '.condition-field, .action-type', function() {
var row = $(this).closest('.condition-row, .action-row');
// 根据选择显示/隐藏相关字段
// 这里可以添加更多逻辑
});
});
</script>
<style>
.workflow-form-section {
background: white;
padding: 20px;
margin-bottom: 20px;
border: 1px solid #ccd0d4;
border-radius: 4px;
}
.condition-row, .action-row {
background: #f9f9f9;
padding: 15px;
margin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 4px;
position: relative;
}
.remove-row {
position: absolute;
top: 10px;
right: 10px;
color: #dc3232;
text-decoration: none;
}
.condition-row select,
.condition-row input,
.action-row select,
.action-row input {
margin-right: 10px;
margin-bottom: 5px;
}
</style>
<?php
}
private function render_condition_row($index, $condition = array()) {
?>
<div class="condition-row">
<a href="#" class="remove-row">删除</a>
<select name="conditions[<?php echo $index; ?>][field]" class="condition-field">
<option value="form_id" <?php selected(isset($condition['field']) && $condition['field'] === 'form_id'); ?>>表单ID</option>
<option value="email" <?php selected(isset($condition['field']) && $condition['field'] === 'email'); ?>>邮箱地址</option>
<option value="custom_field" <?php selected(isset($condition['field']) && $condition['field'] === 'custom_field'); ?>>自定义字段</option>
</select>
<select name="conditions[<?php echo $index; ?>][operator]">
<option value="equals" <?php selected(isset($condition['operator']) && $condition['operator'] === 'equals'); ?>>等于</option>
<option value="contains" <?php selected(isset($condition['operator']) && $condition['operator'] === 'contains'); ?>>包含</option>
<option value="not_equals" <?php selected(isset($condition['operator']) && $condition['operator'] === 'not_equals'); ?>>不等于</option>
<option value="greater_than" <?php selected(isset($condition['operator']) && $condition['operator'] === 'greater_than'); ?>>大于</option>
<option value="less_than" <?php selected(isset($condition['operator']) && $condition['operator'] === 'less_than'); ?>>小于</option>
</select>
<input type="text" name="conditions[<?php echo $index; ?>][value]"
value="<?php echo isset($condition['value']) ? esc_attr($condition['value']) : ''; ?>"
placeholder="值" style="width: 200px;">
<?php if (isset($condition['field']) && $condition['field'] === 'custom_field'): ?>
<input type="text" name="conditions[<?php echo $index; ?>][custom_field]"
value="<?php echo isset($condition['custom_field']) ? esc_attr($condition['custom_field']) : ''; ?>"
placeholder="字段名">
<?php endif; ?>
</div>
<?php
}
private function render_action_row($index, $action = array()) {
$action_type = isset($action['type']) ? $action['type'] : 'email';
?>
<div class="


