'subscription',
'plural' => 'subscriptions',
'ajax' => false,
));
}
/**
* 获取列
*/
public function get_columns() {
return array(
'cb' => '',
'id' => __('ID', 'yoone-subscriptions'),
'customer' => __('客户', 'yoone-subscriptions'),
'status' => __('状态', 'yoone-subscriptions'),
'total' => __('金额', 'yoone-subscriptions'),
'billing_period' => __('计费周期', 'yoone-subscriptions'),
'next_payment' => __('下次付款', 'yoone-subscriptions'),
'created_date' => __('创建日期', 'yoone-subscriptions'),
'actions' => __('操作', 'yoone-subscriptions'),
);
}
/**
* 获取可排序列
*/
public function get_sortable_columns() {
return array(
'id' => array('id', false),
'status' => array('status', false),
'total' => array('total', false),
'next_payment' => array('next_payment_date', false),
'created_date' => array('created_at', false),
);
}
/**
* 获取批量操作
*/
public function get_bulk_actions() {
return array(
'activate' => __('激活', 'yoone-subscriptions'),
'pause' => __('暂停', 'yoone-subscriptions'),
'cancel' => __('取消', 'yoone-subscriptions'),
'delete' => __('删除', 'yoone-subscriptions'),
);
}
/**
* 准备项目
*/
public function prepare_items() {
global $wpdb;
$per_page = 20;
$current_page = $this->get_pagenum();
// 处理搜索
$search = isset($_REQUEST['s']) ? sanitize_text_field($_REQUEST['s']) : '';
// 处理状态过滤
$status_filter = isset($_REQUEST['status']) ? sanitize_text_field($_REQUEST['status']) : '';
// 构建查询
$where_conditions = array('1=1');
$where_values = array();
if (!empty($search)) {
$where_conditions[] = "(s.id LIKE %s OR u.display_name LIKE %s OR u.user_email LIKE %s)";
$where_values[] = '%' . $wpdb->esc_like($search) . '%';
$where_values[] = '%' . $wpdb->esc_like($search) . '%';
$where_values[] = '%' . $wpdb->esc_like($search) . '%';
}
if (!empty($status_filter)) {
$where_conditions[] = "s.status = %s";
$where_values[] = $status_filter;
}
$where_clause = implode(' AND ', $where_conditions);
// 排序
$allowed_orderby = array('id', 'status', 'total', 'next_payment_date', 'created_at');
$orderby = isset($_REQUEST['orderby']) && in_array($_REQUEST['orderby'], $allowed_orderby) ? $_REQUEST['orderby'] : 'id';
$order = isset($_REQUEST['order']) && $_REQUEST['order'] === 'asc' ? 'ASC' : 'DESC';
// 获取总数
$total_query = "
SELECT COUNT(*)
FROM {$wpdb->prefix}yoone_subscriptions s
LEFT JOIN {$wpdb->users} u ON s.customer_id = u.ID
WHERE {$where_clause}
";
if (!empty($where_values)) {
$total_items = $wpdb->get_var($wpdb->prepare($total_query, $where_values));
} else {
$total_items = $wpdb->get_var($total_query);
}
// 获取数据
$offset = ($current_page - 1) * $per_page;
$items_query = "
SELECT s.*, u.display_name, u.user_email
FROM {$wpdb->prefix}yoone_subscriptions s
LEFT JOIN {$wpdb->users} u ON s.customer_id = u.ID
WHERE {$where_clause}
ORDER BY s.{$orderby} {$order}
LIMIT %d OFFSET %d
";
$query_values = array_merge($where_values, array($per_page, $offset));
$this->items = $wpdb->get_results($wpdb->prepare($items_query, $query_values));
// 设置分页
$this->set_pagination_args(array(
'total_items' => $total_items,
'per_page' => $per_page,
'total_pages' => ceil($total_items / $per_page),
));
$this->_column_headers = array(
$this->get_columns(),
array(),
$this->get_sortable_columns(),
);
}
/**
* 默认列显示
*/
public function column_default($item, $column_name) {
switch ($column_name) {
case 'id':
return '#' . $item->id;
case 'customer':
$customer_link = admin_url('user-edit.php?user_id=' . $item->customer_id);
return '' . $item->display_name . '
' . $item->user_email . '';
case 'status':
return $this->get_status_badge($item->status);
case 'total':
return wc_price($item->total);
case 'billing_period':
return $this->format_billing_period($item->billing_period, $item->billing_interval);
case 'next_payment':
if ($item->next_payment_date && $item->status === 'active') {
$date = new DateTime($item->next_payment_date);
return $date->format('Y-m-d H:i');
}
return '-';
case 'created_date':
$date = new DateTime($item->created_at);
return $date->format('Y-m-d H:i');
case 'actions':
return $this->get_row_actions($item);
default:
return isset($item->$column_name) ? $item->$column_name : '';
}
}
/**
* 复选框列
*/
public function column_cb($item) {
return sprintf('', $item->id);
}
/**
* 获取状态徽章
*/
private function get_status_badge($status) {
$statuses = array(
'active' => array('label' => __('活跃', 'yoone-subscriptions'), 'color' => 'green'),
'paused' => array('label' => __('暂停', 'yoone-subscriptions'), 'color' => 'orange'),
'cancelled' => array('label' => __('已取消', 'yoone-subscriptions'), 'color' => 'red'),
'expired' => array('label' => __('已过期', 'yoone-subscriptions'), 'color' => 'gray'),
'pending' => array('label' => __('待处理', 'yoone-subscriptions'), 'color' => 'blue'),
);
$status_info = isset($statuses[$status]) ? $statuses[$status] : array('label' => $status, 'color' => 'gray');
return sprintf(
'%s',
$status,
$status_info['color'],
$status_info['label']
);
}
/**
* 格式化计费周期
*/
private function format_billing_period($period, $interval) {
$periods = array(
'day' => __('天', 'yoone-subscriptions'),
'week' => __('周', 'yoone-subscriptions'),
'month' => __('月', 'yoone-subscriptions'),
'year' => __('年', 'yoone-subscriptions'),
);
$period_name = isset($periods[$period]) ? $periods[$period] : $period;
if ($interval > 1) {
return sprintf(__('每 %d %s', 'yoone-subscriptions'), $interval, $period_name);
} else {
return sprintf(__('每%s', 'yoone-subscriptions'), $period_name);
}
}
/**
* 获取行操作
*/
private function get_row_actions($item) {
$actions = array();
$edit_url = admin_url('admin.php?page=yoone-subscriptions&action=edit&id=' . $item->id);
$actions['edit'] = '' . __('编辑', 'yoone-subscriptions') . '';
if ($item->status === 'active') {
$pause_url = wp_nonce_url(
admin_url('admin.php?page=yoone-subscriptions&action=pause&id=' . $item->id),
'pause_subscription_' . $item->id
);
$actions['pause'] = '' . __('暂停', 'yoone-subscriptions') . '';
}
if ($item->status === 'paused') {
$resume_url = wp_nonce_url(
admin_url('admin.php?page=yoone-subscriptions&action=resume&id=' . $item->id),
'resume_subscription_' . $item->id
);
$actions['resume'] = '' . __('恢复', 'yoone-subscriptions') . '';
}
if (in_array($item->status, array('active', 'paused'))) {
$cancel_url = wp_nonce_url(
admin_url('admin.php?page=yoone-subscriptions&action=cancel&id=' . $item->id),
'cancel_subscription_' . $item->id
);
$actions['cancel'] = '' . __('取消', 'yoone-subscriptions') . '';
}
$delete_url = wp_nonce_url(
admin_url('admin.php?page=yoone-subscriptions&action=delete&id=' . $item->id),
'delete_subscription_' . $item->id
);
$actions['delete'] = '' . __('删除', 'yoone-subscriptions') . '';
return implode(' | ', $actions);
}
/**
* 显示状态过滤器
*/
protected function get_views() {
global $wpdb;
$status_counts = $wpdb->get_results("
SELECT status, COUNT(*) as count
FROM {$wpdb->prefix}yoone_subscriptions
GROUP BY status
", ARRAY_A);
$total_count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}yoone_subscriptions");
$views = array();
$current_status = isset($_REQUEST['status']) ? $_REQUEST['status'] : '';
// 全部
$class = empty($current_status) ? 'current' : '';
$views['all'] = sprintf(
'%s (%d)',
admin_url('admin.php?page=yoone-subscriptions'),
$class,
__('全部', 'yoone-subscriptions'),
$total_count
);
// 各状态
$status_labels = array(
'active' => __('活跃', 'yoone-subscriptions'),
'paused' => __('暂停', 'yoone-subscriptions'),
'cancelled' => __('已取消', 'yoone-subscriptions'),
'expired' => __('已过期', 'yoone-subscriptions'),
'pending' => __('待处理', 'yoone-subscriptions'),
);
foreach ($status_counts as $status_data) {
$status = $status_data['status'];
$count = $status_data['count'];
if (isset($status_labels[$status])) {
$class = $current_status === $status ? 'current' : '';
$views[$status] = sprintf(
'%s (%d)',
admin_url('admin.php?page=yoone-subscriptions&status=' . $status),
$class,
$status_labels[$status],
$count
);
}
}
return $views;
}
/**
* 处理批量操作
*/
public function process_bulk_action() {
$action = $this->current_action();
if (!$action) {
return;
}
$subscription_ids = isset($_REQUEST['subscription']) ? array_map('intval', $_REQUEST['subscription']) : array();
if (empty($subscription_ids)) {
return;
}
foreach ($subscription_ids as $subscription_id) {
$subscription = new Yoone_Subscription($subscription_id);
if (!$subscription->get_id()) {
continue;
}
switch ($action) {
case 'activate':
$subscription->activate();
break;
case 'pause':
$subscription->pause();
break;
case 'cancel':
$subscription->cancel();
break;
case 'delete':
$subscription->delete();
break;
}
}
wp_redirect(admin_url('admin.php?page=yoone-subscriptions&bulk_action=' . $action . '&processed=' . count($subscription_ids)));
exit;
}
/**
* 显示批量操作通知
*/
public function admin_notices() {
if (isset($_GET['bulk_action']) && isset($_GET['processed'])) {
$action = sanitize_text_field($_GET['bulk_action']);
$processed = intval($_GET['processed']);
$messages = array(
'activate' => __('已激活 %d 个订阅', 'yoone-subscriptions'),
'pause' => __('已暂停 %d 个订阅', 'yoone-subscriptions'),
'cancel' => __('已取消 %d 个订阅', 'yoone-subscriptions'),
'delete' => __('已删除 %d 个订阅', 'yoone-subscriptions'),
);
if (isset($messages[$action])) {
echo '
' . sprintf($messages[$action], $processed) . '
'; echo '