init_hooks();
}
/**
* 初始化钩子
*/
private function init_hooks() {
// 管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 产品数据面板
add_filter('woocommerce_product_data_tabs', array($this, 'add_product_data_tabs'));
add_action('woocommerce_product_data_panels', array($this, 'add_product_data_panels'));
add_action('woocommerce_process_product_meta', array($this, 'save_product_data'));
// 产品类型
add_filter('product_type_selector', array($this, 'add_product_types'));
// 订单管理
add_action('add_meta_boxes', array($this, 'add_order_meta_boxes'));
add_action('woocommerce_admin_order_data_after_billing_address', array($this, 'display_order_subscription_info'));
// 脚本和样式
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
// AJAX 处理
add_action('wp_ajax_yoone_search_products', array($this, 'ajax_search_products'));
add_action('wp_ajax_yoone_get_bundle_items', array($this, 'ajax_get_bundle_items'));
add_action('wp_ajax_yoone_save_bundle_items', array($this, 'ajax_save_bundle_items'));
// 列表页面自定义列
add_filter('manage_product_posts_columns', array($this, 'add_product_columns'));
add_action('manage_product_posts_custom_column', array($this, 'display_product_columns'), 10, 2);
}
/**
* 加载管理脚本
*/
public function enqueue_admin_scripts($hook) {
global $post_type;
if ($post_type === 'product' || strpos($hook, 'yoone-subscriptions') !== false) {
wp_enqueue_script(
'yoone-admin',
YOONE_SUBSCRIPTIONS_PLUGIN_URL . 'assets/js/admin.js',
array('jquery', 'jquery-ui-sortable'),
YOONE_SUBSCRIPTIONS_VERSION,
true
);
wp_enqueue_style(
'yoone-admin',
YOONE_SUBSCRIPTIONS_PLUGIN_URL . 'assets/css/admin.css',
array(),
YOONE_SUBSCRIPTIONS_VERSION
);
wp_localize_script('yoone-admin', 'yoone_admin_params', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('yoone_admin_nonce'),
'i18n' => array(
'loading' => __('加载中...', 'yoone-subscriptions'),
'error' => __('发生错误', 'yoone-subscriptions'),
'confirm_delete' => __('确定要删除吗?', 'yoone-subscriptions'),
'select_product' => __('选择产品', 'yoone-subscriptions'),
'add_item' => __('添加项目', 'yoone-subscriptions'),
'remove_item' => __('移除项目', 'yoone-subscriptions'),
)
));
}
}
/*
|--------------------------------------------------------------------------
| 管理菜单
|--------------------------------------------------------------------------
*/
/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_menu_page(
__('Yoone 订阅', 'yoone-subscriptions'),
__('Yoone 订阅', 'yoone-subscriptions'),
'manage_woocommerce',
'yoone-subscriptions',
array($this, 'subscriptions_page'),
'dashicons-update',
56
);
add_submenu_page(
'yoone-subscriptions',
__('所有订阅', 'yoone-subscriptions'),
__('所有订阅', 'yoone-subscriptions'),
'manage_woocommerce',
'yoone-subscriptions',
array($this, 'subscriptions_page')
);
add_submenu_page(
'yoone-subscriptions',
__('套装管理', 'yoone-subscriptions'),
__('套装管理', 'yoone-subscriptions'),
'manage_woocommerce',
'yoone-bundles',
array($this, 'bundles_page')
);
add_submenu_page(
'yoone-subscriptions',
__('支付设置', 'yoone-subscriptions'),
__('支付设置', 'yoone-subscriptions'),
'manage_woocommerce',
'yoone-payment-settings',
array($this, 'payment_settings_page')
);
add_submenu_page(
'yoone-subscriptions',
__('报告', 'yoone-subscriptions'),
__('报告', 'yoone-subscriptions'),
'manage_woocommerce',
'yoone-reports',
array($this, 'reports_page')
);
}
/**
* 订阅管理页面
*/
public function subscriptions_page() {
$list_table = new Yoone_Subscriptions_List_Table();
$list_table->prepare_items();
echo '
';
echo '
' . __('订阅管理', 'yoone-subscriptions') . '
';
$list_table->display();
echo '';
}
/**
* 套装管理页面
*/
public function bundles_page() {
$action = isset($_GET['action']) ? $_GET['action'] : 'list';
switch ($action) {
case 'edit':
case 'add':
$this->bundle_edit_page();
break;
default:
$this->bundle_list_page();
break;
}
}
/**
* 套装列表页面
*/
private function bundle_list_page() {
$list_table = new Yoone_Bundles_List_Table();
$list_table->prepare_items();
echo '';
echo '
';
$list_table->display();
echo '
';
}
/**
* 套装编辑页面
*/
private function bundle_edit_page() {
$bundle_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
$bundle = new Yoone_Bundle($bundle_id);
if (isset($_POST['save_bundle'])) {
$this->save_bundle_data($bundle);
}
include YOONE_SUBSCRIPTIONS_PLUGIN_PATH . 'includes/admin/views/bundle-edit.php';
}
/**
* 支付设置页面
*/
public function payment_settings_page() {
if (isset($_POST['save_settings'])) {
$this->save_payment_settings();
}
include YOONE_SUBSCRIPTIONS_PLUGIN_PATH . 'includes/admin/views/payment-settings.php';
}
/**
* 报告页面
*/
public function reports_page() {
include YOONE_SUBSCRIPTIONS_PLUGIN_PATH . 'includes/admin/views/reports.php';
}
/*
|--------------------------------------------------------------------------
| 产品数据面板
|--------------------------------------------------------------------------
*/
/**
* 添加产品数据标签
*/
public function add_product_data_tabs($tabs) {
$tabs['yoone_bundle'] = array(
'label' => __('套装设置', 'yoone-subscriptions'),
'target' => 'yoone_bundle_product_data',
'class' => array('show_if_yoone_bundle'),
'priority' => 25,
);
$tabs['yoone_subscription'] = array(
'label' => __('订阅设置', 'yoone-subscriptions'),
'target' => 'yoone_subscription_product_data',
'class' => array(),
'priority' => 26,
);
return $tabs;
}
/**
* 添加产品数据面板
*/
public function add_product_data_panels() {
global $post;
// 套装设置面板
echo '';
woocommerce_wp_select(array(
'id' => '_yoone_bundle_discount_type',
'label' => __('折扣类型', 'yoone-subscriptions'),
'options' => array(
'' => __('无折扣', 'yoone-subscriptions'),
'percentage' => __('百分比折扣', 'yoone-subscriptions'),
'fixed' => __('固定金额折扣', 'yoone-subscriptions'),
),
));
woocommerce_wp_text_input(array(
'id' => '_yoone_bundle_discount_value',
'label' => __('折扣值', 'yoone-subscriptions'),
'description' => __('输入折扣值(百分比或固定金额)', 'yoone-subscriptions'),
'type' => 'number',
'custom_attributes' => array(
'step' => '0.01',
'min' => '0',
),
));
woocommerce_wp_text_input(array(
'id' => '_yoone_bundle_min_quantity',
'label' => __('最小数量', 'yoone-subscriptions'),
'description' => __('套装中产品的最小总数量', 'yoone-subscriptions'),
'type' => 'number',
'custom_attributes' => array(
'min' => '0',
),
));
woocommerce_wp_text_input(array(
'id' => '_yoone_bundle_max_quantity',
'label' => __('最大数量', 'yoone-subscriptions'),
'description' => __('套装中产品的最大总数量(0表示无限制)', 'yoone-subscriptions'),
'type' => 'number',
'custom_attributes' => array(
'min' => '0',
),
));
echo '
';
echo '
' . __('套装产品', 'yoone-subscriptions') . '
';
echo '
';
echo '
';
echo '
';
echo '
';
echo '
';
echo '
';
// 订阅设置面板
echo '';
woocommerce_wp_checkbox(array(
'id' => '_yoone_subscription_enabled',
'label' => __('启用订阅', 'yoone-subscriptions'),
'description' => __('将此产品设为订阅产品', 'yoone-subscriptions'),
));
woocommerce_wp_select(array(
'id' => '_yoone_subscription_period',
'label' => __('订阅周期', 'yoone-subscriptions'),
'options' => array(
'day' => __('天', 'yoone-subscriptions'),
'week' => __('周', 'yoone-subscriptions'),
'month' => __('月', 'yoone-subscriptions'),
'year' => __('年', 'yoone-subscriptions'),
),
'value' => get_post_meta($post->ID, '_yoone_subscription_period', true) ?: 'month',
));
woocommerce_wp_text_input(array(
'id' => '_yoone_subscription_interval',
'label' => __('订阅间隔', 'yoone-subscriptions'),
'description' => __('每隔多少个周期收费一次', 'yoone-subscriptions'),
'type' => 'number',
'value' => get_post_meta($post->ID, '_yoone_subscription_interval', true) ?: '1',
'custom_attributes' => array(
'min' => '1',
),
));
woocommerce_wp_text_input(array(
'id' => '_yoone_subscription_length',
'label' => __('订阅长度', 'yoone-subscriptions'),
'description' => __('订阅持续多少个周期(0表示永久)', 'yoone-subscriptions'),
'type' => 'number',
'value' => get_post_meta($post->ID, '_yoone_subscription_length', true) ?: '0',
'custom_attributes' => array(
'min' => '0',
),
));
woocommerce_wp_text_input(array(
'id' => '_yoone_subscription_trial_length',
'label' => __('试用期长度', 'yoone-subscriptions'),
'description' => __('免费试用期天数(0表示无试用期)', 'yoone-subscriptions'),
'type' => 'number',
'value' => get_post_meta($post->ID, '_yoone_subscription_trial_length', true) ?: '0',
'custom_attributes' => array(
'min' => '0',
),
));
woocommerce_wp_text_input(array(
'id' => '_yoone_subscription_signup_fee',
'label' => __('注册费', 'yoone-subscriptions'),
'description' => __('一次性注册费用', 'yoone-subscriptions'),
'type' => 'number',
'value' => get_post_meta($post->ID, '_yoone_subscription_signup_fee', true) ?: '0',
'custom_attributes' => array(
'step' => '0.01',
'min' => '0',
),
));
echo '
';
}
/**
* 保存产品数据
*/
public function save_product_data($post_id) {
// 套装设置
$bundle_fields = array(
'_yoone_bundle_discount_type',
'_yoone_bundle_discount_value',
'_yoone_bundle_min_quantity',
'_yoone_bundle_max_quantity',
);
foreach ($bundle_fields as $field) {
if (isset($_POST[$field])) {
update_post_meta($post_id, $field, sanitize_text_field($_POST[$field]));
}
}
// 订阅设置
$subscription_fields = array(
'_yoone_subscription_enabled',
'_yoone_subscription_period',
'_yoone_subscription_interval',
'_yoone_subscription_length',
'_yoone_subscription_trial_length',
'_yoone_subscription_signup_fee',
);
foreach ($subscription_fields as $field) {
if (isset($_POST[$field])) {
update_post_meta($post_id, $field, sanitize_text_field($_POST[$field]));
} else {
delete_post_meta($post_id, $field);
}
}
// 如果是套装产品,创建或更新套装记录
if (isset($_POST['product-type']) && $_POST['product-type'] === 'yoone_bundle') {
$this->save_bundle_product_data($post_id);
}
}
/**
* 添加产品类型
*/
public function add_product_types($types) {
$types['yoone_bundle'] = __('套装产品', 'yoone-subscriptions');
return $types;
}
/*
|--------------------------------------------------------------------------
| 订单管理
|--------------------------------------------------------------------------
*/
/**
* 添加订单元框
*/
public function add_order_meta_boxes() {
add_meta_box(
'yoone-order-subscriptions',
__('相关订阅', 'yoone-subscriptions'),
array($this, 'order_subscriptions_meta_box'),
'shop_order',
'normal',
'default'
);
}
/**
* 订单订阅元框
*/
public function order_subscriptions_meta_box($post) {
global $wpdb;
$subscriptions = $wpdb->get_results($wpdb->prepare("
SELECT * FROM {$wpdb->prefix}yoone_subscriptions
WHERE parent_order_id = %d
", $post->ID));
if (empty($subscriptions)) {
echo '' . __('此订单没有相关订阅', 'yoone-subscriptions') . '
';
return;
}
echo '';
echo '';
echo '';
echo '| ' . __('订阅ID', 'yoone-subscriptions') . ' | ';
echo '' . __('状态', 'yoone-subscriptions') . ' | ';
echo '' . __('金额', 'yoone-subscriptions') . ' | ';
echo '' . __('下次付款', 'yoone-subscriptions') . ' | ';
echo '' . __('操作', 'yoone-subscriptions') . ' | ';
echo '
';
echo '';
echo '';
foreach ($subscriptions as $subscription) {
echo '';
echo '| #' . $subscription->id . ' | ';
echo '' . ucfirst($subscription->status) . ' | ';
echo '' . wc_price($subscription->total) . ' | ';
echo '' . ($subscription->next_payment_date ? date('Y-m-d', strtotime($subscription->next_payment_date)) : '-') . ' | ';
echo '';
echo '' . __('查看', 'yoone-subscriptions') . '';
echo ' | ';
echo '
';
}
echo '';
echo '
';
}
/**
* 显示订单订阅信息
*/
public function display_order_subscription_info($order) {
$has_subscription = false;
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if ($product && $product->get_meta('_yoone_subscription_enabled') === 'yes') {
$has_subscription = true;
break;
}
}
if ($has_subscription) {
echo '';
echo '
' . __('此订单包含订阅产品', 'yoone-subscriptions') . '
';
echo '
';
}
}
/*
|--------------------------------------------------------------------------
| 产品列表自定义列
|--------------------------------------------------------------------------
*/
/**
* 添加产品列
*/
public function add_product_columns($columns) {
$new_columns = array();
foreach ($columns as $key => $column) {
$new_columns[$key] = $column;
if ($key === 'product_type') {
$new_columns['yoone_subscription'] = __('订阅', 'yoone-subscriptions');
$new_columns['yoone_bundle'] = __('套装', 'yoone-subscriptions');
}
}
return $new_columns;
}
/**
* 显示产品列内容
*/
public function display_product_columns($column, $post_id) {
switch ($column) {
case 'yoone_subscription':
$enabled = get_post_meta($post_id, '_yoone_subscription_enabled', true);
if ($enabled === 'yes') {
echo '';
} else {
echo '';
}
break;
case 'yoone_bundle':
$product = wc_get_product($post_id);
if ($product && $product->get_type() === 'yoone_bundle') {
echo '';
} else {
echo '';
}
break;
}
}
/*
|--------------------------------------------------------------------------
| AJAX 处理
|--------------------------------------------------------------------------
*/
/**
* AJAX 搜索产品
*/
public function ajax_search_products() {
check_ajax_referer('yoone_admin_nonce', 'nonce');
$term = sanitize_text_field($_POST['term']);
$products = wc_get_products(array(
'limit' => 20,
'status' => 'publish',
's' => $term,
));
$results = array();
foreach ($products as $product) {
$results[] = array(
'id' => $product->get_id(),
'text' => $product->get_name() . ' (#' . $product->get_id() . ')',
'price' => $product->get_price(),
);
}
wp_send_json($results);
}
/**
* AJAX 获取套装项目
*/
public function ajax_get_bundle_items() {
check_ajax_referer('yoone_admin_nonce', 'nonce');
$product_id = intval($_POST['product_id']);
$bundle = new Yoone_Bundle();
$bundle_data = $bundle->get_bundle_by_product_id($product_id);
if ($bundle_data) {
$items = $bundle->get_bundle_items($bundle_data['id']);
wp_send_json_success($items);
} else {
wp_send_json_success(array());
}
}
/**
* AJAX 保存套装项目
*/
public function ajax_save_bundle_items() {
check_ajax_referer('yoone_admin_nonce', 'nonce');
$product_id = intval($_POST['product_id']);
$items = isset($_POST['items']) ? $_POST['items'] : array();
if (!$product_id) {
wp_send_json_error(__('无效的产品ID', 'yoone-subscriptions'));
}
// 获取或创建套装
$bundle = new Yoone_Bundle();
$bundle_data = $bundle->get_bundle_by_product_id($product_id);
if ($bundle_data) {
$bundle = new Yoone_Bundle($bundle_data['id']);
} else {
$bundle->set_product_id($product_id);
$bundle->set_name(get_the_title($product_id));
$bundle->set_status('active');
$bundle->save();
}
// 清除现有项目
$bundle->clear_items();
// 添加新项目
foreach ($items as $index => $item) {
$bundle->add_item(
intval($item['product_id']),
intval($item['quantity']),
floatval($item['discount']),
$index
);
}
wp_send_json_success(__('套装项目已保存', 'yoone-subscriptions'));
}
/*
|--------------------------------------------------------------------------
| 辅助方法
|--------------------------------------------------------------------------
*/
/**
* 保存套装产品数据
*/
private function save_bundle_product_data($product_id) {
$bundle = new Yoone_Bundle();
$bundle_data = $bundle->get_bundle_by_product_id($product_id);
if ($bundle_data) {
$bundle = new Yoone_Bundle($bundle_data['id']);
} else {
$bundle->set_product_id($product_id);
$bundle->set_name(get_the_title($product_id));
}
// 更新套装设置
$bundle->set_discount_type(sanitize_text_field($_POST['_yoone_bundle_discount_type'] ?? ''));
$bundle->set_discount_value(floatval($_POST['_yoone_bundle_discount_value'] ?? 0));
$bundle->set_min_quantity(intval($_POST['_yoone_bundle_min_quantity'] ?? 0));
$bundle->set_max_quantity(intval($_POST['_yoone_bundle_max_quantity'] ?? 0));
$bundle->set_status('active');
$bundle->save();
}
/**
* 保存套装数据
*/
private function save_bundle_data($bundle) {
if (!wp_verify_nonce($_POST['yoone_bundle_nonce'], 'save_bundle')) {
return;
}
$bundle->set_name(sanitize_text_field($_POST['bundle_name']));
$bundle->set_description(sanitize_textarea_field($_POST['bundle_description']));
$bundle->set_discount_type(sanitize_text_field($_POST['discount_type']));
$bundle->set_discount_value(floatval($_POST['discount_value']));
$bundle->set_min_quantity(intval($_POST['min_quantity']));
$bundle->set_max_quantity(intval($_POST['max_quantity']));
$bundle->set_status(sanitize_text_field($_POST['status']));
$bundle->save();
// 保存套装项目
if (isset($_POST['bundle_items'])) {
$bundle->clear_items();
foreach ($_POST['bundle_items'] as $index => $item) {
$bundle->add_item(
intval($item['product_id']),
intval($item['quantity']),
floatval($item['discount']),
$index
);
}
}
wp_redirect(admin_url('admin.php?page=yoone-bundles&message=saved'));
exit;
}
/**
* 保存支付设置
*/
private function save_payment_settings() {
if (!wp_verify_nonce($_POST['yoone_payment_nonce'], 'save_payment_settings')) {
return;
}
$settings = array(
'moneris_enabled' => sanitize_text_field($_POST['moneris_enabled'] ?? ''),
'moneris_testmode' => sanitize_text_field($_POST['moneris_testmode'] ?? ''),
'moneris_store_id' => sanitize_text_field($_POST['moneris_store_id'] ?? ''),
'moneris_api_token' => sanitize_text_field($_POST['moneris_api_token'] ?? ''),
'moneris_country' => sanitize_text_field($_POST['moneris_country'] ?? 'CA'),
);
foreach ($settings as $key => $value) {
update_option('yoone_' . $key, $value);
}
wp_redirect(admin_url('admin.php?page=yoone-payment-settings&message=saved'));
exit;
}
}