WooCommerce补货通知插件问题:仅发订阅邮件不发补货邮件
WooCommerce补货通知插件:补货邮件不触发的修复方案
问题概述
开发的WooCommerce补货通知插件中,用户订阅时的确认邮件可正常发送,但商品补货时的通知邮件无法触发,以下是问题排查及修复方案:
核心问题分析
- 缺失关键查询函数:代码中调用了
get_notification_data_by_product_id()但未定义,导致无法获取订阅用户的邮箱数据 - 钩子参数不匹配:使用
woocommerce_product_set_stock钩子时,参数接收错误,该钩子实际传递的是商品对象和库存数量,而非原代码中的$product_id和$stock_status_transition - 库存判断逻辑错误:
!$product->managing_stock()条件会排除开启库存管理的商品,不符合多数补货场景;同时库存状态转换的判断依赖不存在的参数,逻辑无法触发 - 钩子选择不当:
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
相关产品推荐
相关产品推荐

