__('订阅计划', 'yoone-subscriptions'), 'target' => 'yoone_subscriptions_data', 'class' => array('show_if_simple', 'show_if_variable'), 'priority' => 80, ); return $tabs; } /** * 渲染面板内容 */ public function render_panel() { global $post; $product = wc_get_product($post->ID); $cfg = Yoone_Subscriptions::get_config($product); wp_nonce_field('yoone_subscriptions_save', 'yoone_subscriptions_nonce'); echo '
'; } /** * 保存订阅配置 */ public function save_meta($post_id) { if (! isset($_POST['yoone_subscriptions_nonce']) || ! wp_verify_nonce($_POST['yoone_subscriptions_nonce'], 'yoone_subscriptions_save')) { return; // 安全验证失败 } if (! current_user_can('edit_post', $post_id)) return; $enabled = isset($_POST['yoone_sub_enabled']) && 'yes' === $_POST['yoone_sub_enabled']; $period = isset($_POST['yoone_sub_period']) ? sanitize_text_field($_POST['yoone_sub_period']) : 'month'; $qty = isset($_POST['yoone_sub_qty_default']) ? absint($_POST['yoone_sub_qty_default']) : 1; $min_qty = isset($_POST['yoone_sub_min_qty']) ? absint($_POST['yoone_sub_min_qty']) : 1; $price = isset($_POST['yoone_sub_price']) ? wc_clean($_POST['yoone_sub_price']) : ''; $tiers = isset($_POST['yoone_sub_tier_rules']) ? sanitize_text_field($_POST['yoone_sub_tier_rules']) : ''; $onetime = isset($_POST['yoone_sub_allow_onetime']) && 'yes' === $_POST['yoone_sub_allow_onetime']; $period = in_array($period, array('month','year'), true) ? $period : 'month'; $qty = max(1, $qty); $price_v = ($price === '' ? '' : wc_format_decimal($price, 2)); update_post_meta($post_id, Yoone_Subscriptions::META_ENABLED, $enabled ? '1' : ''); update_post_meta($post_id, Yoone_Subscriptions::META_PERIOD, $period); update_post_meta($post_id, Yoone_Subscriptions::META_QTY_DEFAULT, $qty); update_post_meta($post_id, Yoone_Subscriptions::META_MIN_QTY, max(1, $min_qty)); if ($price_v === '') { delete_post_meta($post_id, Yoone_Subscriptions::META_PRICE); } else { update_post_meta($post_id, Yoone_Subscriptions::META_PRICE, $price_v); } if ($tiers === '') { delete_post_meta($post_id, Yoone_Subscriptions::META_TIER_RULES); } else { update_post_meta($post_id, Yoone_Subscriptions::META_TIER_RULES, $tiers); } update_post_meta($post_id, Yoone_Subscriptions::META_ALLOW_ONETIME, $onetime ? '1' : ''); } /** * 注册 WooCommerce → Subscriptions 子菜单。 */ public function register_submenu() { // 仅限具有管理 WooCommerce 权限的用户可访问 add_submenu_page( 'woocommerce', __('Subscriptions', 'yoone-subscriptions'), __('Subscriptions', 'yoone-subscriptions'), 'manage_woocommerce', 'yoone-subscriptions', array($this, 'render_subscriptions_page'), 56 // 显示位置(可选) ); } /** * 渲染订阅列表管理页面。 * 支持按用户、产品、状态筛选与分页。 */ public function render_subscriptions_page() { if (! current_user_can('manage_woocommerce')) { wp_die(__('您没有权限查看该页面。', 'yoone-subscriptions')); } // 处理状态更新操作(pause/resume/cancel),带 nonce if (isset($_POST['yoone_sub_action']) && isset($_POST['_wpnonce']) && wp_verify_nonce($_POST['_wpnonce'], 'yoone_subscriptions_action')) { $action = sanitize_key($_POST['yoone_sub_action']); $sub_id = isset($_POST['yoone_sub_id']) ? absint($_POST['yoone_sub_id']) : 0; $allowed = array('pause' => 'paused', 'resume' => 'active', 'cancel' => 'canceled'); if ($sub_id > 0 && isset($allowed[$action])) { if (class_exists('Yoone_Subscriptions_DB')) { Yoone_Subscriptions_DB::update($sub_id, array('status' => $allowed[$action])); echo '' . esc_html__('状态已更新。', 'yoone-subscriptions') . '
| ' . esc_html($c) . ' | '; echo '|||||||||
|---|---|---|---|---|---|---|---|---|---|
| ' . esc_html__('暂无订阅记录。', 'yoone-subscriptions') . ' | |||||||||
| #' . intval($r['id']) . ' | '; echo '' . ($user ? esc_html($user->user_email) . ' (ID ' . intval($user->ID) . ')' : '-') . ' | '; echo '' . ($product ? esc_html($product->get_name()) . ' (ID ' . intval($product->get_id()) . ')' : 'ID ' . intval($r['product_id'])) . ' | '; echo '' . esc_html($r['period']) . ' | '; echo '' . intval($r['qty']) . ' | '; echo '' . wc_price(floatval($r['price_per_cycle'])) . ' | '; echo '' . esc_html($r['status']) . ' | '; echo '' . esc_html($r['start_date']) . ' | '; echo '' . esc_html($r['next_renewal_date']) . ' | '; echo ''; echo ''; echo ''; echo ''; echo ' | '; echo '