仰望星辰工作室

better-staridc-MNBT

better-staridc-MNBT/ wp_seller_plugin/includes/services/class-provision.php 5.2 KB · 160 行 原始文件
Z zfhsh first commit 2 天前
1<?php
2/**
3 * 开通编排:订单支付成功后创建主机(幂等 + 失败记录可重试)。
4 *
5 * @package MnbtWp
6 */
7
8namespace MnbtWp\Services;
9
10use MnbtWp\Crypto;
11use MnbtWp\Helpers;
12use MnbtWp\Mnbt\Exception as MnbtException;
13
14if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16}
17
18/**
19 * 开通服务。
20 */
21class Provision {
22
23 /**
24 * 根据订单开通主机。
25 *
26 * 幂等:订单已开通(_mnbtwp_provisioned)则直接返回。
27 * 失败:抛出异常并记录 _mnbtwp_provision_error,可后台重试。
28 *
29 * @param int $order_id 订单 ID。
30 * @return array ['ok'=>bool, 'msg'=>string, 'host_id'=>int]
31 *
32 * @throws \Exception 开通失败。
33 */
34 public static function provision_order( $order_id ) {
35 $order = wc_get_order( $order_id );
36 if ( ! $order ) {
37 throw new \Exception( __( '订单不存在', 'wp-seller-plugin' ) );
38 }
39
40 if ( get_post_meta( $order_id, '_mnbtwp_provisioned', true ) ) {
41 return array(
42 'ok' => true,
43 'msg' => __( '该订单已开通', 'wp-seller-plugin' ),
44 'host_id' => (int) get_post_meta( $order_id, '_mnbtwp_host_id', true ),
45 );
46 }
47
48 // 定位主机商品。
49 $product_id = 0;
50 foreach ( $order->get_items() as $item ) {
51 $pid = (int) $item->get_product_id();
52 if ( 'yes' === get_post_meta( $pid, '_mnbtwp_enabled', true ) ) {
53 $product_id = $pid;
54 break;
55 }
56 }
57 if ( ! $product_id ) {
58 throw new \Exception( __( '订单中无主机商品', 'wp-seller-plugin' ) );
59 }
60
61 $provider_id = (int) get_post_meta( $product_id, '_mnbtwp_provider_id', true );
62 $provider = Helpers::get_provider( $provider_id );
63 if ( ! $provider || 'true' !== $provider['qk'] ) {
64 throw new \Exception( __( '节点配置不可用', 'wp-seller-plugin' ) );
65 }
66
67 $user_id = (int) $order->get_user_id();
68 $username = Helpers::generate_username( $user_id );
69 $password = wp_generate_password( 12, true );
70
71 $months = max( 1, (int) get_post_meta( $product_id, '_mnbtwp_period_months', true ) ?: 12 );
72 $expire = date( 'Y-m-d', strtotime( "+{$months} months" ) );
73 $webdx = (int) get_post_meta( $product_id, '_mnbtwp_webdx', true );
74 $sqldx = (int) get_post_meta( $product_id, '_mnbtwp_sqldx', true );
75 $flow = (int) get_post_meta( $product_id, '_mnbtwp_ll', true );
76 $ymbds = (int) get_post_meta( $product_id, '_mnbtwp_ymbds', true );
77
78 $client = Helpers::client_for_provider( $provider );
79 try {
80 $client->createHost(
81 array(
82 'username' => $username,
83 'password' => $password,
84 'webdx' => $webdx,
85 'sqldx' => $sqldx,
86 'll' => $flow,
87 'ymbds' => $ymbds,
88 'dqtime' => $expire,
89 )
90 );
91 } catch ( MnbtException $e ) {
92 update_post_meta( $order_id, '_mnbtwp_provision_error', $e->getMessage() );
93 throw $e;
94 }
95
96 global $wpdb;
97 $quota = wp_json_encode(
98 array(
99 'web' => array( 'max' => $webdx, 'used' => 0 ),
100 'sql' => array( 'max' => $sqldx, 'used' => 0 ),
101 'flow' => array( 'max' => $flow, 'used' => 0 ),
102 )
103 );
104
105 $wpdb->insert(
106 $wpdb->prefix . 'mnbt_hosts',
107 array(
108 'provider_id' => $provider_id,
109 'order_id' => (int) $order_id,
110 'user_id' => $user_id,
111 'username' => $username,
112 'password_enc' => Crypto::encrypt( $password ),
113 'site_domain' => '',
114 'status' => 'active',
115 'expire_date' => $expire,
116 'quota_json' => $quota,
117 'created_at' => current_time( 'mysql' ),
118 'updated_at' => current_time( 'mysql' ),
119 ),
120 array( '%d', '%d', '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )
121 );
122 $host_id = (int) $wpdb->insert_id;
123
124 update_post_meta( $order_id, '_mnbtwp_provisioned', '1' );
125 update_post_meta( $order_id, '_mnbtwp_host_id', $host_id );
126 delete_post_meta( $order_id, '_mnbtwp_provision_error' );
127
128 self::notify( $user_id, $username, $password, $provider, $expire );
129
130 return array(
131 'ok' => true,
132 'msg' => __( '主机开通成功', 'wp-seller-plugin' ),
133 'host_id' => $host_id,
134 );
135 }
136
137 /**
138 * 发送开通通知邮件(含账号/密码/控制台地址)。
139 *
140 * @param int $user_id WP 用户 ID。
141 * @param string $username 主机用户名。
142 * @param string $password 明文密码。
143 * @param array $provider 节点行。
144 * @param string $expire 到期日期。
145 */
146 private static function notify( $user_id, $username, $password, array $provider, $expire ) {
147 $user = get_userdata( $user_id );
148 if ( ! $user || empty( $user->user_email ) ) {
149 return;
150 }
151 $subject = sprintf( __( '【%s】主机开通成功', 'wp-seller-plugin' ), get_bloginfo( 'name' ) );
152 $body = '<p>' . esc_html__( '您购买的虚拟主机已开通:', 'wp-seller-plugin' ) . '</p>'
153 . '<p>主机账号:<code>' . esc_html( $username ) . '</code></p>'
154 . '<p>主机密码:<code>' . esc_html( $password ) . '</code></p>'
155 . '<p>' . esc_html__( '到期时间:', 'wp-seller-plugin' ) . esc_html( $expire ) . '</p>'
156 . '<p>' . esc_html__( '控制台:', 'wp-seller-plugin' ) . '<a href="' . esc_url( Helpers::control_url( $provider ) ) . '">' . esc_html( Helpers::control_url( $provider ) ) . '</a></p>'
157 . '<p style="color:#888;">' . esc_html__( '请妥善保管账号密码,可在「我的主机」中随时重置密码。', 'wp-seller-plugin' ) . '</p>';
158 Helpers::send_mail( $user->user_email, $subject, $body );
159 }
160}