yoone-wc-product-bundles/includes/frontend/class-yoone-product-bundles...

176 lines
6.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* 前端:渲染混装产品的自定义 add-to-cart 表单、校验并加入购物车。
*/
defined('ABSPATH') || exit;
class Yoone_Product_Bundles_Frontend {
private static $_instance = null;
public static function instance() {
if (is_null(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct() {
// 加载自定义的混装产品页面模板
add_filter('template_include', array($this, 'use_bundle_template'), 99);
// 处理加入购物车:校验数量并打包所选组件数据
add_filter('woocommerce_add_to_cart_validation', array($this, 'validate_add_to_cart'), 10, 6);
add_filter('woocommerce_add_cart_item_data', array($this, 'add_cart_item_data'), 10, 3);
// 在购物车/订单中显示组件摘要
add_filter('woocommerce_get_item_data', array($this, 'display_cart_item_data'), 10, 2);
// 结算前动态调整价格
add_action('woocommerce_before_calculate_totals', array($this, 'adjust_bundle_price'), 20, 1);
// 为混装产品页增加 body class便于主题兼容样式控制
add_filter('body_class', array($this, 'filter_body_class'));
// 从 woocommerce_single_product_summary 钩子中移除默认的 add-to-cart
add_action('init', array($this, 'remove_default_add_to_cart'));
}
/**
* 移除默认的 add-to-cart 按钮,因为我们的模板会自己处理
*/
public function remove_default_add_to_cart() {
remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30);
}
/**
* 如果是混装产品页面,则加载我们的自定义模板。
*/
public function use_bundle_template($template) {
if (is_singular('product')) {
global $post;
$product = wc_get_product($post->ID);
if ($product && $product->get_type() === Yoone_Product_Bundles::TYPE) {
// 加载插件内的完整页面模板
$new_template = YOONE_PB_PATH . 'templates/single-product-yoone-bundle.php';
if (file_exists($new_template)) {
return $new_template;
}
}
}
return $template;
}
/**
* 在混装产品页增加 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;
}
/**
* 校验混装产品加入购物车:至少选择一个组件。
*/
public function validate_add_to_cart($passed, $product_id, $quantity, $variation_id = null, $variations = null, $cart_item_data = null) {
$product = wc_get_product($product_id);
if ($product->get_type() !== Yoone_Product_Bundles::TYPE) {
return $passed;
}
$config = Yoone_Product_Bundles::get_bundle_config($product);
$min_qty = max(1, absint($config['min_qty']));
$components = !empty($_POST['yoone_bundle_components']) ? $_POST['yoone_bundle_components'] : array();
$total_qty = 0;
foreach ($components as $comp_id => $qty) {
$qty = absint($qty);
if ($qty > 0) {
$total_qty += $qty;
}
}
if ($total_qty < $min_qty) {
wc_add_notice(sprintf(__('您需要至少选择 %d 件商品才能将此混装包加入购物车。', 'yoone-product-bundles'), $min_qty), 'error');
return false;
}
return $passed;
}
/**
* 将混装组件数据添加到购物车项目。
*/
public function add_cart_item_data($cart_item_data, $product_id, $variation_id) {
$product = wc_get_product($product_id);
if ($product->get_type() !== Yoone_Product_Bundles::TYPE) {
return $cart_item_data;
}
if (isset($_POST['yoone_bundle_components'])) {
$components = array();
foreach ($_POST['yoone_bundle_components'] as $comp_id => $qty) {
$qty = absint($qty);
if ($qty > 0) {
$components[absint($comp_id)] = $qty;
}
}
if (!empty($components)) {
$cart_item_data['yoone_bundle_components'] = $components;
}
}
return $cart_item_data;
}
/**
* 在购物车和订单中显示混装组件的摘要。
*/
public function display_cart_item_data($item_data, $cart_item) {
if (empty($cart_item['yoone_bundle_components'])) {
return $item_data;
}
$value = "";
foreach ($cart_item['yoone_bundle_components'] as $pid => $qty) {
$product = wc_get_product($pid);
if ($product) {
$value .= $product->get_name() . ' &times; ' . $qty . "; ";
}
}
$item_data[] = array(
'key' => __('混装明细', 'yoone-product-bundles'),
'value' => rtrim($value, "; "),
'display' => ''
);
return $item_data;
}
/**
* 在将商品添加到购物车之前,根据所选组件动态计算混装产品的总价。
*/
public function adjust_bundle_price($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
if (isset($cart_item['yoone_bundle_components'])) {
$total_price = 0;
foreach ($cart_item['yoone_bundle_components'] as $pid => $qty) {
$product = wc_get_product($pid);
if ($product) {
$total_price += (float) $product->get_price() * $qty;
}
}
$cart_item['data']->set_price($total_price);
}
}
}
}