subscription/includes/admin/class-yoone-admin.php

754 lines
26 KiB
PHP
Raw Permalink 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
/**
* 后台管理类
*
* 处理WordPress后台管理功能
*/
if (!defined('ABSPATH')) {
exit;
}
/**
* 后台管理类
*/
class Yoone_Admin {
/**
* 构造函数
*/
public function __construct() {
$this->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 '<div class="wrap">';
echo '<h1>' . __('订阅管理', 'yoone-subscriptions') . '</h1>';
$list_table->display();
echo '</div>';
}
/**
* 套装管理页面
*/
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 '<div class="wrap">';
echo '<h1>' . __('套装管理', 'yoone-subscriptions');
echo '<a href="' . admin_url('admin.php?page=yoone-bundles&action=add') . '" class="page-title-action">' . __('添加套装', 'yoone-subscriptions') . '</a>';
echo '</h1>';
$list_table->display();
echo '</div>';
}
/**
* 套装编辑页面
*/
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 '<div id="yoone_bundle_product_data" class="panel woocommerce_options_panel">';
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 '<div class="options_group">';
echo '<h4>' . __('套装产品', 'yoone-subscriptions') . '</h4>';
echo '<div id="yoone-bundle-items">';
echo '<div id="yoone-bundle-items-list"></div>';
echo '<button type="button" class="button" id="add-bundle-item">' . __('添加产品', 'yoone-subscriptions') . '</button>';
echo '</div>';
echo '</div>';
echo '</div>';
// 订阅设置面板
echo '<div id="yoone_subscription_product_data" class="panel woocommerce_options_panel">';
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 '</div>';
}
/**
* 保存产品数据
*/
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 '<p>' . __('此订单没有相关订阅', 'yoone-subscriptions') . '</p>';
return;
}
echo '<table class="widefat">';
echo '<thead>';
echo '<tr>';
echo '<th>' . __('订阅ID', 'yoone-subscriptions') . '</th>';
echo '<th>' . __('状态', 'yoone-subscriptions') . '</th>';
echo '<th>' . __('金额', 'yoone-subscriptions') . '</th>';
echo '<th>' . __('下次付款', 'yoone-subscriptions') . '</th>';
echo '<th>' . __('操作', 'yoone-subscriptions') . '</th>';
echo '</tr>';
echo '</thead>';
echo '<tbody>';
foreach ($subscriptions as $subscription) {
echo '<tr>';
echo '<td>#' . $subscription->id . '</td>';
echo '<td>' . ucfirst($subscription->status) . '</td>';
echo '<td>' . wc_price($subscription->total) . '</td>';
echo '<td>' . ($subscription->next_payment_date ? date('Y-m-d', strtotime($subscription->next_payment_date)) : '-') . '</td>';
echo '<td>';
echo '<a href="' . admin_url('admin.php?page=yoone-subscriptions&action=edit&id=' . $subscription->id) . '" class="button button-small">' . __('查看', 'yoone-subscriptions') . '</a>';
echo '</td>';
echo '</tr>';
}
echo '</tbody>';
echo '</table>';
}
/**
* 显示订单订阅信息
*/
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 '<div class="yoone-order-subscription-notice">';
echo '<p><strong>' . __('此订单包含订阅产品', 'yoone-subscriptions') . '</strong></p>';
echo '</div>';
}
}
/*
|--------------------------------------------------------------------------
| 产品列表自定义列
|--------------------------------------------------------------------------
*/
/**
* 添加产品列
*/
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 '<span class="dashicons dashicons-yes-alt" style="color: green;"></span>';
} else {
echo '<span class="dashicons dashicons-minus" style="color: #ccc;"></span>';
}
break;
case 'yoone_bundle':
$product = wc_get_product($post_id);
if ($product && $product->get_type() === 'yoone_bundle') {
echo '<span class="dashicons dashicons-products" style="color: blue;"></span>';
} else {
echo '<span class="dashicons dashicons-minus" style="color: #ccc;"></span>';
}
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;
}
}