init_hooks();
}
/**
* 初始化钩子
*/
private function init_hooks() {
// 产品页面钩子
add_action('woocommerce_single_product_summary', array($this, 'display_bundle_options'), 25);
add_action('woocommerce_single_product_summary', array($this, 'display_subscription_options'), 30);
// 购物车钩子
add_filter('woocommerce_cart_item_name', array($this, 'display_cart_bundle_info'), 10, 3);
add_filter('woocommerce_cart_item_price', array($this, 'display_cart_subscription_info'), 10, 3);
// 结账钩子
add_action('woocommerce_checkout_order_review', array($this, 'display_checkout_subscription_info'));
// 我的账户钩子
add_filter('woocommerce_account_menu_items', array($this, 'add_subscriptions_menu_item'));
add_action('init', array($this, 'add_subscriptions_endpoint'));
add_action('woocommerce_account_subscriptions_endpoint', array($this, 'subscriptions_content'));
// AJAX 钩子
add_action('wp_ajax_yoone_calculate_bundle_price', array($this, 'ajax_calculate_bundle_price'));
add_action('wp_ajax_nopriv_yoone_calculate_bundle_price', array($this, 'ajax_calculate_bundle_price'));
add_action('wp_ajax_yoone_add_bundle_to_cart', array($this, 'ajax_add_bundle_to_cart'));
add_action('wp_ajax_nopriv_yoone_add_bundle_to_cart', array($this, 'ajax_add_bundle_to_cart'));
// 脚本和样式
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
// 产品类型支持
add_filter('woocommerce_product_class', array($this, 'product_class_filter'), 10, 2);
}
/**
* 加载脚本和样式
*/
public function enqueue_scripts() {
if (is_product() || is_cart() || is_checkout() || is_account_page()) {
wp_enqueue_script(
'yoone-frontend',
YOONE_SUBSCRIPTIONS_PLUGIN_URL . 'assets/js/frontend.js',
array('jquery'),
YOONE_SUBSCRIPTIONS_VERSION,
true
);
wp_enqueue_style(
'yoone-frontend',
YOONE_SUBSCRIPTIONS_PLUGIN_URL . 'assets/css/frontend.css',
array(),
YOONE_SUBSCRIPTIONS_VERSION
);
wp_localize_script('yoone-frontend', 'yoone_frontend_params', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('yoone_frontend_nonce'),
'i18n' => array(
'loading' => __('加载中...', 'yoone-subscriptions'),
'error' => __('发生错误,请重试', 'yoone-subscriptions'),
'select_products' => __('请选择产品', 'yoone-subscriptions'),
'min_quantity' => __('最小数量: %d', 'yoone-subscriptions'),
'max_quantity' => __('最大数量: %d', 'yoone-subscriptions'),
'bundle_savings' => __('套装优惠: %s', 'yoone-subscriptions'),
'subscription_info' => __('订阅信息', 'yoone-subscriptions'),
)
));
}
}
/*
|--------------------------------------------------------------------------
| 产品页面功能
|--------------------------------------------------------------------------
*/
/**
* 显示套装选项
*/
public function display_bundle_options() {
global $product;
if (!$product || $product->get_type() !== 'yoone_bundle') {
return;
}
$bundle = new Yoone_Bundle();
$bundle_data = $bundle->get_bundle_by_product_id($product->get_id());
if (!$bundle_data) {
return;
}
$bundle_items = $bundle->get_bundle_items($bundle_data['id']);
if (empty($bundle_items)) {
return;
}
wc_get_template(
'single-product/bundle-options.php',
array(
'bundle' => $bundle_data,
'bundle_items' => $bundle_items,
'product' => $product
),
'',
YOONE_SUBSCRIPTIONS_PLUGIN_PATH . 'templates/'
);
}
/**
* 显示订阅选项
*/
public function display_subscription_options() {
global $product;
if (!$product) {
return;
}
$subscription_enabled = $product->get_meta('_yoone_subscription_enabled');
if ($subscription_enabled !== 'yes') {
return;
}
$subscription_data = array(
'period' => $product->get_meta('_yoone_subscription_period'),
'interval' => $product->get_meta('_yoone_subscription_interval'),
'length' => $product->get_meta('_yoone_subscription_length'),
'trial' => $product->get_meta('_yoone_subscription_trial_length'),
'signup' => $product->get_meta('_yoone_subscription_signup_fee')
);
wc_get_template(
'single-product/subscription-options.php',
array(
'subscription_data' => $subscription_data,
'product' => $product
),
'',
YOONE_SUBSCRIPTIONS_PLUGIN_PATH . 'templates/'
);
}
/*
|--------------------------------------------------------------------------
| 购物车功能
|--------------------------------------------------------------------------
*/
/**
* 显示购物车套装信息
*/
public function display_cart_bundle_info($name, $cart_item, $cart_item_key) {
if (isset($cart_item['yoone_bundle_data'])) {
$bundle_data = $cart_item['yoone_bundle_data'];
$name .= '
';
$name .= '
' . __('套装产品', 'yoone-subscriptions') . '';
if (!empty($bundle_data['items'])) {
$name .= '
';
foreach ($bundle_data['items'] as $item) {
$item_product = wc_get_product($item['product_id']);
if ($item_product) {
$name .= '- ' . $item_product->get_name() . ' × ' . $item['quantity'] . '
';
}
}
$name .= '
';
}
if (isset($bundle_data['savings']) && $bundle_data['savings'] > 0) {
$name .= '
' . sprintf(__('节省: %s', 'yoone-subscriptions'), wc_price($bundle_data['savings'])) . '';
}
$name .= '
';
}
return $name;
}
/**
* 显示购物车订阅信息
*/
public function display_cart_subscription_info($price, $cart_item, $cart_item_key) {
if (isset($cart_item['yoone_subscription_data'])) {
$subscription_data = $cart_item['yoone_subscription_data'];
$price .= '';
$price .= '' . $this->format_subscription_string($subscription_data) . '';
$price .= '
';
}
return $price;
}
/*
|--------------------------------------------------------------------------
| 结账功能
|--------------------------------------------------------------------------
*/
/**
* 显示结账订阅信息
*/
public function display_checkout_subscription_info() {
$has_subscription = false;
foreach (WC()->cart->get_cart() as $cart_item) {
if (isset($cart_item['yoone_subscription_data'])) {
$has_subscription = true;
break;
}
}
if (!$has_subscription) {
return;
}
echo '';
echo '
' . __('订阅信息', 'yoone-subscriptions') . '
';
echo '
' . __('您的订单包含订阅产品,将会自动续费。', 'yoone-subscriptions') . '
';
foreach (WC()->cart->get_cart() as $cart_item) {
if (isset($cart_item['yoone_subscription_data'])) {
$product = $cart_item['data'];
$subscription_data = $cart_item['yoone_subscription_data'];
echo '
';
echo '' . $product->get_name() . '
';
echo '' . $this->format_subscription_string($subscription_data) . '';
echo '
';
}
}
echo '
';
}
/*
|--------------------------------------------------------------------------
| 我的账户功能
|--------------------------------------------------------------------------
*/
/**
* 添加订阅菜单项
*/
public function add_subscriptions_menu_item($items) {
$new_items = array();
foreach ($items as $key => $item) {
$new_items[$key] = $item;
if ($key === 'orders') {
$new_items['subscriptions'] = __('我的订阅', 'yoone-subscriptions');
}
}
return $new_items;
}
/**
* 添加订阅端点
*/
public function add_subscriptions_endpoint() {
add_rewrite_endpoint('subscriptions', EP_ROOT | EP_PAGES);
}
/**
* 订阅页面内容
*/
public function subscriptions_content() {
$customer_id = get_current_user_id();
if (!$customer_id) {
return;
}
// 获取用户订阅
global $wpdb;
$subscriptions = $wpdb->get_results($wpdb->prepare("
SELECT * FROM {$wpdb->prefix}yoone_subscriptions
WHERE customer_id = %d
ORDER BY created_at DESC
", $customer_id));
wc_get_template(
'myaccount/subscriptions.php',
array(
'subscriptions' => $subscriptions,
'customer_id' => $customer_id
),
'',
YOONE_SUBSCRIPTIONS_PLUGIN_PATH . 'templates/'
);
}
/*
|--------------------------------------------------------------------------
| AJAX 处理
|--------------------------------------------------------------------------
*/
/**
* AJAX 计算套装价格
*/
public function ajax_calculate_bundle_price() {
check_ajax_referer('yoone_frontend_nonce', 'nonce');
$bundle_id = intval($_POST['bundle_id']);
$selected_items = isset($_POST['selected_items']) ? $_POST['selected_items'] : array();
if (!$bundle_id || empty($selected_items)) {
wp_send_json_error(__('无效的参数', 'yoone-subscriptions'));
}
$bundle = new Yoone_Bundle($bundle_id);
if (!$bundle->get_id()) {
wp_send_json_error(__('套装不存在', 'yoone-subscriptions'));
}
// 计算价格
$total_price = 0;
$original_price = 0;
$valid_items = array();
foreach ($selected_items as $item) {
$product_id = intval($item['product_id']);
$quantity = intval($item['quantity']);
if ($quantity <= 0) {
continue;
}
$product = wc_get_product($product_id);
if (!$product) {
continue;
}
$item_price = $product->get_price() * $quantity;
$original_price += $item_price;
$valid_items[] = array(
'product_id' => $product_id,
'quantity' => $quantity,
'price' => $item_price
);
}
if (empty($valid_items)) {
wp_send_json_error(__('请选择有效的产品', 'yoone-subscriptions'));
}
// 应用套装折扣
$bundle_price = $bundle->calculate_bundle_price($valid_items);
$savings = $original_price - $bundle_price;
wp_send_json_success(array(
'original_price' => wc_price($original_price),
'bundle_price' => wc_price($bundle_price),
'savings' => wc_price($savings),
'savings_amount' => $savings
));
}
/**
* AJAX 添加套装到购物车
*/
public function ajax_add_bundle_to_cart() {
check_ajax_referer('yoone_frontend_nonce', 'nonce');
$bundle_id = intval($_POST['bundle_id']);
$selected_items = isset($_POST['selected_items']) ? $_POST['selected_items'] : array();
if (!$bundle_id || empty($selected_items)) {
wp_send_json_error(__('无效的参数', 'yoone-subscriptions'));
}
$bundle = new Yoone_Bundle($bundle_id);
if (!$bundle->get_id()) {
wp_send_json_error(__('套装不存在', 'yoone-subscriptions'));
}
// 验证数量限制
$total_quantity = array_sum(array_column($selected_items, 'quantity'));
if ($bundle->get_min_quantity() > 0 && $total_quantity < $bundle->get_min_quantity()) {
wp_send_json_error(sprintf(__('最小数量要求: %d', 'yoone-subscriptions'), $bundle->get_min_quantity()));
}
if ($bundle->get_max_quantity() > 0 && $total_quantity > $bundle->get_max_quantity()) {
wp_send_json_error(sprintf(__('最大数量限制: %d', 'yoone-subscriptions'), $bundle->get_max_quantity()));
}
// 创建套装产品并添加到购物车
$bundle_product_id = $bundle->get_product_id();
if (!$bundle_product_id) {
wp_send_json_error(__('套装产品不存在', 'yoone-subscriptions'));
}
// 计算套装价格
$bundle_price = $bundle->calculate_bundle_price($selected_items);
$original_price = 0;
foreach ($selected_items as $item) {
$product = wc_get_product($item['product_id']);
if ($product) {
$original_price += $product->get_price() * $item['quantity'];
}
}
$savings = $original_price - $bundle_price;
// 添加到购物车
$cart_item_data = array(
'yoone_bundle_data' => array(
'bundle_id' => $bundle_id,
'items' => $selected_items,
'original_price' => $original_price,
'bundle_price' => $bundle_price,
'savings' => $savings
)
);
$cart_item_key = WC()->cart->add_to_cart($bundle_product_id, 1, 0, array(), $cart_item_data);
if ($cart_item_key) {
wp_send_json_success(array(
'message' => __('套装已添加到购物车', 'yoone-subscriptions'),
'cart_url' => wc_get_cart_url()
));
} else {
wp_send_json_error(__('添加到购物车失败', 'yoone-subscriptions'));
}
}
/*
|--------------------------------------------------------------------------
| 辅助方法
|--------------------------------------------------------------------------
*/
/**
* 格式化订阅字符串
*/
private function format_subscription_string($subscription_data) {
$period_strings = array(
'day' => __('天', 'yoone-subscriptions'),
'week' => __('周', 'yoone-subscriptions'),
'month' => __('月', 'yoone-subscriptions'),
'year' => __('年', 'yoone-subscriptions')
);
$period = isset($subscription_data['period']) ? $subscription_data['period'] : 'month';
$interval = isset($subscription_data['interval']) ? intval($subscription_data['interval']) : 1;
$period_string = isset($period_strings[$period]) ? $period_strings[$period] : $period;
if ($interval > 1) {
return sprintf(__('每 %d %s', 'yoone-subscriptions'), $interval, $period_string);
} else {
return sprintf(__('每%s', 'yoone-subscriptions'), $period_string);
}
}
/**
* 产品类型过滤器
*/
public function product_class_filter($classname, $product_type) {
if ($product_type === 'yoone_bundle') {
return 'Yoone_Bundle_Product';
}
return $classname;
}
/**
* 获取用户订阅统计
*/
public function get_customer_subscription_stats($customer_id) {
global $wpdb;
$stats = $wpdb->get_row($wpdb->prepare("
SELECT
COUNT(*) as total_subscriptions,
SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active_subscriptions,
SUM(CASE WHEN status = 'paused' THEN 1 ELSE 0 END) as paused_subscriptions,
SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) as cancelled_subscriptions,
SUM(CASE WHEN status = 'active' THEN total ELSE 0 END) as monthly_total
FROM {$wpdb->prefix}yoone_subscriptions
WHERE customer_id = %d
", $customer_id), ARRAY_A);
return $stats;
}
}