WordPress Cron周五异常:缺失计划/触发过频,WooCommerce订单克隆失效
WooCommerce每周重复订单Cron故障分析与修复
问题根源
- 自定义Cron调度注册失效:WordPress更新后,
everyweek调度的注册时机被打乱,系统无法识别这个自定义调度,触发“Cron missing schedule”错误。 - 对象参数传递不可靠:直接把
WC_Order对象传给Cron任务是错误的——WordPress存储Cron任务时会序列化参数,但对象序列化后无法完整还原为有效WC_Order实例,执行时就会出现订单ID为0的情况,且WordPress会因任务失败自动每2分钟重试,造成频繁触发。 - 旧无效任务残留:更新前创建的错误Cron任务(带无效对象参数)未被清理,持续引发异常。
修复步骤
1. 确保自定义Cron调度正确注册
把调度注册逻辑绑定到init钩子,保证WordPress启动时就加载这个自定义调度:
// 在WordPress初始化阶段注册每周调度 add_action('init', function() { add_filter('cron_schedules', 'cron_add_weekly'); }); function cron_add_weekly( $schedules ) { $schedules['everyweek'] = array( 'interval' => 60 * 60 * 24 * 7, // 每周总秒数 'display' => __( 'Once Every Week' ) ); return $schedules; }
2. 修改Cron参数传递逻辑(用订单ID替代对象)
Cron任务不能可靠传递对象,改用订单ID作为参数,在触发函数中重新获取订单实例:
修改激活函数:
add_action('woocommerce_order_action_clone_order_weekly', 'cronstarter_activation_weekly'); function cronstarter_activation_weekly( $order ) { if ( ! is_a($order, 'WC_Order') ) { return; } $order_id = $order->get_id(); // 只传订单ID,避免对象序列化问题 $args = array( $order_id ); // 避免重复创建相同任务 if( ! wp_next_scheduled( 'clone_order_weekly', $args ) ) { wp_schedule_event(time(), 'everyweek', 'clone_order_weekly', $args ); } }
修改触发函数:
add_action('clone_order_weekly', 'trigger_action_clone_order', 10, 1); // 明确声明接收1个参数 function trigger_action_clone_order( $order_id ) { // 通过ID重新获取订单对象 $order = wc_get_order( $order_id ); if ( ! is_a($order, 'WC_Order') || $order->get_order_number() == 0 ) { // 删除无效的Cron任务,避免重复触发错误 wp_unschedule_event( wp_next_scheduled( 'clone_order_weekly', array($order_id) ), 'clone_order_weekly', array($order_id) ); return; } // 测试邮件(可保留或删除) $recipients = 'myemail@someemail.com'; $subject = 'Scheduled Cron Job from Order number #'.$order->get_order_number(); $message = 'This is a test mail from a scheduled Cron Job on Order number #'.$order->get_order_number(); wp_mail($recipients, $subject, $message); // 更新父订单的元数据标记 $order->update_meta_data( '_is_recurring_order', 'true'); $order->update_meta_data( '_is_recurring_order_weekly_parent', 'true'); $order->update_meta_data( '_is_recurring_order_child_created', date("d-m-Y H:i:s")); $order->save(); // 执行克隆逻辑 $child_order = mutiara_woocommerce_order_clone( $order_id, 'everyweek'); if ( $child_order && is_a($child_order, 'WC_Order') ) { $child_order_id = $child_order->get_id(); $order->update_meta_data( '_recurring_order_child_id', $child_order_id ); $order->save(); } }
3. 清理旧的无效Cron任务
把下面的代码临时添加到主题的functions.php,登录后台执行一次,清理所有旧的错误任务:
add_action('admin_init', function() { $crons = _get_cron_array(); foreach ( $crons as $timestamp => $hooks ) { if ( isset( $hooks['clone_order_weekly'] ) ) { foreach ( $hooks['clone_order_weekly'] as $hash => $cron ) { wp_unschedule_event( $timestamp, 'clone_order_weekly', $cron['args'] ); } } } wp_die('旧Cron任务已清理,请返回后台'); });
执行完成后,记得删除这段代码。
4. 重新激活订单克隆任务
清理完旧任务后,回到对应订单页面,重新点击激活每周克隆的按钮,创建新的有效Cron任务。
内容的提问来源于stack exchange,提问作者iv444
相关产品推荐
相关产品推荐

