WordPress文创产品柔性订阅制服务插件开发教程
一、项目概述与需求分析
在文创产品领域,柔性订阅制服务正成为新的商业模式。与传统的固定周期订阅不同,柔性订阅允许用户根据自身需求灵活调整订阅频率、产品和时长。本教程将指导您开发一个完整的WordPress文创产品柔性订阅制服务插件。
核心功能需求:
- 多层级订阅计划管理
- 灵活的订阅周期设置
- 用户自主调整订阅内容
- 自动化支付与续费处理
- 订阅状态监控与管理
二、插件基础结构搭建
首先,我们创建插件的基本文件结构:
<?php
/**
* Plugin Name: 文创柔性订阅制服务
* Plugin URI: https://yourwebsite.com/
* Description: 为文创产品提供柔性订阅制服务解决方案
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: cultural-subscription
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('CULTURAL_SUBSCRIPTION_VERSION', '1.0.0');
define('CULTURAL_SUBSCRIPTION_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CULTURAL_SUBSCRIPTION_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
class CulturalSubscription {
private static $instance = null;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init_hooks();
}
private function init_hooks() {
// 激活/停用钩子
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 初始化
add_action('init', array($this, 'init'));
// 管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 加载文本域
add_action('plugins_loaded', array($this, 'load_textdomain'));
}
public function activate() {
// 创建必要的数据库表
$this->create_tables();
// 设置默认选项
$this->set_default_options();
// 刷新重写规则
flush_rewrite_rules();
}
public function deactivate() {
// 清理临时数据
// 注意:不删除用户订阅数据
flush_rewrite_rules();
}
public function load_textdomain() {
load_plugin_textdomain(
'cultural-subscription',
false,
dirname(plugin_basename(__FILE__)) . '/languages'
);
}
public function init() {
// 注册自定义文章类型和分类
$this->register_post_types();
}
public function add_admin_menu() {
// 添加管理菜单
add_menu_page(
__('文创订阅', 'cultural-subscription'),
__('文创订阅', 'cultural-subscription'),
'manage_options',
'cultural-subscription',
array($this, 'admin_dashboard'),
'dashicons-products',
30
);
}
private function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'cultural_subscriptions';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
user_id bigint(20) NOT NULL,
plan_id bigint(20) NOT NULL,
product_ids text NOT NULL,
subscription_type varchar(50) NOT NULL,
frequency varchar(20) NOT NULL,
next_delivery_date date NOT NULL,
status varchar(20) DEFAULT 'active',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY user_id (user_id),
KEY status (status)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
private function set_default_options() {
$default_options = array(
'currency' => 'CNY',
'min_subscription_period' => 1, // 月
'max_subscription_period' => 12, // 月
'grace_period' => 7, // 天
'auto_renew' => true,
);
add_option('cultural_subscription_settings', $default_options);
}
private function register_post_types() {
// 注册订阅计划类型
register_post_type('subscription_plan',
array(
'labels' => array(
'name' => __('订阅计划', 'cultural-subscription'),
'singular_name' => __('订阅计划', 'cultural-subscription')
),
'public' => true,
'has_archive' => true,
'supports' => array('title', 'editor', 'thumbnail'),
'menu_icon' => 'dashicons-calendar-alt',
'rewrite' => array('slug' => 'subscription-plans'),
)
);
}
public function admin_dashboard() {
// 管理面板HTML
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<div class="cultural-subscription-dashboard">
<div class="dashboard-stats">
<div class="stat-card">
<h3><?php _e('活跃订阅', 'cultural-subscription'); ?></h3>
<p class="stat-number">0</p>
</div>
<div class="stat-card">
<h3><?php _e('本月收入', 'cultural-subscription'); ?></h3>
<p class="stat-number">¥0</p>
</div>
</div>
</div>
</div>
<?php
}
}
// 启动插件
CulturalSubscription::get_instance();
?>
三、订阅计划管理系统
创建订阅计划管理类,处理柔性订阅的核心逻辑:
<?php
/**
* 订阅计划管理类
*/
class SubscriptionPlanManager {
private $db;
public function __construct() {
global $wpdb;
$this->db = $wpdb;
}
/**
* 创建柔性订阅计划
* @param array $plan_data 计划数据
* @return int|false 计划ID或false
*/
public function create_flexible_plan($plan_data) {
$defaults = array(
'title' => '',
'description' => '',
'base_price' => 0,
'frequency_options' => array('monthly', 'quarterly', 'yearly'),
'min_products' => 1,
'max_products' => 5,
'allow_customization' => true,
'status' => 'draft'
);
$plan_data = wp_parse_args($plan_data, $defaults);
// 验证数据
if (empty($plan_data['title']) || $plan_data['base_price'] <= 0) {
return false;
}
// 插入到自定义文章类型
$post_id = wp_insert_post(array(
'post_title' => sanitize_text_field($plan_data['title']),
'post_content' => wp_kses_post($plan_data['description']),
'post_type' => 'subscription_plan',
'post_status' => $plan_data['status'],
'meta_input' => array(
'_base_price' => floatval($plan_data['base_price']),
'_frequency_options' => $plan_data['frequency_options'],
'_min_products' => intval($plan_data['min_products']),
'_max_products' => intval($plan_data['max_products']),
'_allow_customization' => (bool)$plan_data['allow_customization']
)
));
return $post_id;
}
/**
* 计算订阅价格
* @param int $plan_id 计划ID
* @param array $options 用户选项
* @return float 总价格
*/
public function calculate_price($plan_id, $options) {
$base_price = get_post_meta($plan_id, '_base_price', true);
$frequency = $options['frequency'] ?? 'monthly';
$product_count = count($options['products'] ?? array());
// 频率折扣系数
$frequency_multiplier = array(
'monthly' => 1.0,
'quarterly' => 0.95, // 5%折扣
'yearly' => 0.85 // 15%折扣
);
// 产品数量系数(鼓励多选)
$product_multiplier = 1.0;
if ($product_count > 1) {
$product_multiplier = 0.9 + (0.05 * $product_count); // 每多一个产品增加5%折扣
}
// 计算总价
$total_price = $base_price *
($frequency_multiplier[$frequency] ?? 1.0) *
$product_multiplier;
return round($total_price, 2);
}
/**
* 获取可用的订阅计划
* @return array 计划列表
*/
public function get_available_plans() {
$args = array(
'post_type' => 'subscription_plan',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => '_base_price',
'value' => 0,
'compare' => '>',
'type' => 'NUMERIC'
)
)
);
$plans = get_posts($args);
$formatted_plans = array();
foreach ($plans as $plan) {
$formatted_plans[] = array(
'id' => $plan->ID,
'title' => $plan->post_title,
'description' => $plan->post_content,
'base_price' => get_post_meta($plan->ID, '_base_price', true),
'frequency_options' => get_post_meta($plan->ID, '_frequency_options', true),
'features' => $this->extract_features($plan->post_content)
);
}
return $formatted_plans;
}
/**
* 从描述中提取特性
* @param string $content 描述内容
* @return array 特性列表
*/
private function extract_features($content) {
// 简单的特性提取逻辑
$features = array();
$lines = explode("n", strip_tags($content));
foreach ($lines as $line) {
$trimmed = trim($line);
if (strlen($trimmed) > 3 && !empty($trimmed)) {
$features[] = $trimmed;
}
}
return array_slice($features, 0, 5); // 最多返回5个特性
}
}
?>
四、用户订阅管理界面
创建前端用户界面,让用户可以管理自己的订阅:
<?php
/**
* 用户订阅前端界面
*/
class SubscriptionFrontend {
public function __construct() {
add_shortcode('cultural_subscription_plans', array($this, 'render_subscription_plans'));
add_shortcode('cultural_my_subscriptions', array($this, 'render_my_subscriptions'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_scripts'));
}
/**
* 渲染订阅计划选择页面
*/
public function render_subscription_plans() {
if (!is_user_logged_in()) {
return '<div class="subscription-login-required">' .
__('请先登录以查看订阅计划', 'cultural-subscription') .
'</div>';
}
$manager = new SubscriptionPlanManager();
$plans = $manager->get_available_plans();
ob_start();
?>
<div class="cultural-subscription-plans">
<h2><?php _e('选择您的文创订阅计划', 'cultural-subscription'); ?></h2>
<div class="plans-container">
<?php foreach ($plans as $plan): ?>
<div class="subscription-plan-card">
<h3><?php echo esc_html($plan['title']); ?></h3>
<div class="plan-price">
<span class="base-price">¥<?php echo number_format($plan['base_price'], 2); ?></span>
<span class="period">/月</span>
</div>
<div class="plan-features">
<ul>
<?php foreach ($plan['features'] as $feature): ?>
<li><?php echo esc_html($feature); ?></li>
<?php endforeach; ?>
</ul>
</div>
<div class="frequency-options">
<h4><?php _e('选择频率:', 'cultural-subscription'); ?></h4>
<?php foreach ($plan['frequency_options'] as $freq): ?>
<label class="frequency-option">
<input type="radio"
name="frequency_<?php echo $plan['id']; ?>"
value="<?php echo esc_attr($freq); ?>"
data-plan-id="<?php echo $plan['id']; ?>">
<?php echo $this->get_frequency_label($freq); ?>
</label>
<?php endforeach; ?>
</div>
<button class="select-plan-btn"
data-plan-id="<?php echo $plan['id']; ?>">
<?php _e('选择此计划', 'cultural-subscription'); ?>
</button>
</div>
<?php endforeach; ?>
</div>
<!-- 产品选择模态框 -->
<div id="product-selection-modal" class="modal">
<div class="modal-content">
<span class="close-modal">×</span>
<h3><?php _e('选择文创产品', 'cultural-subscription'); ?></h3>
<div id="product-selection-area"></div>
<button id="confirm-subscription" class="button-primary">
<?php _e('确认订阅', 'cultural-subscription'); ?>
</button>
</div>
</div>
</div>
<?php
return ob_get_clean();
}
/**
* 渲染用户当前订阅
*/
public function render_my_subscriptions() {
if (!is_user_logged_in()) {
return '';
}
$user_id = get_current_user_id();
$subscriptions = $this->get_user_subscriptions($user_id);
ob_start();
?>
<div class="my-subscriptions">
<h2><?php _e('我的订阅', 'cultural-subscription'); ?></h2>
<?php if (empty($subscriptions)): ?>
<p><?php _e('您当前没有活跃的订阅。', 'cultural-subscription'); ?></p>
<?php else: ?>
<div class="subscriptions-list">
<?php foreach ($subscriptions as $subscription): ?>
<div class="subscription-item">
<div class="subscription-header">
<h3><?php echo get_the_title($subscription->plan_id); ?></h3>
<span class="status-badge <?php echo esc_attr($subscription->status); ?>">
<?php echo $this->get_status_label($subscription->status); ?>
</span>
</div>
<div class="subscription-details">
<p><strong><?php _e('频率:', 'cultural-subscription'); ?></strong>
<?php echo $this->get_frequency_label($subscription->frequency); ?>
</p>
<p><strong><?php _e('下次配送:', 'cultural-subscription'); ?></strong>
<?php echo date_i18n(get_option('date_format'), strtotime($subscription->next_delivery_date)); ?>
</p>
<div class="subscription-actions">
<button class="button modify-subscription"
data-subscription-id="<?php echo $subscription->id; ?>">
<?php _e('修改订阅', 'cultural-subscription'); ?>
</button>
<button class="button cancel-subscription"
data-subscription-id="<?php echo $subscription->id; ?>">
<?php _e('取消订阅', 'cultural-subscription'); ?>
</button>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<?php
return ob_get_clean();
}
/**
* 获取用户订阅
*/
private function get_user_subscriptions($user_id) {
global $wpdb;
$table_name = $wpdb->prefix . 'cultural_subscriptions';
return $wpdb->get_results($wpdb->prepare(
"SELECT * FROM $table_name WHERE user_id = %d ORDER BY created_at DESC",
$user_id
));
}
/**
* 获取频率标签
*/
private function get_frequency_label($frequency) {
$labels = array(
'monthly' => __('每月', 'cultural-subscription'),
'quarterly' => __('每季度', 'cultural-subscription'),
'yearly' => __('每年', 'cultural-subscription')
);
return $labels[$frequency] ?? $frequency;
}
/**
* 获取状态标签
*/
private function get_status_label($status) {
$labels = array(
'active' => __('活跃', 'cultural-subscription'),
'paused' => __('已暂停', 'cultural-subscription'),
'cancelled' => __('已取消', 'cultural-subscription'),
'expired' => __('已过期', 'cultural-subscription')
);
return $labels[$status] ?? $status;
}
/**
* 加载前端脚本和样式
*/
public function enqueue_frontend_scripts() {
wp_enqueue_style(
'cultural-subscription-frontend',
CULTURAL_SUBSCRIPTION_PLUGIN_URL . 'assets/css/frontend.css',
array(),
CULTURAL_SUBSCRIPTION_VERSION
);
wp_enqueue_script(
'cultural-subscription-frontend',
CULTURAL_SUBSCRIPTION_PLUGIN_URL . 'assets/js/frontend.js',
array('jquery'),
CULTURAL_SUBSCRIPTION_VERSION,
true
);
wp_localize_script('cultural-subscription-frontend', 'culturalSubscription', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('cultural_subscription_nonce'),
'i18n' => array(
'confirm_cancel' => __('确定要取消订阅吗?', 'cultural-subscription'),
'loading' => __('加载中...', 'cultural-subscription'),
'error' => __('发生错误,请重试', 'cultural-subscription')
)
));
}
}
// 初始化前端
new SubscriptionFrontend();
?>
## 五、AJAX处理与支付集成
创建AJAX处理器和支付集成模块:
<?php
/**
- AJAX处理器
*/
class SubscriptionAjaxHandler {
public function __construct() {
// 订阅相关AJAX
add_action('wp_ajax_create_subscription', array($this, 'handle_create_subscription'));
add_action('wp_ajax_nopriv_create_subscription', array($this, 'handle_no_privilege'));
add_action('wp_ajax_modify_subscription', array($this, 'handle_modify_subscription'));
add_action('wp_ajax_cancel_subscription', array($this, 'handle_cancel_subscription'));
// 产品选择
add_action('wp_ajax_get_products_for_plan', array($this, 'handle_get_products'));
}
/**
* 创建订阅
*/
public function handle_create_subscription() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'cultural_subscription_nonce')) {
wp_die('非法请求');
}
// 验证用户
if (!is_user_logged_in()) {
wp_send_json_error(array('message' => '请先登录'));
}
$user_id = get_current_user_id();
$plan_id = intval($_POST['plan_id']);
$frequency = sanitize_text_field($_POST['frequency']);
$product_ids = array_map('intval', $_POST['product_ids'] ?? array());
// 验证数据
if (!$plan_id || empty($product_ids)) {
wp_send_json_error(array('message' => '请选择产品和计划'));
}
// 检查计划是否存在
$plan = get_post($plan_id);
if (!$plan || $plan->post_type !== 'subscription_plan') {
wp_send_json_error(array('message' => '订阅计划不存在'));
}
// 创建订阅记录
$subscription_id = $this->create_subscription_record(array(
'user_id' => $user_id,
'plan_id' => $plan_id,
'product_ids' => $product_ids,
'frequency' => $frequency,
'status' => 'pending_payment'
));
if (!$subscription_id) {
wp_send_json_error(array('message' => '创建订阅失败'));
}
// 生成支付
$payment_data = $this->create_payment($subscription_id);
wp_send_json_success(array(
'message' => '订阅创建成功',
'subscription_id' => $subscription_id,
'payment_data' => $payment_data
));
}
/**
* 创建订阅记录
*/
private function create_subscription_record($data) {
global $wpdb;
$table_name = $wpdb->prefix . 'cultural_subscriptions';
// 计算下次配送日期
$next_delivery = $this->calculate_next_delivery($data['frequency']);
$result = $wpdb->insert($table_name, array(
'user_id' => $data['user_id'],
'plan_id' => $data['plan_id'],
'product_ids' => json_encode($data['product_ids']),
'subscription_type' => 'flexible',
'frequency' => $data['frequency'],
'next_delivery_date' => $next_delivery,
'status' => $data['status']
));
return $result ? $wpdb->insert_id : false;
}
/**
* 计算下次配送日期
*/
private function calculate_next_delivery($frequency) {
$today = current_time('Y-m-d');
switch ($frequency) {
case 'monthly':
return date('Y-m-d', strtotime($today . ' +1 month'));
case 'quarterly':
return date('Y-m-d', strtotime($today . ' +3 months'));
case 'yearly':
return date('Y-m-d', strtotime($today . ' +1 year'));
default:
return date('Y-m-d', strtotime($today . ' +1 month'));
}
}
/**
* 创建支付
*/
private function create_payment($subscription_id) {
// 这里集成支付网关
// 示例:使用WooCommerce支付
if (class_exists('WooCommerce')) {
return $this->create_woocommerce_payment($subscription_id);
}
// 或者使用其他支付网关
return array(
'type' => 'manual',
'message' => '请等待管理员确认支付'
);
}
/**
* 创建WooCommerce支付
*/
private function create_woocommerce_payment($subscription_id) {
global $wpdb;
// 获取订阅信息
$table_name = $wpdb->prefix . 'cultural_subscriptions';
$subscription = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $table_name WHERE id = %d",
$subscription_id
));
if (!$subscription) {
return false;
}
// 创建订单
$order = wc_create_order(array(
'customer_id' => $subscription->user_id,
'created_via' => 'cultural_subscription'
));
// 获取计划价格
$plan_manager = new SubscriptionPlanManager();
$price = $plan_manager->calculate_price(
$subscription->plan_id,
array(
'frequency' => $subscription->frequency,
'products' => json_decode($subscription->product_ids, true)
)
);
// 添加产品到订单
$product_ids = json_decode($subscription->product_ids, true);
foreach ($product_ids as $product_id) {
$product = wc_get_product($product_id);
if ($product) {
$order->add_product($product, 1);
}
}
// 设置订阅费用
$order->add_meta_data('_subscription_id', $subscription_id);
$order->add_meta_data('_subscription_frequency', $subscription->frequency);
$order->set_total($price);
$order->save();
return array(
'type' => 'woocommerce',
'order_id' => $order->get_id(),
'payment_url' => $order->get_checkout_payment_url()
);
}
/**
* 修改订阅
*/
public function handle_modify_subscription() {
// 验证nonce和用户权限
if (!wp_verify_nonce($_POST['nonce'], 'cultural_subscription_nonce') || !is_user_logged_in()) {
wp_die('非法请求');
}
$subscription_id = intval($_POST['subscription_id']);
$user_id = get_current_user_id();
// 验证订阅所有权
if (!$this->validate_subscription_ownership($subscription_id, $user_id)) {
wp_send_json_error(array('message' => '无权修改此订阅'));
}
// 获取修改选项
$new_frequency = sanitize_text_field($_POST['new_frequency'] ?? '');
$new_products = array_map('intval', $_POST['new_products'] ?? array());
// 更新订阅
$updated = $this->update_subscription($subscription_id, array(
'frequency' => $new_frequency,
'product_ids' => $new_products
));
if ($updated) {
wp_send_json_success(array('message' => '订阅修改成功'));
} else {
wp_send_json_error(array('message' => '修改失败'));
}
}
/**
* 验证订阅所有权
*/
private function validate_subscription_ownership($subscription_id, $user_id) {
global $wpdb;
$table_name = $wpdb->prefix . 'cultural_subscriptions';
$subscription = $wpdb->get_row($wpdb->prepare(
"SELECT user_id FROM $table_name WHERE id = %d",
$subscription_id
));
return $subscription && $subscription->user_id == $user_id;
}
/**
* 更新订阅
*/
private function update_subscription($subscription_id, $data) {
global $wpdb;
$table_name = $wpdb->prefix . 'cultural_subscriptions';
$update_data = array();
if (!empty($data['frequency'])) {
$update_data['frequency'] = $data['frequency'];
// 重新计算下次配送日期
$update_data['next_delivery_date'] = $this->calculate_next_delivery($data['frequency']);
}
if (!empty($data['product_ids'])) {
$update_data['product_ids'] = json_encode($data['product_ids']);
}
if (empty($update_data)) {
return false;
}
return $wpdb->update(
$table_name,
$update_data,
array('id' => $subscription_id)
);
}
/**
* 取消订阅
*/
public function handle_cancel_subscription() {
// 验证nonce和用户权限
if (!wp_verify_nonce($_POST['nonce'], 'cultural_subscription_nonce') || !is_user_logged_in()) {
wp_die('非法请求');
}
$subscription_id = intval($_POST['subscription_id']);
$user_id = get_current_user_id();
// 验证订阅所有权
if (!$this->validate_subscription_ownership($subscription_id, $user_id)) {
wp_send_json_error(array('message' => '无权取消此订阅'));
}
// 取消订阅(软删除)
$cancelled = $this->cancel_subscription_record($subscription_id);
if ($cancelled) {
wp_send_json_success(array('message' => '订阅已取消'));
} else {
wp_send_json_error(array('message' => '取消失败'));
}
}
/**
* 取消订阅记录
*/
private function cancel_subscription_record($subscription_id) {
global $wpdb;
$table_name = $wpdb->prefix . 'cultural_subscriptions';
return $wpdb->update(
$table_name,
array('status' => 'cancelled'),
array('id' => $subscription_id)
);
}
/**
* 获取计划相关产品
*/
public function handle_get_products() {
$plan_id = intval($_POST['plan_id']);
// 这里应该根据计划获取相关文创产品
// 示例:获取所有文创产品
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'cultural-creative' // 文创产品分类
)
)
);
$products = get_posts($args);
$formatted_products = array();
foreach ($products as $product) {
$product_obj = wc_get_product($product->ID);
$formatted_products[] = array(
'id' => $product->ID,
'name' => $product->post_title,
'price' => $product_obj->get_price(),
'image' => get_the_post_thumbnail_url($product->ID, 'thumbnail')
);
}
wp_send_json_success($formatted_products);
}
/**
* 无权限处理
*/
public function handle_no_privilege() {
wp_send_json_error(array('message' => '请先登录'));
}
}
// 初始化AJAX处理器
new SubscriptionAjaxHandler();
?>
## 六、自动化任务与通知系统
创建定时任务和通知系统:
<?php
/**
- 自动化任务管理器
*/
class SubscriptionAutomation {
public function __construct() {
// 注册定时任务
add_action('init', array($this, 'schedule_events'));
// 定义定时任务钩子
add_action('cultural_subscription_daily_check', array($this, 'daily_check'));
add_action('cultural_subscription_process_renewals', array($this, 'process_renewals'));
add_action('cultural_subscription_send_reminders', array($this, 'send_reminders'));
}
/**
* 安排定时任务
*/
public function schedule_events() {
if (!wp_next_scheduled('cultural_subscription_daily_check')) {
wp_schedule_event(time(), 'daily', 'cultural_subscription_daily_check');
}
if (!wp_next_scheduled('cultural_subscription_process_renewals')) {
wp_schedule_event(time(), 'twicedaily', 'cultural_subscription_process_renewals');
}
}
/**
* 每日检查
*/
public function daily_check() {
$this->check_expiring_subscriptions();
$this->update_subscription_statuses();
$this->cleanup_old_data();
}
/**
* 检查即将到期的订阅
*/
private function check_expiring_subscriptions() {
global $wpdb;
$table_name = $wpdb->prefix . 'cultural_subscriptions';
// 查找7天内到期的订阅
$seven_days_later = date('Y-m-d', strtotime('+7 days'));
$expiring_subscriptions = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM $table_name
WHERE status = 'active'
AND next_delivery_date <= %s
AND next_delivery_date > %s",
$seven_days_later,
current_time('Y-m-d')
));
foreach ($expiring_subscriptions as $subscription) {
$this->send_expiration_reminder($subscription);
}
}
/**
* 发送到期提醒
*/
private function send_expiration_reminder($subscription) {
$user = get_user_by('id', $subscription->user_id);
if (!$user) {
return;
}
$plan_name = get_the_title($subscription->plan_id);
$next_delivery = date_i18n(get_option('date_format'), strtotime($subscription->next_delivery_date));
$subject = sprintf(__('您的文创订阅即将配送 - %s', 'cultural-subscription'), $plan_name);
$message = sprintf(
__('亲爱的%s,<br><br>您的文创订阅"%s"将在%s进行下次配送。<br><br>如需修改配送内容或时间,请登录您的账户进行操作。<br><br>感谢您的订阅!', 'cultural-subscription'),
$user->display_name,
$plan_name,
$next_delivery
);
wp_mail($user->user_email, $subject, $message, array('Content-Type: text/html; charset=UTF-8'));
}
/**
* 更新订阅状态
*/
private function update_subscription_statuses() {
global $wpdb;
$table_name = $wpdb->prefix . 'cultural_subscriptions';
// 将过期的订阅标记为过期
$wpdb->query($wpdb->prepare(
"UPDATE $table_name
SET status = 'expired'
WHERE status = 'active'
AND next_delivery_date < %s",
current_time('Y-m-d')
));
}
/**
* 处理续订
*/
public function process_renewals() {
global $wpdb;
$table_name = $wpdb->prefix . 'cultural_subscriptions';
// 查找需要续订的订阅
$today = current_time('Y-m-d');
$renewal_subscriptions = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM $table_name
WHERE status = 'active'
AND next_delivery_date = %s",
$today
));
foreach ($renewal_subscriptions as $subscription) {
$this->process_single_renewal($subscription);
}
}
/**
* 处理单个续订
*/
private function process_single_renewal($subscription) {
// 创建新订单
$payment_data = $this->create_renewal_payment($subscription);
if ($payment_data) {
// 更新下次配送日期
$this->update_next_delivery_date($subscription->id);
// 发送续订确认
$this->send_renewal_confirmation($subscription);
} else {
// 支付失败,进入宽限期
$this->handle_payment_failure($subscription);
}
}
/**
