Files
WooAApanel/includes/class-wooaapanel-admin.php
Malin 8bb96b9048 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>
2026-03-06 12:48:06 +01:00

746 lines
34 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* WooAApanel Admin menu pages and AJAX handlers.
*/
defined( 'ABSPATH' ) || exit;
class WooAApanel_Admin {
public function __construct() {
add_action( 'admin_menu', [ $this, 'register_menu' ] );
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
$actions = [
// Servers
'wooaapanel_servers_list',
'wooaapanel_server_save',
'wooaapanel_server_delete',
'wooaapanel_server_test',
// Site assignments
'wooaapanel_site_assignments_list',
'wooaapanel_site_assignment_save',
'wooaapanel_site_assignment_delete',
// DB assignments
'wooaapanel_db_assignments_list',
'wooaapanel_db_assignment_save',
'wooaapanel_db_assignment_delete',
// Customer search
'wooaapanel_customers_search',
// Remote site list
'wooaapanel_remote_sites',
'wooaapanel_remote_dbs',
// === Admin site actions ===
'wooaapanel_admin_site_list',
'wooaapanel_admin_site_add',
'wooaapanel_admin_site_delete',
'wooaapanel_admin_site_domains',
'wooaapanel_admin_site_add_domain',
'wooaapanel_admin_site_del_domain',
'wooaapanel_admin_site_xss_get',
'wooaapanel_admin_site_xss_set',
'wooaapanel_admin_site_php_get',
'wooaapanel_admin_site_php_versions',
'wooaapanel_admin_site_php_set',
'wooaapanel_admin_site_rewrite_list',
'wooaapanel_admin_site_rewrite_get',
'wooaapanel_admin_site_rewrite_set',
'wooaapanel_admin_site_ssl_get',
'wooaapanel_admin_site_ssl_close',
'wooaapanel_admin_site_ssl_upload',
'wooaapanel_admin_site_ssl_deploy',
'wooaapanel_admin_site_ssl_list',
'wooaapanel_admin_site_run_path',
// === Admin DB actions ===
'wooaapanel_admin_db_list',
'wooaapanel_admin_db_add',
'wooaapanel_admin_db_delete',
'wooaapanel_admin_db_backup',
'wooaapanel_admin_db_backups',
'wooaapanel_admin_db_backup_delete',
'wooaapanel_admin_db_optimize',
'wooaapanel_admin_db_repair',
'wooaapanel_admin_db_access_get',
'wooaapanel_admin_db_access_set',
'wooaapanel_admin_db_password',
'wooaapanel_admin_db_recycle',
'wooaapanel_admin_db_restore',
'wooaapanel_admin_db_sync',
'wooaapanel_admin_db_quota',
// WC product settings
'wooaapanel_products_list',
'wooaapanel_product_server_save',
];
foreach ( $actions as $action ) {
add_action( 'wp_ajax_' . $action, [ $this, 'ajax_' . $action ] );
}
}
// ── Menu ─────────────────────────────────────────────────────────────────
public function register_menu(): void {
add_menu_page(
'WooAApanel',
'WooAApanel',
'manage_woocommerce',
'wooaapanel',
[ $this, 'page_dashboard' ],
'dashicons-admin-site-alt3',
57
);
add_submenu_page( 'wooaapanel', 'Dashboard', 'Dashboard', 'manage_woocommerce', 'wooaapanel', [ $this, 'page_dashboard' ] );
add_submenu_page( 'wooaapanel', 'Servers', 'Servers', 'manage_woocommerce', 'wooaapanel-servers', [ $this, 'page_servers' ] );
add_submenu_page( 'wooaapanel', 'Site Assignments', 'Site Assignments', 'manage_woocommerce', 'wooaapanel-site-assignments',[ $this, 'page_site_assignments' ] );
add_submenu_page( 'wooaapanel', 'DB Assignments', 'DB Assignments', 'manage_woocommerce', 'wooaapanel-db-assignments', [ $this, 'page_db_assignments' ] );
add_submenu_page( 'wooaapanel', 'Sites', 'Sites', 'manage_woocommerce', 'wooaapanel-sites', [ $this, 'page_sites' ] );
add_submenu_page( 'wooaapanel', 'Databases', 'Databases', 'manage_woocommerce', 'wooaapanel-databases', [ $this, 'page_databases' ] );
add_submenu_page( 'wooaapanel', 'WC Products', 'WC Products', 'manage_woocommerce', 'wooaapanel-products', [ $this, 'page_products' ] );
}
public function enqueue_assets( string $hook ): void {
if ( strpos( $hook, 'wooaapanel' ) === false ) {
return;
}
wp_enqueue_style( 'wooaapanel-admin', WOOAAPANEL_PLUGIN_URL . 'assets/css/wooaapanel-admin.css', [], WOOAAPANEL_VERSION );
wp_enqueue_script( 'wooaapanel-admin', WOOAAPANEL_PLUGIN_URL . 'assets/js/wooaapanel-admin.js', [ 'jquery' ], WOOAAPANEL_VERSION, true );
wp_localize_script( 'wooaapanel-admin', 'wooaapanel', [
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'wooaapanel_admin' ),
] );
}
// ── Pages ────────────────────────────────────────────────────────────────
public function page_dashboard(): void {
echo '<div class="wrap"><h1>WooAApanel</h1>';
echo '<p>' . esc_html__( 'Manage aaPanel servers, site and database assignments for your WooCommerce customers.', 'wooaapanel' ) . '</p>';
echo '<ul>';
$pages = [
'wooaapanel-servers' => 'Servers',
'wooaapanel-site-assignments' => 'Site Assignments',
'wooaapanel-db-assignments' => 'DB Assignments',
'wooaapanel-sites' => 'Sites',
'wooaapanel-databases' => 'Databases',
'wooaapanel-products' => 'WC Product Linking',
];
foreach ( $pages as $slug => $label ) {
printf( '<li><a href="%s">%s</a></li>', esc_url( admin_url( 'admin.php?page=' . $slug ) ), esc_html( $label ) );
}
echo '</ul></div>';
}
public function page_servers(): void {
echo '<div class="wrap wooaapanel-page" id="wooaapanel-servers-page"><h1>' . esc_html__( 'aaPanel Servers', 'wooaapanel' ) . '</h1>';
echo '<div id="wap-servers-wrap"></div></div>';
}
public function page_site_assignments(): void {
echo '<div class="wrap wooaapanel-page" id="wooaapanel-site-assignments-page"><h1>' . esc_html__( 'Site Assignments', 'wooaapanel' ) . '</h1>';
echo '<div id="wap-site-assignments-wrap"></div></div>';
}
public function page_db_assignments(): void {
echo '<div class="wrap wooaapanel-page" id="wooaapanel-db-assignments-page"><h1>' . esc_html__( 'Database Assignments', 'wooaapanel' ) . '</h1>';
echo '<div id="wap-db-assignments-wrap"></div></div>';
}
public function page_sites(): void {
echo '<div class="wrap wooaapanel-page" id="wooaapanel-sites-page"><h1>' . esc_html__( 'Sites', 'wooaapanel' ) . '</h1>';
echo '<div id="wap-sites-wrap"></div></div>';
}
public function page_databases(): void {
echo '<div class="wrap wooaapanel-page" id="wooaapanel-databases-page"><h1>' . esc_html__( 'Databases', 'wooaapanel' ) . '</h1>';
echo '<div id="wap-databases-wrap"></div></div>';
}
public function page_products(): void {
echo '<div class="wrap wooaapanel-page" id="wooaapanel-products-page"><h1>' . esc_html__( 'WC Product ↔ Server Linking', 'wooaapanel' ) . '</h1>';
echo '<p>' . esc_html__( 'Link a WooCommerce product to an aaPanel server. When a customer purchases the product, a site and database will be automatically provisioned on the linked server.', 'wooaapanel' ) . '</p>';
echo '<div id="wap-products-wrap"></div></div>';
}
// ── Helpers ───────────────────────────────────────────────────────────────
private function verify_admin(): void {
check_ajax_referer( 'wooaapanel_admin', 'nonce' );
if ( ! current_user_can( 'manage_woocommerce' ) ) {
wp_send_json_error( 'Insufficient permissions.', 403 );
}
}
private function get_server( int $id ): ?object {
global $wpdb;
return $wpdb->get_row( $wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}wooaapanel_servers WHERE id = %d",
$id
) );
}
private function api( int $server_id ): WooAApanel_API {
$server = $this->get_server( $server_id );
if ( ! $server ) {
wp_send_json_error( 'Server not found.', 404 );
}
return WooAApanel_API::from_server( $server );
}
// ═════════════════════════════════════════════════════════════════════════
// AJAX: Servers
// ═════════════════════════════════════════════════════════════════════════
public function ajax_wooaapanel_servers_list(): void {
$this->verify_admin();
global $wpdb;
$rows = $wpdb->get_results( "SELECT id, name, url, active, created_at FROM {$wpdb->prefix}wooaapanel_servers ORDER BY id DESC" );
wp_send_json_success( $rows );
}
public function ajax_wooaapanel_server_save(): void {
$this->verify_admin();
$id = absint( $_POST['id'] ?? 0 );
$name = sanitize_text_field( $_POST['name'] ?? '' );
$url = esc_url_raw( $_POST['url'] ?? '' );
$api_key = sanitize_text_field( $_POST['api_key'] ?? '' );
$active = absint( $_POST['active'] ?? 1 );
if ( ! $name || ! $url || ! $api_key ) {
wp_send_json_error( 'Name, URL and API key are required.' );
}
global $wpdb;
$data = compact( 'name', 'url', 'api_key', 'active' );
if ( $id ) {
$wpdb->update( "{$wpdb->prefix}wooaapanel_servers", $data, [ 'id' => $id ] );
} else {
$wpdb->insert( "{$wpdb->prefix}wooaapanel_servers", $data );
$id = $wpdb->insert_id;
}
wp_send_json_success( [ 'id' => $id ] );
}
public function ajax_wooaapanel_server_delete(): void {
$this->verify_admin();
$id = absint( $_POST['id'] ?? 0 );
global $wpdb;
$wpdb->delete( "{$wpdb->prefix}wooaapanel_servers", [ 'id' => $id ] );
wp_send_json_success();
}
public function ajax_wooaapanel_server_test(): void {
$this->verify_admin();
$id = absint( $_POST['id'] ?? 0 );
$api = $this->api( $id );
$res = $api->test_connection();
wp_send_json( $res );
}
// ── Remote site/db lists (used by assignment UI) ──────────────────────
public function ajax_wooaapanel_remote_sites(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$api = $this->api( $server_id );
$res = $api->get_sites( 1, 200 );
wp_send_json( $res );
}
public function ajax_wooaapanel_remote_dbs(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$api = $this->api( $server_id );
$res = $api->get_databases( 1, 200 );
wp_send_json( $res );
}
// ═════════════════════════════════════════════════════════════════════════
// AJAX: Site Assignments
// ═════════════════════════════════════════════════════════════════════════
public function ajax_wooaapanel_site_assignments_list(): void {
$this->verify_admin();
global $wpdb;
$rows = $wpdb->get_results( "
SELECT a.id, a.customer_id, a.server_id, a.site_name, a.domain, a.created_at,
s.name AS server_name,
u.display_name AS customer_name, u.user_email AS customer_email
FROM {$wpdb->prefix}wooaapanel_site_assignments a
JOIN {$wpdb->prefix}wooaapanel_servers s ON s.id = a.server_id
LEFT JOIN {$wpdb->users} u ON u.ID = a.customer_id
ORDER BY a.id DESC
" );
wp_send_json_success( $rows );
}
public function ajax_wooaapanel_site_assignment_save(): void {
$this->verify_admin();
$id = absint( $_POST['id'] ?? 0 );
$customer_id = absint( $_POST['customer_id'] ?? 0 );
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$domain = sanitize_text_field( $_POST['domain'] ?? '' );
if ( ! $customer_id || ! $server_id || ! $site_name ) {
wp_send_json_error( 'Customer, server and site name are required.' );
}
global $wpdb;
$data = compact( 'customer_id', 'server_id', 'site_name', 'domain' );
if ( $id ) {
$wpdb->update( "{$wpdb->prefix}wooaapanel_site_assignments", $data, [ 'id' => $id ] );
} else {
$wpdb->insert( "{$wpdb->prefix}wooaapanel_site_assignments", $data );
$id = $wpdb->insert_id;
}
wp_send_json_success( [ 'id' => $id ] );
}
public function ajax_wooaapanel_site_assignment_delete(): void {
$this->verify_admin();
$id = absint( $_POST['id'] ?? 0 );
global $wpdb;
$wpdb->delete( "{$wpdb->prefix}wooaapanel_site_assignments", [ 'id' => $id ] );
wp_send_json_success();
}
// ═════════════════════════════════════════════════════════════════════════
// AJAX: DB Assignments
// ═════════════════════════════════════════════════════════════════════════
public function ajax_wooaapanel_db_assignments_list(): void {
$this->verify_admin();
global $wpdb;
$rows = $wpdb->get_results( "
SELECT a.id, a.customer_id, a.server_id, a.db_name, a.created_at,
s.name AS server_name,
u.display_name AS customer_name, u.user_email AS customer_email
FROM {$wpdb->prefix}wooaapanel_db_assignments a
JOIN {$wpdb->prefix}wooaapanel_servers s ON s.id = a.server_id
LEFT JOIN {$wpdb->users} u ON u.ID = a.customer_id
ORDER BY a.id DESC
" );
wp_send_json_success( $rows );
}
public function ajax_wooaapanel_db_assignment_save(): void {
$this->verify_admin();
$id = absint( $_POST['id'] ?? 0 );
$customer_id = absint( $_POST['customer_id'] ?? 0 );
$server_id = absint( $_POST['server_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
if ( ! $customer_id || ! $server_id || ! $db_name ) {
wp_send_json_error( 'Customer, server and database name are required.' );
}
global $wpdb;
$data = compact( 'customer_id', 'server_id', 'db_name' );
if ( $id ) {
$wpdb->update( "{$wpdb->prefix}wooaapanel_db_assignments", $data, [ 'id' => $id ] );
} else {
$wpdb->insert( "{$wpdb->prefix}wooaapanel_db_assignments", $data );
$id = $wpdb->insert_id;
}
wp_send_json_success( [ 'id' => $id ] );
}
public function ajax_wooaapanel_db_assignment_delete(): void {
$this->verify_admin();
$id = absint( $_POST['id'] ?? 0 );
global $wpdb;
$wpdb->delete( "{$wpdb->prefix}wooaapanel_db_assignments", [ 'id' => $id ] );
wp_send_json_success();
}
// ═════════════════════════════════════════════════════════════════════════
// AJAX: Customer search
// ═════════════════════════════════════════════════════════════════════════
public function ajax_wooaapanel_customers_search(): void {
$this->verify_admin();
$q = sanitize_text_field( $_POST['q'] ?? '' );
$users = get_users( [
'role__in' => [ 'customer', 'subscriber', 'administrator' ],
'search' => '*' . $q . '*',
'number' => 20,
'fields' => [ 'ID', 'display_name', 'user_email' ],
] );
wp_send_json_success( array_map( fn( $u ) => [
'id' => $u->ID,
'label' => $u->display_name . ' <' . $u->user_email . '>',
], $users ) );
}
// ═════════════════════════════════════════════════════════════════════════
// AJAX: Admin site actions (ALL operations)
// ═════════════════════════════════════════════════════════════════════════
public function ajax_wooaapanel_admin_site_list(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$search = sanitize_text_field( $_POST['search'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->get_sites( 1, 100, $search ) );
}
public function ajax_wooaapanel_admin_site_add(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$api = $this->api( $server_id );
$data = [
'webname' => sanitize_text_field( $_POST['webname'] ?? '' ),
'path' => sanitize_text_field( $_POST['path'] ?? '' ),
'type_id' => absint( $_POST['type_id'] ?? 0 ),
'version' => sanitize_text_field( $_POST['version'] ?? '' ),
'port' => absint( $_POST['port'] ?? 80 ),
'ps' => sanitize_text_field( $_POST['ps'] ?? '' ),
'ftp_username' => sanitize_text_field( $_POST['ftp_username'] ?? '' ),
'ftp_password' => sanitize_text_field( $_POST['ftp_password'] ?? '' ),
'sql' => sanitize_text_field( $_POST['sql'] ?? '' ),
'codeing' => sanitize_text_field( $_POST['codeing'] ?? 'utf8mb4' ),
'datauser' => sanitize_text_field( $_POST['datauser'] ?? '' ),
'datapassword' => sanitize_text_field( $_POST['datapassword'] ?? '' ),
];
wp_send_json( $api->add_site( $data ) );
}
public function ajax_wooaapanel_admin_site_delete(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$ftp = ! empty( $_POST['ftp'] );
$database = ! empty( $_POST['database'] );
$path = ! empty( $_POST['path'] );
$api = $this->api( $server_id );
wp_send_json( $api->delete_site( $site_name, $ftp, $database, $path ) );
}
public function ajax_wooaapanel_admin_site_domains(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->get_site_domains( $site_name ) );
}
public function ajax_wooaapanel_admin_site_add_domain(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$domain = sanitize_text_field( $_POST['domain'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->add_domain( $site_name, $domain ) );
}
public function ajax_wooaapanel_admin_site_del_domain(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$domain = sanitize_text_field( $_POST['domain'] ?? '' );
$site_id = absint( $_POST['site_id'] ?? 0 );
$api = $this->api( $server_id );
wp_send_json( $api->delete_domain( $site_name, $domain, $site_id ) );
}
public function ajax_wooaapanel_admin_site_xss_get(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$site_path = sanitize_text_field( $_POST['site_path'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->get_xss( $site_name, $site_path ) );
}
public function ajax_wooaapanel_admin_site_xss_set(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$site_path = sanitize_text_field( $_POST['site_path'] ?? '' );
$enable = ! empty( $_POST['enable'] );
$api = $this->api( $server_id );
wp_send_json( $api->set_xss( $site_name, $site_path, $enable ) );
}
public function ajax_wooaapanel_admin_site_php_get(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->get_site_php_version( $site_name ) );
}
public function ajax_wooaapanel_admin_site_php_versions(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$api = $this->api( $server_id );
wp_send_json( $api->get_php_versions() );
}
public function ajax_wooaapanel_admin_site_php_set(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$version = sanitize_text_field( $_POST['version'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->set_site_php_version( $site_name, $version ) );
}
public function ajax_wooaapanel_admin_site_rewrite_list(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->get_rewrite_list( $site_name ) );
}
public function ajax_wooaapanel_admin_site_rewrite_get(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$template = sanitize_text_field( $_POST['template'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->get_rewrite_content( $site_name, $template ) );
}
public function ajax_wooaapanel_admin_site_rewrite_set(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$content = wp_unslash( $_POST['content'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->set_rewrite( $site_name, $content ) );
}
public function ajax_wooaapanel_admin_site_ssl_get(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->get_ssl( $site_name ) );
}
public function ajax_wooaapanel_admin_site_ssl_close(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->close_ssl( $site_name ) );
}
public function ajax_wooaapanel_admin_site_ssl_list(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$api = $this->api( $server_id );
wp_send_json( $api->list_ssl_certs() );
}
public function ajax_wooaapanel_admin_site_ssl_upload(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$key = wp_unslash( $_POST['key'] ?? '' );
$cert = wp_unslash( $_POST['cert'] ?? '' );
$domain = sanitize_text_field( $_POST['domain'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->upload_cert( $key, $cert, $domain ) );
}
public function ajax_wooaapanel_admin_site_ssl_deploy(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$cert_id = absint( $_POST['cert_id'] ?? 0 );
$api = $this->api( $server_id );
wp_send_json( $api->deploy_cert_to_site( $site_name, $cert_id ) );
}
public function ajax_wooaapanel_admin_site_run_path(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$site_name = sanitize_text_field( $_POST['site_name'] ?? '' );
$run_path = sanitize_text_field( $_POST['run_path'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->set_run_path( $site_name, $run_path ) );
}
// ═════════════════════════════════════════════════════════════════════════
// AJAX: Admin DB actions (ALL operations)
// ═════════════════════════════════════════════════════════════════════════
public function ajax_wooaapanel_admin_db_list(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$search = sanitize_text_field( $_POST['search'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->get_databases( 1, 100, $search ) );
}
public function ajax_wooaapanel_admin_db_add(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
$db_user = sanitize_text_field( $_POST['db_user'] ?? '' );
$password = sanitize_text_field( $_POST['password'] ?? '' );
$codeing = sanitize_text_field( $_POST['codeing'] ?? 'utf8mb4' );
$api = $this->api( $server_id );
wp_send_json( $api->add_database( $db_name, $db_user, $password, $codeing ) );
}
public function ajax_wooaapanel_admin_db_delete(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->delete_database( $db_name ) );
}
public function ajax_wooaapanel_admin_db_backup(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->backup_database( $db_name ) );
}
public function ajax_wooaapanel_admin_db_backups(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->get_db_backups( $db_name ) );
}
public function ajax_wooaapanel_admin_db_backup_delete(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$backup_id = absint( $_POST['backup_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->delete_db_backup( $backup_id, $db_name ) );
}
public function ajax_wooaapanel_admin_db_optimize(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->optimize_table( $db_name ) );
}
public function ajax_wooaapanel_admin_db_repair(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->repair_table( $db_name ) );
}
public function ajax_wooaapanel_admin_db_access_get(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->get_db_access( $db_name ) );
}
public function ajax_wooaapanel_admin_db_access_set(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
$access = sanitize_text_field( $_POST['access'] ?? '%' );
$api = $this->api( $server_id );
wp_send_json( $api->set_db_access( $db_name, $access ) );
}
public function ajax_wooaapanel_admin_db_password(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
$db_user = sanitize_text_field( $_POST['db_user'] ?? '' );
$password = sanitize_text_field( $_POST['password'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->reset_db_password( $db_name, $db_user, $password ) );
}
public function ajax_wooaapanel_admin_db_recycle(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$api = $this->api( $server_id );
wp_send_json( $api->get_recycle_bin() );
}
public function ajax_wooaapanel_admin_db_restore(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$path = sanitize_text_field( $_POST['path'] ?? '' );
$api = $this->api( $server_id );
wp_send_json( $api->restore_from_recycle( $path ) );
}
public function ajax_wooaapanel_admin_db_sync(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$api = $this->api( $server_id );
wp_send_json( $api->sync_to_databases() );
}
public function ajax_wooaapanel_admin_db_quota(): void {
$this->verify_admin();
$server_id = absint( $_POST['server_id'] ?? 0 );
$db_name = sanitize_text_field( $_POST['db_name'] ?? '' );
$quota_mb = absint( $_POST['quota_mb'] ?? 0 );
$api = $this->api( $server_id );
wp_send_json( $api->modify_db_quota( $db_name, $quota_mb ) );
}
// ═════════════════════════════════════════════════════════════════════════
// AJAX: WC Product server linking
// ═════════════════════════════════════════════════════════════════════════
public function ajax_wooaapanel_products_list(): void {
$this->verify_admin();
$products = wc_get_products( [ 'limit' => 200, 'status' => 'publish' ] );
$servers = $this->get_all_servers();
$rows = [];
foreach ( $products as $product ) {
$rows[] = [
'id' => $product->get_id(),
'name' => $product->get_name(),
'server_id' => (int) get_post_meta( $product->get_id(), '_wooaapanel_server_id', true ),
];
}
wp_send_json_success( [
'products' => $rows,
'servers' => $servers,
] );
}
public function ajax_wooaapanel_product_server_save(): void {
$this->verify_admin();
$product_id = absint( $_POST['product_id'] ?? 0 );
$server_id = absint( $_POST['server_id'] ?? 0 );
update_post_meta( $product_id, '_wooaapanel_server_id', $server_id );
wp_send_json_success();
}
// ── Internal helpers ──────────────────────────────────────────────────
private function get_all_servers(): array {
global $wpdb;
return $wpdb->get_results( "SELECT id, name FROM {$wpdb->prefix}wooaapanel_servers WHERE active = 1 ORDER BY name" );
}
}