setup_hooks(); } /** * 设置所有与前端相关的钩子。 */ public function setup_hooks() { // 处理混装产品的自定义“添加到购物车”流程 add_filter('woocommerce_add_to_cart_validation', array($this, 'process_bundle_add_to_cart'), 10, 3); // 当混装容器被移除时,移除其子项目 add_action('woocommerce_cart_item_removed', array($this, 'remove_bundle_children'), 10, 2); // 隐藏购物车中子项目的“移除”链接 add_filter('woocommerce_cart_item_remove_link', array($this, 'hide_child_remove_link'), 10, 2); // 在购物车中,显示子项目所属的混装产品 add_filter('woocommerce_get_item_data', array($this, 'display_child_bundle_link'), 10, 2); // 为混装产品页面添加 body class,以便于样式化 add_filter('body_class', array($this, 'filter_body_class')); // 用我们的自定义表单替换默认的“添加到购物车”按钮 add_action('woocommerce_single_product_summary', array($this, 'remove_default_add_to_cart_for_bundle'), 29); add_action('woocommerce_single_product_summary', array($this, 'render_bundle_add_to_cart_form'), 30); } /** * 劫持混装产品的“添加到购物车”流程。 * 验证提交,然后将容器和所有子产品添加到购物车。 * * @return bool False 以阻止默认的“添加到购物车”操作。 */ public function process_bundle_add_to_cart($passed, $product_id, $quantity) { $product = wc_get_product($product_id); if (!$product || $product->get_type() !== Yoone_Product_Bundles::TYPE) { return $passed; // 不是我们的产品,直接通过。 } // 1. 验证 $config = Yoone_Product_Bundles::get_bundle_config($product); $min_qty = max(1, absint($config['min_qty'])); $components = !empty($_POST['yoone_bundle_components']) ? (array) $_POST['yoone_bundle_components'] : array(); $total_qty = 0; $clean_components = array(); foreach ($components as $comp_id => $qty) { $qty = absint($qty); if ($qty > 0) { $total_qty += $qty; $clean_components[absint($comp_id)] = $qty; } } if ($total_qty < $min_qty) { wc_add_notice(sprintf(__('You need to select at least %d items to add this bundle to your cart.', 'yoone-product-bundles'), $min_qty), 'error'); return false; } // 2. 添加商品到购物车 try { $bundle_container_id = uniqid('bundle_'); // 添加主混装产品(作为价格为0的容器) WC()->cart->add_to_cart($product_id, 1, 0, array(), array('yoone_bundle_container_id' => $bundle_container_id)); // 添加子组件 foreach ($clean_components as $comp_id => $qty) { WC()->cart->add_to_cart($comp_id, $qty, 0, array(), array( 'yoone_bundle_parent_id' => $bundle_container_id, 'yoone_bundle_parent_product_id' => $product_id )); } // 设置成功消息并重定向 wc_add_to_cart_message(array($product_id => 1), true); add_filter('woocommerce_add_to_cart_redirect', function() { return wc_get_cart_url(); }); } catch (Exception $e) { wc_add_notice($e->getMessage(), 'error'); return false; } // 阻止主产品的默认“添加到购物车”行为 return false; } /** * 当一个购物车项目被移除时,检查它是否是一个混装容器。 * 如果是,则找到并移除其所有的子项目。 */ public function remove_bundle_children($removed_cart_item_key, $cart) { // 此钩子在项目已从购物车会话中移除后触发,所以我们在 `removed_cart_contents` 中查找它。 if (!isset($cart->removed_cart_contents[$removed_cart_item_key])) { return; } $removed_item = $cart->removed_cart_contents[$removed_cart_item_key]; // 检查被移除的商品是否是我们的混装容器。 if (isset($removed_item['yoone_bundle_container_id'])) { $bundle_container_id = $removed_item['yoone_bundle_container_id']; $child_item_keys_to_remove = []; // 遍历购物车,找到所有属于此容器的子项目。 // 我们不能在遍历时直接修改购物车,所以我们先收集要移除的项目的key。 foreach ($cart->get_cart() as $cart_item_key => $cart_item) { if (isset($cart_item['yoone_bundle_parent_id']) && $cart_item['yoone_bundle_parent_id'] === $bundle_container_id) { $child_item_keys_to_remove[] = $cart_item_key; } } // 现在,遍历收集到的key并从购物车中移除子项目。 foreach ($child_item_keys_to_remove as $key_to_remove) { $cart->remove_cart_item($key_to_remove); } } } /** * 隐藏混装产品子项目的移除链接。 */ public function hide_child_remove_link($link, $cart_item_key) { $cart_item = WC()->cart->get_cart_item($cart_item_key); if (isset($cart_item['yoone_bundle_parent_id'])) { return ''; } return $link; } /** * 对于子项目,在购物车中添加一个元信息行,以链接回父混装产品。 */ public function display_child_bundle_link($item_data, $cart_item) { if (isset($cart_item['yoone_bundle_parent_product_id'])) { $parent_product = wc_get_product($cart_item['yoone_bundle_parent_product_id']); if ($parent_product) { $item_data[] = array( 'key' => __('Part of', 'yoone-product-bundles'), 'value' => $parent_product->get_name(), ); } } return $item_data; } /** * 仅为混装产品移除默认的“添加到购物车”按钮。 */ public function remove_default_add_to_cart_for_bundle() { global $product; if ($product && $product->get_type() === Yoone_Product_Bundles::TYPE) { remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30); } } /** * 为混装产品渲染自定义的“添加到购物车”表单。 */ public function render_bundle_add_to_cart_form() { global $product; if ($product && $product->get_type() === Yoone_Product_Bundles::TYPE) { wc_get_template('global/yoone-bundle-form.php', array(), '', YOONE_PB_PATH . 'templates/'); } } /** * 为混装产品页面添加一个 body class。 */ public function filter_body_class($classes) { global $post; if (is_singular('product') && $post) { $product = wc_get_product($post->ID); if ($product && $product->get_type() === Yoone_Product_Bundles::TYPE) { $classes[] = 'yoone-bundle-product'; } } return $classes; } }