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

WooCommerce补货通知插件问题:仅发订阅邮件不发补货邮件

WooCommerce补货通知插件:补货邮件不触发的修复方案

问题概述

开发的WooCommerce补货通知插件中,用户订阅时的确认邮件可正常发送,但商品补货时的通知邮件无法触发,以下是问题排查及修复方案:

核心问题分析

  1. 缺失关键查询函数:代码中调用了get_notification_data_by_product_id()但未定义,导致无法获取订阅用户的邮箱数据
  2. 钩子参数不匹配:使用woocommerce_product_set_stock钩子时,参数接收错误,该钩子实际传递的是商品对象和库存数量,而非原代码中的$product_id和$stock_status_transition
  3. 库存判断逻辑错误:!$product->managing_stock()条件会排除开启库存管理的商品,不符合多数补货场景;同时库存状态转换的判断依赖不存在的参数,逻辑无法触发
  4. 钩子选择不当:woocommerce_product_set_stock并非监听库存状态变更的最佳钩子,应使用专门的woocommerce_product_stock_status_changed钩子

修复步骤

1. 补充订阅数据查询函数

添加get_notification_data_by_product_id()函数,从数据库中查询指定商品的订阅邮箱:

// Get notification data by product ID
function get_notification_data_by_product_id($product_id) {
    global $wpdb;
    $table_name = $wpdb->prefix . 'stock_notifier_notifications';
    
    return $wpdb->get_results($wpdb->prepare("SELECT email FROM $table_name WHERE product_id = %d", $product_id), ARRAY_A);
}

2. 更换并修正库存状态监听钩子

替换原有的woocommerce_product_set_stock钩子,改用woocommerce_product_stock_status_changed,并修正参数和判断逻辑:

// Hook into WooCommerce stock status changes
function woocommerce_stock_notifier_track_stock_status_changes($product_id, $old_status, $new_status) {
    $product = wc_get_product($product_id);

    // 仅当状态从缺货变为有货时触发
    if ($old_status !== 'instock' && $new_status === 'instock') {
        $notification_data = get_notification_data_by_product_id($product_id);
        if (!empty($notification_data)) {
            foreach ($notification_data as $notification) {
                send_notification_email($product_id, $notification['email']);
            }
            // 发送后删除该商品的订阅记录
            delete_notification_entries($product_id);
        }
    }
}
add_action('woocommerce_product_stock_status_changed', 'woocommerce_stock_notifier_track_stock_status_changes', 10, 3);

3. 移除不合理的库存管理判断

删除原代码中!$product->managing_stock()的条件,确保开启库存管理的商品也能触发通知

完整修复后的代码

function woocommerce_stock_notifier_enqueue_scripts() {
    wp_enqueue_script('jquery');
    wp_enqueue_script('woocommerce-stock-notifier-script', plugin_dir_url(__FILE__) . 'js/script.js', array('jquery'), '1.0.0', true);

    wp_localize_script('woocommerce-stock-notifier-script', 'stock_notifier_ajax', array('ajax_url' => admin_url('admin-ajax.php')));
}
add_action('wp_enqueue_scripts', 'woocommerce_stock_notifier_enqueue_scripts');

// Display notification form on product pages
function woocommerce_stock_notifier_display_form() {
    if (is_product() && !is_user_logged_in()) {
        global $product;
        if (!$product->is_in_stock()) {
            include(plugin_dir_path(__FILE__) . 'templates/notification-form.php');
        }
    }
}
add_action('woocommerce_single_product_summary', 'woocommerce_stock_notifier_display_form', 30);

// Handle form submission
function woocommerce_stock_notifier_handle_submission() {
    if (isset($_POST['product_id']) && isset($_POST['email'])) {
        $product_id = intval($_POST['product_id']);
        $email = sanitize_email($_POST['email']);

        // Send email to confirm subscription
        send_subscription_confirmation_email($product_id, $email);

        // Store the email and product ID for notification
        save_notification_data($product_id, $email);

        echo 'You will be notified when the product is back in stock.';
    }
    wp_die(); // Terminate the Ajax request
}
add_action('wp_ajax_woocommerce_stock_notifier_submit', 'woocommerce_stock_notifier_handle_submission');
add_action('wp_ajax_nopriv_woocommerce_stock_notifier_submit', 'woocommerce_stock_notifier_handle_submission');

// Save notification data to the database
function save_notification_data($product_id, $email) {
    global $wpdb;
    $table_name = $wpdb->prefix . 'stock_notifier_notifications';

    $wpdb->insert(
        $table_name,
        array(
            'product_id' => $product_id,
            'email' => $email,
        ),
        array('%d', '%s')
    );
}

// Send email to confirm subscription
function send_subscription_confirmation_email($product_id, $email) {
    $product = wc_get_product($product_id);
    $product_name = $product->get_name();

    $subject = 'Subscription Confirmation';
    $message = "Hello,\n\nYou have subscribed to receive notifications for the product '$product_name' when it is back in stock.";

    wp_mail($email, $subject, $message);
}

// Get notification data by product ID
function get_notification_data_by_product_id($product_id) {
    global $wpdb;
    $table_name = $wpdb->prefix . 'stock_notifier_notifications';
    
    return $wpdb->get_results($wpdb->prepare("SELECT email FROM $table_name WHERE product_id = %d", $product_id), ARRAY_A);
}

// Hook into WooCommerce stock status changes
function woocommerce_stock_notifier_track_stock_status_changes($product_id, $old_status, $new_status) {
    $product = wc_get_product($product_id);

    if ($old_status !== 'instock' && $new_status === 'instock') {
        $notification_data = get_notification_data_by_product_id($product_id);
        if (!empty($notification_data)) {
            foreach ($notification_data as $notification) {
                send_notification_email($product_id, $notification['email']);
            }
            // After sending emails, remove the notification entries for this product
            delete_notification_entries($product_id);
        }
    }
}
add_action('woocommerce_product_stock_status_changed', 'woocommerce_stock_notifier_track_stock_status_changes', 10, 3);

// Send email notification
function send_notification_email($product_id, $email) {
    $product = wc_get_product($product_id);
    $product_name = $product->get_name();

    $subject = 'Product Back in Stock Notification';
    $message = "Hello,\n\nThe product '$product_name' is back in stock. Thank you for using our notification service.";

    wp_mail($email, $subject, $message);
}

// Delete notification entries for a product
function delete_notification_entries($product_id) {
    global $wpdb;
    $table_name = $wpdb->prefix . 'stock_notifier_notifications';

    $wpdb->delete(
        $table_name,
        array('product_id' => $product_id),
        array('%d')
    );
}

// Create database table on plugin activation
function create_notification_table() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'stock_notifier_notifications';
    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE $table_name (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        product_id bigint(20) NOT NULL,
        email varchar(100) NOT NULL,
        PRIMARY KEY (id)
    ) $charset_collate;";

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}
register_activation_hook(__FILE__, 'create_notification_table');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:29:56