WooCommerce插件开发:挂钩函数后‘前往结账’按钮消失排查
问题分析与修复方案
核心问题诊断
1. 结账按钮消失原因
- 钩子使用错误:
woocommerce_proceed_to_checkout钩子负责渲染「前往结账」按钮,你的函数未输出按钮内容,直接覆盖了原钩子的默认输出,导致按钮丢失。 - 参数不匹配:该钩子的回调函数不支持
$order和$order_id参数(购物车阶段尚未生成订单),参数错误触发PHP警告,进一步破坏页面渲染。 - 冗余输出干扰:函数中的
echo "not set"会在购物车页面输出额外文本,打乱DOM结构,导致按钮无法正常显示。
2. 元数据保存失败原因
- POST参数名不匹配:选择框的
name属性是discount_select,但代码中判断的是$_POST['mytoosheh_delivery_date_option'],永远无法触发保存逻辑。 - 保存时机错误:购物车阶段尝试操作订单对象(
$order)无效,此时订单尚未创建,无法写入元数据。
修正后的完整代码
1. 购物车页面添加配送选项选择框
// Add the delivery date field to the cart page add_action('woocommerce_cart_collaterals', 'mytoosheh_add_delivery_date_field'); function mytoosheh_add_delivery_date_field() { // Get saved option from session to pre-select the user's choice $selected_option = WC()->session->get('mytoosheh_delivery_date_option', '1'); echo '<div id="discount-select-container">'; echo '<h3>' . __('زمان تحویل سفارش:', 'discount_select_option') . '</h3>'; echo '<select id="discount-select" name="discount_select">'; echo '<option value="1" ' . selected($selected_option, '1', false) . '>' . __('تحویل فوری : ' . mytoosheh_get_delivery_date(3), 'mytoosheh_delivery_date_option') . '</option>'; echo '<option value="5" ' . selected($selected_option, '5', false) . '>' . __('پنج هفته : ' . mytoosheh_get_delivery_date(35), 'mytoosheh_delivery_date_option') . '</option>'; echo '<option value="8" ' . selected($selected_option, '8', false) . '>' . __('هشت هفته : ' . mytoosheh_get_delivery_date(56), 'mytoosheh_delivery_date_option') . '</option>'; echo '</select>'; echo '</div>'; // Auto-submit cart when selection changes (improves UX) ?> <script> jQuery(document).ready(function($) { $('#discount-select').change(function() { $(this).closest('form').submit(); }); }); </script> <?php }
2. 将选择的配送选项保存到WC Session
// Save selected delivery option to WC Session add_action('woocommerce_cart_update_action_cart_updated', 'mytoosheh_save_delivery_option_to_session'); function mytoosheh_save_delivery_option_to_session() { if (isset($_POST['discount_select'])) { $option_data = sanitize_text_field($_POST['discount_select']); WC()->session->set('mytoosheh_delivery_date_option', $option_data); // Calculate and save corresponding delivery date switch($option_data) { case '1': $delivery_date = mytoosheh_get_delivery_date(3); break; case '5': $delivery_date = mytoosheh_get_delivery_date(35); break; case '8': $delivery_date = mytoosheh_get_delivery_date(56); break; default: $delivery_date = __('خطا در محاسبه', 'mytoosheh_delivery_date_option'); } WC()->session->set('mytoosheh_delivery_date', $delivery_date); } }
3. 将配送选项保存到订单元数据
// Save delivery option to order meta data when order is created add_action('woocommerce_checkout_create_order', 'mytoosheh_save_delivery_option_to_order'); function mytoosheh_save_delivery_option_to_order($order) { $option_data = WC()->session->get('mytoosheh_delivery_date_option'); $delivery_date = WC()->session->get('mytoosheh_delivery_date'); if ($option_data) { $order->update_meta_data('mytoosheh_delivery_date_option', $option_data); } if ($delivery_date) { $order->update_meta_data('mytoosheh_delivery_date', $delivery_date); } }
关键修复说明
- 使用
woocommerce_cart_update_action_cart_updated钩子处理Session保存,确保用户选择的选项在购物车更新时即时存入Session。 - 添加JS自动提交逻辑,用户更改选择后无需手动点击「更新购物车」。
- 使用
woocommerce_checkout_create_order钩子在订单创建时写入元数据,这是操作订单对象的正确时机。 - 保留预选中逻辑,返回购物车时自动显示用户之前选择的配送选项。
内容的提问来源于stack exchange,提问作者Mohammad Abtahi
相关产品推荐
相关产品推荐

