You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce如何移除已停用活动分类产品的待发送定时邮件

问题核心原因

你现有代码的逻辑存在两个本质问题:

  1. woocommerce_is_purchasable 钩子仅在前端判断商品是否可购买时触发,订单完成、Cron任务执行等场景根本不会运行该钩子内的逻辑,所以你写的 remove_action 几乎不会生效
  2. 已经通过 wp_schedule_event 或 wp_schedule_single_event 排入WordPress Cron队列的任务,不会因为你移除了Action就自动删除,已经入队的任务到期后还是会尝试执行

修复方案

你需要从三个层面调整逻辑,覆盖所有场景:

1. 兜底拦截:所有邮件发送前强制校验活动有效性

这是最稳妥的方案,不管是新调度还是已经入队的邮件,发送前都会先判断对应活动是否属于失效分类,是就直接终止发送,不会漏发:

// 拦截提醒邮件发送
add_action('wooevent_email_reminder', 'check_deactivated_event_before_send', 1, 4);
add_action('wooevent_email_reminder_2', 'check_deactivated_event_before_send', 1, 4);
add_action('wooevent_email_reminder_3', 'check_deactivated_event_before_send', 1, 4);
function check_deactivated_event_before_send($event_id, $order_id, $attendee_id, $template_id) {
    // 替换为你实际的失效分类别名,你代码里写的是seminar-deaktiviert,注意匹配
    if (has_term('event-deactivated', 'product_cat', $event_id)) {
        // 直接移除后续的发送动作
        global $WooEvent_Reminder_Email;
        remove_action(current_action(), array($WooEvent_Reminder_Email, 'send_mail'), 10);
    }
}

// 拦截反馈邮件发送
add_action('wooevent_email_reminder_feedback', 'check_deactivated_event_before_send_fb', 1, 3);
function check_deactivated_event_before_send_fb($event_id, $order_id, $template_id) {
    if (has_term('event-deactivated', 'product_cat', $event_id)) {
        global $WooEvent_Reminder_Email;
        remove_action(current_action(), array($WooEvent_Reminder_Email, 'send_mail_fb'), 10);
    }
}

// 拦截参会人邮件发送
add_action('we_send_email_reminder', 'check_deactivated_event_before_send_attendee', 1, 1);
function check_deactivated_event_before_send_attendee($event_data) {
    $event_id = $event_data['event_id'] ?? 0;
    if ($event_id && has_term('event-deactivated', 'product_cat', $event_id)) {
        global $WooEvent_Reminder_Email;
        remove_action(current_action(), array($WooEvent_Reminder_Email, 'send_mail_attendee'), 10);
    }
}

2. 阻止新订单生成邮件调度任务

不需要在woocommerce_is_purchasable里移除动作,直接在调度动作执行前判断订单内是否包含失效活动即可:

add_action('woocommerce_order_status_completed', 'block_deactivated_event_email_schedule', 9, 1);
function block_deactivated_event_email_schedule($order_id) {
    $order = wc_get_order($order_id);
    foreach ($order->get_items() as $item) {
        $product_id = $item->get_product_id();
        if (has_term('event-deactivated', 'product_cat', $product_id)) {
            global $WooEvent_Reminder_Email;
            remove_action('woocommerce_order_status_completed', array($WooEvent_Reminder_Email, 'remind_email'), 10);
            remove_action('woocommerce_order_status_completed', array($WooEvent_Reminder_Email, 'remind_email_fb'), 11);
            break;
        }
    }
}

3. 清理已经入队的失效活动邮件任务

你可以运行一次以下代码清理现有队列,运行后可以删除:

add_action('admin_init', 'clear_deactivated_event_cron_jobs');
function clear_deactivated_event_cron_jobs() {
    // 仅管理员运行一次,运行后注释掉即可
    if (!current_user_can('manage_options')) return;

    $cron_jobs = _get_cron_array();
    $email_hooks = [
        'wooevent_email_reminder',
        'wooevent_email_reminder_2',
        'wooevent_email_reminder_3',
        'wooevent_email_reminder_feedback',
        'we_send_email_reminder'
    ];

    foreach ($cron_jobs as $timestamp => $jobs) {
        foreach ($jobs as $hook => $events) {
            if (in_array($hook, $email_hooks)) {
                foreach ($events as $event) {
                    $event_id = $event['args'][0] ?? 0;
                    if ($event_id && has_term('event-deactivated', 'product_cat', $event_id)) {
                        wp_unschedule_event($timestamp, $hook, $event['args']);
                    }
                }
            }
        }
    }
}

其他注意事项

  • 你原有实现分类禁用活动的woocommerce_is_purchasable钩子代码可以保留,仅删除里面所有remove_action相关的代码即可
  • 注意替换代码中event-deactivated为你实际的产品分类别名,你现有代码中写的是seminar-deaktiviert,保持统一即可
  • PHP 7.0+版本调用类方法时不需要加&引用符,原有代码中的&$WooEvent_Reminder_Email可以去掉&避免报错
  • 你原有代码中移除send_mail_fb时写的参数数量是1,和原注册时的3不一致,会导致移除失败,上述修正代码已经规避了该问题

内容的提问来源于stack exchange,提问作者dig99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 19:36:03