WooCommerce租房程序:携总价与选中日期跳转至结账页方案
WooCommerce自定义租房产品携带日期与总价到结账页方案
一、推荐方案:利用WooCommerce会话存储数据
WooCommerce原生会话机制稳定性更高,能避免AJAX跳转时的数据丢失问题,步骤如下:
1. 产品页提交数据到会话
在产品页的日历选择逻辑中,用户确认日期和总价后,通过表单或AJAX把数据存入会话:
前端脚本(产品页)
// 假设已通过日历组件获取selectedDates数组和totalCost整数 document.getElementById('checkout-btn').addEventListener('click', function(e) { e.preventDefault(); const selectedDates = ['2024-09-01', '2024-09-03']; // 示例日期 const totalCost = 300; // 示例总价 // 更新隐藏表单字段(无AJAX方案,直接提交表单) document.getElementById('selected-dates').value = JSON.stringify(selectedDates); document.getElementById('total-cost').value = totalCost; // 提交表单到购物车/结账 document.getElementById('rental-form').submit(); });
产品页表单代码
<form id="rental-form" action="/checkout/?add-to-cart=<?php echo get_the_ID(); ?>" method="post"> <?php wp_nonce_field('rental_data_nonce', 'rental_nonce'); ?> <input type="hidden" id="selected-dates" name="selected_dates" value=""> <input type="hidden" id="total-cost" name="total_cost" value=""> <button id="checkout-btn" type="submit">确认去结账</button> </form>
后台会话存储逻辑(functions.php)
// 处理表单提交,将数据存入WooCommerce会话 add_action('template_redirect', 'save_rental_data_to_session'); function save_rental_data_to_session() { if (!isset($_POST['selected_dates']) || !isset($_POST['total_cost']) || !wp_verify_nonce($_POST['rental_nonce'], 'rental_data_nonce')) { return; } $product_id = isset($_GET['add-to-cart']) ? intval($_GET['add-to-cart']) : 0; $product = wc_get_product($product_id); if ($product && $product->get_type() === 'room-rental') { // 解析并验证日期格式 $selected_dates = json_decode(stripslashes($_POST['selected_dates']), true); foreach ($selected_dates as $date) { if (!DateTime::createFromFormat('Y-m-d', $date)) { wc_add_notice('日期格式错误,请重新选择', 'error'); return; } } // 存入会话 WC()->session->set('rental_selected_dates', $selected_dates); WC()->session->set('rental_total_cost', intval($_POST['total_cost'])); } }
2. 结账页读取会话并设置订单总价
// 修改订单总价为会话中存储的租房费用 add_action('woocommerce_before_calculate_totals', 'set_rental_order_total'); function set_rental_order_total($cart) { if (is_admin() && !defined('DOING_AJAX')) return; foreach ($cart->get_cart() as $cart_item) { if ($cart_item['data']->get_type() === 'room-rental') { $rental_total = WC()->session->get('rental_total_cost'); if ($rental_total) { $cart_item['data']->set_price($rental_total); // 直接覆盖产品价格为租房总价 } } } }
3. 支付成功后将日期存入数据库
// 订单完成时,把选中日期写入不可用日期表 add_action('woocommerce_order_status_completed', 'save_rental_dates_to_db', 10, 1); function save_rental_dates_to_db($order_id) { $selected_dates = WC()->session->get('rental_selected_dates'); if (empty($selected_dates)) return; global $wpdb; $table_name = $wpdb->prefix . 'room_rental_unavailable_dates'; // 批量插入日期(需提前创建对应数据表) $values = []; foreach ($selected_dates as $date) { $values[] = "('" . $wpdb->escape($date) . "', {$order_id})"; } $wpdb->query("INSERT INTO {$table_name} (unavailable_date, order_id) VALUES " . implode(', ', $values)); // 清除会话数据,避免重复提交 WC()->session->__unset('rental_selected_dates'); WC()->session->__unset('rental_total_cost'); }
二、提前准备:创建不可用日期数据表
通过phpMyAdmin执行以下SQL创建存储表:
CREATE TABLE wp_room_rental_unavailable_dates ( id INT AUTO_INCREMENT PRIMARY KEY, unavailable_date DATE NOT NULL, order_id INT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY (unavailable_date) -- 防止同一日期被重复标记 );
内容的提问来源于stack exchange,提问作者908EH
相关产品推荐
相关产品推荐

