WooCommerce前端订单状态更新失效问题求助
修复WordPress订单详情短码的状态更新问题
核心问题分析
点击“Update Status”后回到初始搜索框,本质是表单提交后未保留订单标识,且状态更新的POST逻辑未正确关联订单,导致页面刷新后无法识别当前操作的订单,直接回到初始状态。
修复后的完整代码
function my_plugin_order_details_shortcode() { ob_start(); $order_id = ''; $order = null; $message = ''; $message_type = ''; // 处理订单搜索提交 if (isset($_POST['search_order']) && current_user_can('manage_options')) { $order_id = sanitize_text_field($_POST['order_number']); $order = wc_get_order($order_id); if (!$order) { $message = '未找到对应订单,请检查订单编号'; $message_type = 'error'; } } // 处理订单状态更新提交 if (isset($_POST['update_order_status']) && current_user_can('manage_options')) { $order_id = sanitize_text_field($_POST['current_order_id']); $new_status = sanitize_text_field($_POST['order_status']); $order = wc_get_order($order_id); if ($order && in_array($new_status, array_keys(wc_get_order_statuses()))) { $order->update_status($new_status); $message = '订单状态已成功更新为:' . wc_get_order_status_name($new_status); $message_type = 'success'; // 更新后重新获取订单数据,确保状态显示最新 $order = wc_get_order($order_id); } else { $message = '状态更新失败,请检查订单编号或状态值'; $message_type = 'error'; } } // 显示提示消息 if (!empty($message)) { echo '<div class="notice notice-' . esc_attr($message_type) . ' is-dismissible"><p>' . esc_html($message) . '</p></div>'; } // 渲染搜索表单或订单详情 if (!$order) { // 初始搜索表单 ?> <form method="post" action=""> <p> <label for="order_number">订单编号:</label> <input type="text" id="order_number" name="order_number" required placeholder="输入订单编号"> </p> <p> <button type="submit" name="search_order" class="button button-primary">Search</button> </p> </form> <?php } else { // 订单详情及状态更新表单 ?> <h3>订单详情 #<?php echo esc_html($order->get_id()); ?></h3> <p><strong>客户:</strong><?php echo esc_html($order->get_billing_first_name() . ' ' . $order->get_billing_last_name()); ?></p> <p><strong>当前状态:</strong><?php echo esc_html(wc_get_order_status_name($order->get_status())); ?></p> <p><strong>订单总额:</strong><?php echo wp_kses_post($order->get_formatted_order_total()); ?></p> <form method="post" action=""> <input type="hidden" name="current_order_id" value="<?php echo esc_attr($order->get_id()); ?>"> <p> <label for="order_status">修改状态:</label> <select id="order_status" name="order_status" required> <?php foreach (wc_get_order_statuses() as $status_key => $status_name) : ?> <option value="<?php echo esc_attr(str_replace('wc-', '', $status_key)); ?>" <?php selected($order->get_status(), str_replace('wc-', '', $status_key)); ?>> <?php echo esc_html($status_name); ?> </option> <?php endforeach; ?> </select> </p> <p> <button type="submit" name="update_order_status" class="button button-primary">Update Status</button> <a href="" class="button">返回搜索</a> </p> </form> <?php } return ob_get_clean(); } add_shortcode('my_plugin_order_details', 'my_plugin_order_details_shortcode');
关键修复点说明
- 区分提交动作:通过
search_order和update_order_status两个不同的提交按钮name,分别处理搜索和更新逻辑,避免混淆 - 保留订单ID:状态更新表单中添加隐藏字段
current_order_id,提交时传递当前订单ID,确保更新操作能定位到目标订单 - 更新后刷新订单数据:状态更新完成后重新调用
wc_get_order($order_id),保证页面显示最新的订单状态 - 权限验证:所有操作都添加
current_user_can('manage_options')验证,确保只有管理员能执行操作 - 安全处理:使用
sanitize_text_field、esc_attr、esc_html等函数处理用户输入和输出,防止XSS攻击
内容的提问来源于stack exchange,提问作者MarkBui
相关产品推荐
相关产品推荐

