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 .= ''; } 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; } }