如何通过自定义按钮实现WooCommerce到货通知功能?
解决方案
1. 调整前端代码(添加必要标识与JS逻辑)
先给输入框加ID,新增商品ID隐藏字段,完善按钮的点击事件函数:
<input type="text" id="backinstock-email" name="email" placeholder="Enter your e-mail" onclick="event.preventDefault();event.stopPropagation();"> <?php $productId = $product->get_id(); echo '<input type="hidden" id="product-id" value="'.esc_attr($productId).'">'; echo '<input type="hidden" id="product-name" value="'.esc_attr($product->name).'">'; ?> <button class="button" type="button" onclick="submitData_frompopUP();">Ja</button> <script> function submitData_frompopUP() { const emailInput = document.getElementById('backinstock-email'); const email = emailInput.value.trim(); const productId = document.getElementById('product-id').value; const productName = document.getElementById('product-name').value; // 前端基础验证 if (!/^\S+@\S+\.\S+$/.test(email)) { alert('请输入有效的邮箱地址'); emailInput.focus(); return; } // 发送AJAX请求 fetch('<?php echo admin_url('admin-ajax.php'); ?>', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-WP-Nonce': '<?php echo wp_create_nonce('backinstock_submit_nonce'); ?>' }, body: `action=custom_backinstock_submit&email=${encodeURIComponent(email)}&product_id=${productId}&product_name=${encodeURIComponent(productName)}` }) .then(response => response.json()) .then(data => { if (data.success) { alert('到货通知订阅成功!'); emailInput.value = ''; } else { alert(data.message || '订阅失败,请重试'); } }) .catch(() => { alert('网络异常,请稍后再试'); }); } </script>
2. 后端注册AJAX处理逻辑(主题functions.php中添加)
通过WordPress AJAX机制对接插件的数据库操作方法,直接复用插件核心逻辑:
// 注册AJAX动作,支持登录/未登录用户 add_action('wp_ajax_custom_backinstock_submit', 'custom_handle_backinstock_submit'); add_action('wp_ajax_nopriv_custom_backinstock_submit', 'custom_handle_backinstock_submit'); function custom_handle_backinstock_submit() { // 验证请求合法性 check_ajax_referer('backinstock_submit_nonce', 'X-WP-Nonce'); // 获取并过滤参数 $email = isset($_POST['email']) ? sanitize_email($_POST['email']) : ''; $product_id = isset($_POST['product_id']) ? absint($_POST['product_id']) : 0; $product_name = isset($_POST['product_name']) ? sanitize_text_field($_POST['product_name']) : ''; // 参数有效性校验 if (!is_email($email) || $product_id === 0) { wp_send_json_error('无效的邮箱或商品信息'); } // 确认插件已激活 if (!class_exists('WC_Back_In_Stock_Notification')) { wp_send_json_error('库存通知插件未激活'); } $plugin_instance = WC_Back_In_Stock_Notification::get_instance(); // 检查是否已订阅过该商品 $existing_sub = $plugin_instance->db->get_subscription_by_email_and_product($email, $product_id); if ($existing_sub) { wp_send_json_error('您已订阅过该商品的到货通知'); } // 组装订阅数据并写入数据库 $subscription_data = [ 'email' => $email, 'product_id' => $product_id, 'product_name' => $product_name, 'date_added' => current_time('mysql'), 'status' => 'active' ]; $sub_id = $plugin_instance->db->add_subscription($subscription_data); if ($sub_id) { // 可选:调用插件的确认邮件发送逻辑(如果需要) if (method_exists($plugin_instance, 'send_confirmation_email')) { $plugin_instance->send_confirmation_email($email, $product_id); } wp_send_json_success('订阅成功'); } else { wp_send_json_error('订阅失败,请稍后重试'); } wp_die(); // 终止AJAX请求 }
关键说明
- 用商品ID而非名称:插件数据库以商品ID作为关联标识,避免名称重复/修改导致的关联错误。
- 复用插件内置方法:直接调用插件的
add_subscription和重复订阅检查方法,避免自定义SQL带来的兼容性问题。 - 安全保障:添加Nonce验证、参数过滤与校验,符合WordPress安全规范。
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

