File: /wordpress/plugins/wp-cloud-client/1.1.6/src/Handler/NetworkInstallHandler.php
<?php
declare(strict_types=1);
namespace VPlugins\WPCloudClient\Handler;
use VPlugins\WPCloudClient\Support\Logger;
/**
* Installs a WordPress multisite network.
*
* WP_ALLOW_MULTISITE must already be defined and true in wp-config.php
* before this action is called. After a successful response, the caller
* is responsible for writing the remaining multisite constants
* (MULTISITE, SUBDOMAIN_INSTALL, DOMAIN_CURRENT_SITE, etc.) to wp-config.php.
*
* See: https://github.com/vendasta/wsp-bootstrapper/blob/master/src/add-ons/api/wsp-network-install.php
* Mirrored contract: email + optional domain/site_name in → installed bool + domain out.
*/
final class NetworkInstallHandler extends AbstractHandler {
/**
* Class constructor.
*
* @param Logger $logger Logger instance.
*/
public function __construct( private readonly Logger $logger ) {}
/**
* Return the action name.
*
* @return string Action name.
*/
public function action(): string {
return 'network_install';
}
/**
* Install the WordPress multisite network.
*
* Requires WP_ALLOW_MULTISITE to be defined and true in wp-config.php.
*
* @param array{email: string, domain?: string, site_name?: string} $params Action parameters.
* @return array{installed: bool, domain: string, message?: string} Install result.
*
* @throws \InvalidArgumentException If email is missing or invalid, or domain resolves to empty.
* @throws \RuntimeException If WP_ALLOW_MULTISITE is off, a network is already installed
* on a different domain, admin user cannot be created,
* or populate_network() fails.
*/
public function execute( array $params ): array {
$this->requireParams( $params, 'email' );
if ( ! \defined( 'WP_ALLOW_MULTISITE' ) || ! \WP_ALLOW_MULTISITE ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound
throw new \RuntimeException( 'Multisite is not enabled. Set WP_ALLOW_MULTISITE to true in wp-config.php.' );
}
if ( ! \function_exists( 'install_network' ) ) {
require_once \ABSPATH . 'wp-admin/includes/network.php';
}
if ( ! \function_exists( 'dbDelta' ) ) {
require_once \ABSPATH . 'wp-admin/includes/upgrade.php';
}
// wpmu_create_user() lives in ms-functions.php which WordPress only
// auto-loads when MULTISITE=true. network_install runs with MULTISITE=false
// (single-site boot) so we must load it explicitly.
if ( ! \function_exists( 'wpmu_create_user' ) ) {
require_once \ABSPATH . WPINC . '/ms-functions.php';
}
$email = \sanitize_email( $params['email'] );
if ( '' === $email ) {
throw new \InvalidArgumentException( 'A valid admin email is required.' );
}
$domain = isset( $params['domain'] )
? \sanitize_text_field( (string) $params['domain'] )
: (string) \wp_parse_url( (string) \get_option( 'siteurl' ), PHP_URL_HOST );
if ( '' === $domain ) {
throw new \InvalidArgumentException( 'A valid domain is required.' );
}
$siteName = \sanitize_text_field( $params['site_name'] ?? \get_bloginfo( 'name' ) );
$normalize = static fn ( string $d ): string => \strtolower( \rtrim( $d, '.' ) );
// Populate global multisite table references before calling network_domain_check().
global $wpdb;
foreach ( $wpdb->tables( 'ms_global' ) as $table => $prefixed_table ) {
$wpdb->$table = $prefixed_table;
}
$existingDomain = \network_domain_check();
if ( $existingDomain ) {
if ( $normalize( $existingDomain ) === $normalize( $domain ) ) {
$this->logger->info( 'NetworkInstall: network already installed, skipping', [ 'domain' => $existingDomain ] );
return [
'installed' => false,
'message' => 'Network already installed with this domain.',
'domain' => $existingDomain,
];
}
throw new \RuntimeException(
\sprintf( 'A network is already installed with domain: %s', $existingDomain )
);
}
$this->ensureAdminUser( $email );
$this->logger->info(
'NetworkInstall: installing network',
[
'domain' => $domain,
'email' => $email,
]
);
\install_network();
$result = \populate_network( 1, $domain, $email, $siteName, '/', false );
if ( \is_wp_error( $result ) ) {
$this->logger->error(
'NetworkInstall: populate_network failed',
[
'domain' => $domain,
'code' => $result->get_error_code(),
'error' => $result->get_error_message(),
]
);
throw new \RuntimeException(
\sprintf( '[%s] %s', $result->get_error_code(), $result->get_error_message() )
);
}
$installedDomain = (string) \network_domain_check();
$this->logger->info( 'NetworkInstall: network installed', [ 'domain' => $installedDomain ] );
return [
'installed' => true,
'domain' => $installedDomain,
];
}
/**
* Ensure a WordPress admin user exists for the given email.
*
* Throws if the user already exists but is not an administrator, to prevent
* silent privilege promotion of unrelated accounts.
* The generated password is intentionally discarded — access is via OneClickLogin.
*
* @param string $email Admin email address.
* @return void
*
* @throws \RuntimeException If the user is not an admin, or user creation fails.
*/
private function ensureAdminUser( string $email ): void {
$user = \get_user_by( 'email', $email );
if ( $user ) {
if ( ! \in_array( 'administrator', (array) $user->roles, true ) ) {
$this->logger->warning(
'NetworkInstall: refusing to promote existing non-admin user',
[
'email' => $email,
'roles' => (array) $user->roles,
]
);
throw new \RuntimeException(
\sprintf( 'User %s already exists and is not an administrator; refusing to promote.', $email )
);
}
return;
}
$login = \sanitize_user( (string) \strstr( $email, '@', true ) );
$userId = \wpmu_create_user( $login, \wp_generate_password(), $email );
if ( false === $userId || \is_wp_error( $userId ) ) {
$message = \is_wp_error( $userId ) ? $userId->get_error_message() : 'wpmu_create_user returned false';
$this->logger->error(
'NetworkInstall: failed to create admin user',
[
'email' => $email,
'error' => $message,
]
);
throw new \RuntimeException(
\sprintf( 'Failed to create admin user for %s: %s', $email, $message )
);
}
}
}