feat: initial WooAApanel plugin
Full WooCommerce plugin for aaPanel hosting management: - aaPanel API client (all website + database endpoints) - Admin: server management, site/DB assignments, full site/DB management panels - Customer My Account: web hosting tab with sites and databases - WooDomains PowerDNS integration for DNS management - WooCommerce order auto-provisioning (product → server linking) - Permission model: admin has all actions, customers have scoped access Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
124
includes/class-wooaapanel-orders.php
Normal file
124
includes/class-wooaapanel-orders.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* WooAApanel Orders – auto-provision sites and databases when a WooCommerce
|
||||
* order is completed for a product linked to an aaPanel server.
|
||||
*
|
||||
* Product meta:
|
||||
* _wooaapanel_server_id (int) – which server to provision on
|
||||
*/
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
class WooAApanel_Orders {
|
||||
|
||||
public function __construct() {
|
||||
add_action( 'woocommerce_order_status_completed', [ $this, 'provision_on_complete' ], 10, 1 );
|
||||
}
|
||||
|
||||
public function provision_on_complete( int $order_id ): void {
|
||||
$order = wc_get_order( $order_id );
|
||||
if ( ! $order ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$customer_id = $order->get_customer_id();
|
||||
if ( ! $customer_id ) {
|
||||
return; // guest orders – skip
|
||||
}
|
||||
|
||||
foreach ( $order->get_items() as $item ) {
|
||||
$product_id = $item->get_product_id();
|
||||
$server_id = (int) get_post_meta( $product_id, '_wooaapanel_server_id', true );
|
||||
|
||||
if ( ! $server_id ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Avoid double-provisioning if order is re-completed.
|
||||
$provisioned_key = "_wooaapanel_provisioned_{$product_id}";
|
||||
if ( $order->get_meta( $provisioned_key ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$server = $wpdb->get_row( $wpdb->prepare(
|
||||
"SELECT * FROM {$wpdb->prefix}wooaapanel_servers WHERE id = %d AND active = 1",
|
||||
$server_id
|
||||
) );
|
||||
|
||||
if ( ! $server ) {
|
||||
$order->add_order_note( sprintf(
|
||||
__( 'WooAApanel: server #%d not found or inactive – skipping provisioning for product #%d.', 'wooaapanel' ),
|
||||
$server_id,
|
||||
$product_id
|
||||
) );
|
||||
continue;
|
||||
}
|
||||
|
||||
$user = get_user_by( 'id', $customer_id );
|
||||
$username = $user ? sanitize_user( $user->user_login, true ) : 'user' . $customer_id;
|
||||
// Sanitise to aaPanel-safe names (alphanumeric + underscore, max 16 chars).
|
||||
$safe_name = preg_replace( '/[^a-z0-9_]/', '', strtolower( $username ) );
|
||||
$safe_name = substr( $safe_name ?: 'user', 0, 12 );
|
||||
$suffix = substr( md5( $order_id . $product_id ), 0, 4 );
|
||||
$site_name = $safe_name . '_' . $suffix;
|
||||
$db_name = $safe_name . '_' . $suffix;
|
||||
$db_user = $safe_name . '_' . $suffix;
|
||||
$db_pass = wp_generate_password( 16, false );
|
||||
|
||||
$api = WooAApanel_API::from_server( $server );
|
||||
|
||||
// Create site.
|
||||
$site_res = $api->add_site( [
|
||||
'webname' => $site_name,
|
||||
'path' => "/www/wwwroot/{$site_name}",
|
||||
'type_id' => 0,
|
||||
'version' => '',
|
||||
'port' => 80,
|
||||
'ps' => "WooCommerce order #{$order_id}",
|
||||
'ftp_username' => '',
|
||||
'ftp_password' => '',
|
||||
'sql' => 'MySQL',
|
||||
'codeing' => 'utf8mb4',
|
||||
'datauser' => $db_user,
|
||||
'datapassword' => $db_pass,
|
||||
] );
|
||||
|
||||
$site_ok = ! empty( $site_res['data']['siteStatus'] ) || ( $site_res['success'] ?? false );
|
||||
|
||||
if ( $site_ok ) {
|
||||
// Record site assignment.
|
||||
$wpdb->insert( "{$wpdb->prefix}wooaapanel_site_assignments", [
|
||||
'customer_id' => $customer_id,
|
||||
'server_id' => $server_id,
|
||||
'site_name' => $site_name,
|
||||
'domain' => '',
|
||||
] );
|
||||
|
||||
// Record DB assignment.
|
||||
$wpdb->insert( "{$wpdb->prefix}wooaapanel_db_assignments", [
|
||||
'customer_id' => $customer_id,
|
||||
'server_id' => $server_id,
|
||||
'db_name' => $db_name,
|
||||
] );
|
||||
|
||||
$order->update_meta_data( $provisioned_key, '1' );
|
||||
$order->add_order_note( sprintf(
|
||||
__( 'WooAApanel: provisioned site "%s" and database "%s" on server "%s".', 'wooaapanel' ),
|
||||
$site_name,
|
||||
$db_name,
|
||||
$server->name
|
||||
) );
|
||||
} else {
|
||||
$error = $site_res['error'] ?? wp_json_encode( $site_res['data'] ?? [] );
|
||||
$order->add_order_note( sprintf(
|
||||
__( 'WooAApanel: provisioning failed for product #%d on server "%s": %s', 'wooaapanel' ),
|
||||
$product_id,
|
||||
$server->name,
|
||||
$error
|
||||
) );
|
||||
}
|
||||
|
||||
$order->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user