subscription/includes/bundle/class-yoone-bundle-frontend...

318 lines
9.9 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
/**
* 混装产品前端展示类
*
* 处理混装产品的前端显示和用户交互
*/
if (!defined('ABSPATH')) {
exit;
}
/**
* 混装产品前端展示类
*/
class Yoone_Bundle_Frontend {
/**
* 构造函数
*/
public function __construct() {
$this->init_hooks();
}
/**
* 初始化钩子
*/
private function init_hooks() {
// 在产品页面显示混装选项
add_action('woocommerce_single_product_summary', array($this, 'display_bundle_options'), 25);
// 处理混装产品添加到购物车
add_filter('woocommerce_add_to_cart_validation', array($this, 'validate_bundle_add_to_cart'), 10, 3);
add_action('woocommerce_add_to_cart', array($this, 'add_bundle_to_cart'), 10, 6);
// 在购物车中显示混装信息
add_filter('woocommerce_get_item_data', array($this, 'display_bundle_cart_item_data'), 10, 2);
// 计算混装价格
add_action('woocommerce_before_calculate_totals', array($this, 'calculate_bundle_cart_item_price'));
// 加载前端脚本和样式
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
}
/**
* 显示混装选项
*/
public function display_bundle_options() {
global $product;
if (!$product || !$this->is_bundle_product($product->get_id())) {
return;
}
$bundle = $this->get_product_bundle($product->get_id());
if (!$bundle || !$bundle->is_available()) {
return;
}
$items = $bundle->get_items();
if (empty($items)) {
return;
}
// 加载模板
wc_get_template(
'single-product/bundle-options.php',
array(
'bundle' => $bundle,
'items' => $items,
'product' => $product
),
'',
YOONE_SUBSCRIPTIONS_PLUGIN_PATH . 'templates/frontend/'
);
}
/**
* 验证混装产品添加到购物车
*/
public function validate_bundle_add_to_cart($passed, $product_id, $quantity) {
if (!$this->is_bundle_product($product_id)) {
return $passed;
}
$bundle = $this->get_product_bundle($product_id);
if (!$bundle) {
wc_add_notice(__('混装产品不存在', 'yoone-subscriptions'), 'error');
return false;
}
// 验证数量
if (!$bundle->validate_quantity($quantity)) {
$min = $bundle->get_min_quantity();
$max = $bundle->get_max_quantity();
if ($max) {
$message = sprintf(__('数量必须在 %d 到 %d 之间', 'yoone-subscriptions'), $min, $max);
} else {
$message = sprintf(__('最小数量为 %d', 'yoone-subscriptions'), $min);
}
wc_add_notice($message, 'error');
return false;
}
// 验证选择的商品
$selected_items = isset($_POST['bundle_items']) ? $_POST['bundle_items'] : array();
if (empty($selected_items)) {
wc_add_notice(__('请选择混装商品', 'yoone-subscriptions'), 'error');
return false;
}
// 验证必需商品
$bundle_items = $bundle->get_items();
foreach ($bundle_items as $item) {
if ($item['is_required'] && !isset($selected_items[$item['product_id']])) {
$product = wc_get_product($item['product_id']);
$message = sprintf(__('必须选择商品: %s', 'yoone-subscriptions'), $product->get_name());
wc_add_notice($message, 'error');
return false;
}
}
// 验证库存
foreach ($selected_items as $item_product_id => $item_quantity) {
$item_product = wc_get_product($item_product_id);
if (!$item_product) {
continue;
}
if (!$item_product->has_enough_stock($item_quantity * $quantity)) {
$message = sprintf(__('商品 %s 库存不足', 'yoone-subscriptions'), $item_product->get_name());
wc_add_notice($message, 'error');
return false;
}
}
return $passed;
}
/**
* 添加混装产品到购物车
*/
public function add_bundle_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
if (!$this->is_bundle_product($product_id)) {
return;
}
$selected_items = isset($_POST['bundle_items']) ? $_POST['bundle_items'] : array();
if (empty($selected_items)) {
return;
}
// 保存混装信息到购物车项目
WC()->cart->cart_contents[$cart_item_key]['bundle_items'] = $selected_items;
WC()->cart->cart_contents[$cart_item_key]['is_bundle'] = true;
}
/**
* 在购物车中显示混装信息
*/
public function display_bundle_cart_item_data($item_data, $cart_item) {
if (!isset($cart_item['is_bundle']) || !$cart_item['is_bundle']) {
return $item_data;
}
if (!isset($cart_item['bundle_items']) || empty($cart_item['bundle_items'])) {
return $item_data;
}
$item_data[] = array(
'key' => __('混装商品', 'yoone-subscriptions'),
'value' => $this->format_bundle_items($cart_item['bundle_items'])
);
return $item_data;
}
/**
* 计算混装购物车项目价格
*/
public function calculate_bundle_cart_item_price($cart) {
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
if (!isset($cart_item['is_bundle']) || !$cart_item['is_bundle']) {
continue;
}
$product_id = $cart_item['product_id'];
$bundle = $this->get_product_bundle($product_id);
if (!$bundle) {
continue;
}
$selected_items = isset($cart_item['bundle_items']) ? $cart_item['bundle_items'] : array();
$bundle_price = $bundle->calculate_price($this->format_selected_items($selected_items));
// 设置新价格
$cart_item['data']->set_price($bundle_price);
}
}
/**
* 加载前端脚本和样式
*/
public function enqueue_scripts() {
if (is_product()) {
wp_enqueue_script(
'yoone-bundle-frontend',
YOONE_SUBSCRIPTIONS_PLUGIN_URL . 'assets/js/bundle-frontend.js',
array('jquery'),
YOONE_SUBSCRIPTIONS_VERSION,
true
);
wp_enqueue_style(
'yoone-bundle-frontend',
YOONE_SUBSCRIPTIONS_PLUGIN_URL . 'assets/css/bundle-frontend.css',
array(),
YOONE_SUBSCRIPTIONS_VERSION
);
// 本地化脚本
wp_localize_script('yoone-bundle-frontend', 'yoone_bundle_params', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('yoone_bundle_nonce'),
'i18n' => array(
'select_items' => __('请选择商品', 'yoone-subscriptions'),
'calculating' => __('计算中...', 'yoone-subscriptions'),
'error' => __('发生错误', 'yoone-subscriptions')
)
));
}
}
/*
|--------------------------------------------------------------------------
| 辅助方法
|--------------------------------------------------------------------------
*/
/**
* 检查是否为混装产品
*/
private function is_bundle_product($product_id) {
$bundle = $this->get_product_bundle($product_id);
return $bundle && $bundle->is_available();
}
/**
* 获取产品的混装配置
*/
private function get_product_bundle($product_id) {
static $bundles = array();
if (!isset($bundles[$product_id])) {
global $wpdb;
$bundle_id = $wpdb->get_var($wpdb->prepare("
SELECT id FROM {$wpdb->prefix}yoone_bundles
WHERE product_id = %d AND status = 'active'
LIMIT 1
", $product_id));
if ($bundle_id) {
$bundles[$product_id] = new Yoone_Bundle($bundle_id);
} else {
$bundles[$product_id] = false;
}
}
return $bundles[$product_id];
}
/**
* 格式化混装商品显示
*/
private function format_bundle_items($bundle_items) {
$formatted = array();
foreach ($bundle_items as $product_id => $quantity) {
$product = wc_get_product($product_id);
if ($product) {
$formatted[] = sprintf('%s × %d', $product->get_name(), $quantity);
}
}
return implode(', ', $formatted);
}
/**
* 格式化选择的商品为计算格式
*/
private function format_selected_items($selected_items) {
$formatted = array();
foreach ($selected_items as $product_id => $quantity) {
$formatted[] = array(
'product_id' => $product_id,
'quantity' => $quantity,
'discount_type' => 'none',
'discount_value' => 0,
'is_required' => false,
'sort_order' => 0
);
}
return $formatted;
}
}
// 初始化
new Yoone_Bundle_Frontend();