如何用Action Scheduler实现WooCommerce订单定时克隆与启停
正确实现WooCommerce定时订单克隆与停止功能
一、核心代码实现步骤
1. 注册定时克隆动作
先把你的克隆函数绑定到Action Scheduler的自定义钩子,再写一个函数来创建定时任务(避免重复添加):
// 绑定克隆函数到定时钩子 add_action('mutiara_scheduled_order_clone', 'mutiara_woocommerce_order_clone', 10, 1); // 创建定时任务 function mutiara_schedule_order_clone($order_id, $interval) { // 先查有没有同订单的活跃任务,防止重复 $existing_actions = as_get_scheduled_actions(array( 'hook' => 'mutiara_scheduled_order_clone', 'args' => array($order_id), 'status' => array('pending', 'in-progress', 'scheduled') )); if (!empty($existing_actions)) return; // 转换周期为Action Scheduler支持的格式 switch($interval) { case 'weekly': $schedule = 'weekly'; break; case 'biweekly': // 注册每两周的自定义周期(14天=1209600秒) add_filter('cron_schedules', function($schedules) { $schedules['biweekly'] = array( 'interval' => 1209600, 'display' => __('每两周') ); return $schedules; }); $schedule = 'biweekly'; break; case 'monthly': $schedule = 'monthly'; break; default: return; } // 添加循环定时任务 as_schedule_recurring_action(time(), $schedule, 'mutiara_scheduled_order_clone', array($order_id)); }
2. 订单详情页添加操作按钮
在订单侧边栏加一个 metabox,包含周期选择、启动按钮,以及停止按钮(有活跃任务时显示):
// 注册 metabox add_action('add_meta_boxes', 'mutiara_order_clone_meta_box'); function mutiara_order_clone_meta_box() { add_meta_box( 'mutiara-order-clone-scheduler', '定时克隆订单', 'mutiara_order_clone_meta_box_content', 'shop_order', 'side', 'default' ); } // 渲染 metabox 内容 function mutiara_order_clone_meta_box_content($post) { $order_id = $post->ID; // 检查是否有活跃定时任务 $has_scheduled = !empty(as_get_scheduled_actions(array( 'hook' => 'mutiara_scheduled_order_clone', 'args' => array($order_id), 'status' => array('pending', 'scheduled') ))); ?> <div class="inside"> <?php if (!$has_scheduled) : ?> <p>选择克隆周期:</p> <select id="clone-interval" name="clone-interval"> <option value="weekly">每周</option> <option value="biweekly">每两周</option> <option value="monthly">每月</option> </select> <p><button type="button" id="schedule-clone" class="button button-primary" data-order-id="<?php echo $order_id; ?>">启动定时克隆</button></p> <?php else : ?> <p>当前已有定时克隆任务运行</p> <p><button type="button" id="stop-clone" class="button button-secondary" data-order-id="<?php echo $order_id; ?>">停止定时克隆</button></p> <?php endif; ?> </div> <?php } // AJAX处理启动/停止请求 add_action('wp_ajax_schedule_order_clone', 'mutiara_ajax_schedule_order_clone'); add_action('wp_ajax_stop_order_clone', 'mutiara_ajax_stop_order_clone'); function mutiara_ajax_schedule_order_clone() { if (!current_user_can('edit_shop_orders')) { wp_send_json_error('无权限操作'); } $order_id = intval($_POST['order_id']); $interval = sanitize_text_field($_POST['interval']); mutiara_schedule_order_clone($order_id, $interval); wp_send_json_success('定时克隆已启动'); } function mutiara_ajax_stop_order_clone() { if (!current_user_can('edit_shop_orders')) { wp_send_json_error('无权限操作'); } $order_id = intval($_POST['order_id']); // 取消所有相关任务 $actions = as_get_scheduled_actions(array( 'hook' => 'mutiara_scheduled_order_clone', 'args' => array($order_id), 'status' => array('pending', 'scheduled') )); foreach ($actions as $action) { as_unschedule_action($action->hook, $action->args, $action->group); } wp_send_json_success('定时克隆已停止'); } // 加载前端交互JS add_action('admin_footer', 'mutiara_clone_scheduler_js'); function mutiara_clone_scheduler_js() { global $post_type; if ($post_type !== 'shop_order') return; ?> <script> jQuery(document).ready(function($) { $('#schedule-clone').click(function() { const orderId = $(this).data('order-id'); const interval = $('#clone-interval').val(); $.ajax({ url: ajaxurl, type: 'POST', data: { action: 'schedule_order_clone', order_id: orderId, interval: interval }, success: res => { alert(res.data); location.reload(); }, error: () => alert('操作失败') }); }); $('#stop-clone').click(function() { const orderId = $(this).data('order-id'); $.ajax({ url: ajaxurl, type: 'POST', data: { action: 'stop_order_clone', order_id: orderId }, success: res => { alert(res.data); location.reload(); }, error: () => alert('操作失败') }); }); }); </script> <?php }
二、常见错误排查方案
1. 致命错误定位
先开启WP debug模式,在wp-config.php里加这段代码:
define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false);
然后看wp-content/debug.log里的报错信息,常见问题:
- Action Scheduler未激活:确认插件已启用,且调用的函数(比如
as_schedule_recurring_action)存在 - 克隆函数参数错误:检查
mutiara_woocommerce_order_clone是否正确接收$order_id,且内部有没有未处理的空订单情况
2. 定时任务不执行
- 看Action Scheduler后台:WP后台
工具 → Action Scheduler里查看任务状态,有没有失败或未调度的任务 - 检查WP Cron:访问
你的域名/wp-cron.php?doing_wp_cron手动触发,看任务是否执行 - 自定义周期失效:每两周的周期要确保
cron_schedules过滤器在添加任务前已注册
3. 重复克隆问题
每次添加任务前必须检查已有任务,代码里已经加了as_get_scheduled_actions的判断,不要跳过这步,否则会出现一个订单被多次克隆的情况。
三、额外注意事项
- 权限控制:代码里用
current_user_can('edit_shop_orders')限制了操作权限,不要去掉 - 订单状态过滤:在你的克隆函数里加个判断,只克隆有效状态的订单,比如:
function mutiara_woocommerce_order_clone($order_id) { $order = wc_get_order($order_id); if (!$order || !in_array($order->get_status(), array('completed', 'processing'))) { // 订单无效就取消后续任务 as_unschedule_action('mutiara_scheduled_order_clone', array($order_id)); return; } // 你的克隆逻辑... }
- 性能考量:如果定时任务太多,会影响服务器性能,建议限制可定时克隆的订单数量
内容的提问来源于stack exchange,提问作者iv444
相关产品推荐
相关产品推荐

