'capability_here'
* To add a page to the network admin (wp-admin/network), use: 'network_admin_menu' => 'capability_here'
* To add a page to the user (wp-admin/user) admin, use: 'user_admin_menu' => 'capability_here'
*
* @since 2.0.0
* @var array
*/
protected $supported_panels = [
'network_admin_menu' => 'manage_network',
];
/**
* Is this an old install migrating.
*
* @since 2.0.0
* @var bool|null
*/
private ?bool $is_migration = null;
/**
* The integration object, if it exists.
*
* @since 2.2.0
* @var mixed
*/
protected $integration;
/**
* Overrides original construct method.
*
* We need to override the construct method to make sure
* we make the necessary changes to the Wizard page when it's
* being run for the first time.
*
* @since 2.0.0
* @return void
*/
public function __construct() {
if ( ! $this->is_core_loaded()) {
require_once wu_path('inc/functions/documentation.php');
/**
* Loads the necessary apis.
*/
WP_Ultimo()->load_public_apis();
$this->highlight_menu_slug = false;
$this->type = 'menu';
$this->position = 10_101_010;
$this->menu_icon = 'dashicons-wu-wp-ultimo';
add_action('admin_enqueue_scripts', [$this, 'register_scripts']);
}
parent::__construct();
add_action('admin_action_download_migration_logs', [$this, 'download_migration_logs']);
/*
* Serve the installers
*/
add_action('wp_ajax_wu_setup_install', [$this, 'setup_install']);
/*
* Load installers
*/
add_action('wu_handle_ajax_installers', [Core_Installer::get_instance(), 'handle'], 10, 3);
add_action('wu_handle_ajax_installers', [Default_Content_Installer::get_instance(), 'handle'], 10, 3);
add_action('wu_handle_ajax_installers', [Migrator::get_instance(), 'handle'], 10, 3);
/*
* Redirect on activation
*/
add_action('wu_activation', [$this, 'redirect_to_wizard']);
}
/**
* Download the migration logs.
*
* @since 2.0.7
* @return void
*/
public function download_migration_logs(): void {
check_admin_referer('download_migration_logs', 'nonce');
$path = Logger::get_logs_folder();
$file = $path . Migrator::LOG_FILE_NAME . '.log';
$file_name = str_replace($path, '', $file);
header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename=$file_name");
header('Pragma: no-cache');
readfile($file);
exit;
}
/**
* Loads the extra elements we need on the wizard itself.
*
* @since 1.8.2
* @return void
*/
public function page_loaded(): void {
parent::page_loaded();
$this->set_settings();
}
/**
* Checks if this is a migration or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_migration() {
if (null === $this->is_migration) {
$this->is_migration = Migrator::is_legacy_network();
}
return $this->is_migration;
}
/**
* Adds missing setup from settings when WP Multisite WaaS is not fully loaded.
*
* @since 2.0.0
* @return void
*/
public function set_settings(): void {
WP_Ultimo()->settings->default_sections();
}
/**
* Redirects to the wizard, if we need to.
*
* @since 2.0.0
* @return void
*/
public function redirect_to_wizard(): void {
if ( ! \WP_Ultimo\Requirements::run_setup() && wu_request('page') !== 'wp-ultimo-setup') {
wp_redirect(wu_network_admin_url('wp-ultimo-setup'));
exit;
}
}
/**
* Handles the ajax actions for installers and migrators.
*
* @since 2.0.0
* @return void
*/
public function setup_install(): void {
global $wpdb;
if ( ! current_user_can('manage_network')) {
wp_send_json_error(new \WP_Error('not-allowed', __('Permission denied.', 'wp-ultimo')));
exit;
}
/*
* Load tables.
*/
WP_Ultimo()->tables = \WP_Ultimo\Loaders\Table_Loader::get_instance();
$installer = wu_request('installer', '');
/*
* Installers should hook into this filter
*/
$status = apply_filters('wu_handle_ajax_installers', true, $installer, $this);
if (is_wp_error($status)) {
wp_send_json_error($status);
}
wp_send_json_success();
}
/**
* Check if the core was loaded.
*
* @since 2.0.0
* @return boolean
*/
public function is_core_loaded() {
return \WP_Ultimo\Requirements::met() && \WP_Ultimo\Requirements::run_setup();
}
/**
* Returns the logo for the wizard.
*
* @since 2.0.0
* @return string
*/
public function get_logo() {
return wu_get_asset('logo.webp', 'img');
}
/**
* Returns the title of the page.
*
* @since 2.0.0
* @return string Title of the page.
*/
public function get_title(): string {
return sprintf(__('Installation', 'wp-ultimo'));
}
/**
* Returns the title of menu for this page.
*
* @since 2.0.0
* @return string Menu label of the page.
*/
public function get_menu_title() {
return WP_Ultimo()->is_loaded() ? __('WP Multisite WaaS Install', 'wp-ultimo') : __('WP Multisite WaaS', 'wp-ultimo');
}
/**
* Returns the sections for this Wizard.
*
* @since 2.0.0
* @return array
*/
public function get_sections() {
$sections = [
'welcome' => [
'title' => __('Welcome', 'wp-ultimo'),
'description' => implode(
'
',
[
__('...and thanks for choosing WP Multisite WaaS!', 'wp-ultimo'),
__('This quick setup wizard will make sure your server is correctly setup, help you configure your new network, and migrate data from previous WP Multisite WaaS versions if necessary.', 'wp-ultimo'),
__('You will also have the option of importing default content. It should take 10 minutes or less!', 'wp-ultimo'),
]
),
'next_label' => __('Get Started →', 'wp-ultimo'),
'back' => false,
],
'checks' => [
'title' => __('Pre-install Checks', 'wp-ultimo'),
'description' => __('Now it is time to see if this machine has what it takes to run WP Multisite WaaS well!', 'wp-ultimo'),
'next_label' => \WP_Ultimo\Requirements::met() ? __('Go to the Next Step →', 'wp-ultimo') : __('Check Again', 'wp-ultimo'),
'handler' => [$this, 'handle_checks'],
'back' => false,
'fields' => [
'requirements' => [
'type' => 'note',
'desc' => [$this, 'renders_requirements_table'],
],
],
],
'installation' => [
'title' => __('Installation', 'wp-ultimo'),
'description' => __('Now, let\'s update your database and install the Sunrise.php file, which are necessary for the correct functioning of WP Multisite WaaS.', 'wp-ultimo'),
'next_label' => Core_Installer::get_instance()->all_done() ? __('Go to the Next Step →', 'wp-ultimo') : __('Install', 'wp-ultimo'),
'fields' => [
'terms' => [
'type' => 'note',
'desc' => fn() => $this->render_installation_steps(Core_Installer::get_instance()->get_steps(), false),
],
],
],
];
/*
* In case of migrations, add different sections.
*/
if ($this->is_migration()) {
$dry_run = wu_request('dry-run', true);
$next = true;
$errors = Migrator::get_instance()->get_errors();
$back_traces = Migrator::get_instance()->get_back_traces();
$next_label = __('Migrate!', 'wp-ultimo');
$description = __('No errors found during dry run! Now it is time to actually migrate!
We strongly recommend creating a backup of your database before moving forward with the migration.', 'wp-ultimo');
if ($dry_run) {
$next_label = __('Run Check', 'wp-ultimo');
$description = __('It seems that you were running WP Multisite WaaS 1.X on this network. This migrator will convert the data from the old version to the new one.', 'wp-ultimo') . '
' . __('First, let\'s run a test migration to see if we can spot any potential errors.', 'wp-ultimo');
}
$fields = [
'migration' => [
'type' => 'note',
'desc' => fn() => $this->render_installation_steps(Migrator::get_instance()->get_steps(), false),
],
];
if ($errors) {
$subject = 'Errors on migrating my network';
$user = wp_get_current_user();
$message_lines = [
'Hi there,',
sprintf('My name is %s.', $user->display_name),
'I tried to migrate my network from version 1 to version 2, but was not able to do it successfully...',
'Here are the error messages I got:',
sprintf('```%s%s%s```', PHP_EOL, implode(PHP_EOL, $errors), PHP_EOL),
sprintf('```%s%s%s```', PHP_EOL, $back_traces ? implode(PHP_EOL, $back_traces) : 'No backtraces found.', PHP_EOL),
'Kind regards.',
];
$message = implode(PHP_EOL . PHP_EOL, $message_lines);
$description = __('The dry run test detected issues during the test migration. Please, contact our support team to get help migrating from 1.X to version 2.', 'wp-ultimo');
$next = true;
$next_label = __('Try Again!', 'wp-ultimo');
$error_list = '' . __('List of errors detected:', 'wp-ultimo') . '
';
$errors[] = sprintf(
'
%1$s',
__('Download migration error log', 'wp-ultimo'),
add_query_arg(
[
'action' => 'download_migration_logs',
'nonce' => wp_create_nonce('download_migration_logs'),
],
network_admin_url('admin.php')
)
);
$errors[] = sprintf(
'
%1$s',
__('Rollback to version 1.10.13', 'wp-ultimo'),
add_query_arg(
[
'page' => 'wp-ultimo-rollback',
'version' => '1.10.13',
'type' => 'select-version',
],
network_admin_url('admin.php')
)
);
$error_list .= implode('
', $errors);
$fields = array_merge(
[
'errors' => [
'type' => 'note',
'classes' => 'wu-flex-grow',
'desc' => function () use ($error_list) {
/** Reset errors */
Migrator::get_instance()->session->set('errors', []);
return sprintf('