Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 50 additions & 4 deletions inc/admin-pages/class-setup-wizard-admin-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,45 @@ public function __construct() {
add_filter('wu_handle_ajax_installers', [Migrator::get_instance(), 'handle'], 10, 3);

add_action('admin_init', [$this, 'alert_incomplete_installation']);

/*
* Handle network activation of Ultimate Multisite via AJAX.
*/
add_action('wp_ajax_wu_setup_network_activate', [$this, 'ajax_network_activate']);
}

/**
* Handles the AJAX request to network-activate Ultimate Multisite.
*
* Attempts to network-activate the plugin, returning a JSON response.
* On success the caller should reload the page so the checks refresh.
*
* @since 2.3.0
* @return void
*/
public function ajax_network_activate(): void {

check_ajax_referer('wu_setup_network_activate', 'nonce');

if ( ! current_user_can('manage_network')) {
wp_send_json_error(new \WP_Error('not-allowed', __('Permission denied.', 'ultimate-multisite')));

exit;
}

if ( ! function_exists('activate_plugin')) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}

$result = activate_plugin(WP_ULTIMO_PLUGIN_BASENAME, '', true);

if (is_wp_error($result)) {
wp_send_json_error($result);

exit;
}

wp_send_json_success();
}

/**
Expand Down Expand Up @@ -628,6 +667,10 @@ public function renders_requirements_table() {
],
];

$is_network_active = Requirements::is_network_active();

$can_network_activate = ! $is_network_active && current_user_can('manage_network');

$plugin_requirements = [
'multisite' => [
'name' => __('WordPress Multisite', 'ultimate-multisite'),
Expand All @@ -636,10 +679,12 @@ public function renders_requirements_table() {
'pass_requirements' => is_multisite(),
],
'wp-ultimo' => [
'name' => __('Ultimate Multisite', 'ultimate-multisite'),
'help' => wu_get_documentation_url('wp-ultimo-requirements'),
'condition' => apply_filters('wp_ultimo_skip_network_active_check', false) ? __('Bypassed via filter', 'ultimate-multisite') : __('Network Activated', 'ultimate-multisite'),
'pass_requirements' => Requirements::is_network_active(),
'name' => __('Ultimate Multisite', 'ultimate-multisite'),
'help' => wu_get_documentation_url('wp-ultimo-requirements'),
'condition' => apply_filters('wp_ultimo_skip_network_active_check', false) ? __('Bypassed via filter', 'ultimate-multisite') : __('Network Activated', 'ultimate-multisite'),
'pass_requirements' => $is_network_active,
'can_activate' => $can_network_activate,
'network_activate_nonce' => $can_network_activate ? wp_create_nonce('wu_setup_network_activate') : '',
],
'wp-cron' => [
'name' => __('WordPress Cron', 'ultimate-multisite'),
Expand All @@ -654,6 +699,7 @@ public function renders_requirements_table() {
[
'requirements' => $requirements,
'plugin_requirements' => $plugin_requirements,
'has_activate_button' => $can_network_activate,
]
);
}
Expand Down
21 changes: 21 additions & 0 deletions tests/WP_Ultimo/Admin_Pages/Setup_Wizard_Admin_Page_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ protected function tearDown(): void {
$_REQUEST['installer'],
$_REQUEST['dry-run'],
$_REQUEST['step'],
$_REQUEST['nonce'],
$_GET['action'],
$_GET['nonce'],
$_GET['_wpnonce']
Expand Down Expand Up @@ -443,4 +444,24 @@ public function test_constructor_registers_alert_incomplete_installation(): void
has_action('admin_init', [$this->page, 'alert_incomplete_installation'])
);
}

public function test_constructor_registers_network_activate_ajax_action(): void {
$this->assertGreaterThan(
0,
has_action('wp_ajax_wu_setup_network_activate', [$this->page, 'ajax_network_activate'])
);
}

// -------------------------------------------------------------------------
// ajax_network_activate() — permission guard
// -------------------------------------------------------------------------

public function test_ajax_network_activate_sends_json_error_without_permission(): void {
// Provide a valid nonce so the nonce check passes, isolating the permission check.
$_REQUEST['nonce'] = wp_create_nonce('wu_setup_network_activate');
wp_set_current_user(0);
$this->expectException(\WPAjaxDieStopException::class);
$this->page->ajax_network_activate();
}

}
97 changes: 92 additions & 5 deletions views/wizards/setup/requirements_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,38 @@

<?php if ( ! $req['pass_requirements']) : ?>

<a target="_blank" class="wu-no-underline wu-ml-2" href="<?php echo esc_url($req['help']); ?>" title="<?php esc_attr_e('Help', 'ultimate-multisite'); ?>">
<span class="dashicons-wu-help-with-circle wu-align-baseline"></span>
<?php esc_html_e('Read More', 'ultimate-multisite'); ?>
</a>
<?php if ( ! empty($req['can_activate'])) : ?>

<div class="wu-mt-2">
<button
type="button"
class="button button-primary wu-network-activate-btn"
data-nonce="<?php echo esc_attr($req['network_activate_nonce']); ?>"
>
<?php esc_html_e('Network Activate', 'ultimate-multisite'); ?>
</button>
<span class="wu-network-activate-spinner spinner" style="float: none; margin-top: 0; vertical-align: middle;"></span>
<span class="wu-network-activate-message wu-block wu-mt-1 wu-text-xs wu-text-red-500"></span>
<a
target="_blank"
class="wu-no-underline wu-ml-2 wu-network-activate-fallback"
href="<?php echo esc_url($req['help']); ?>"
title="<?php esc_attr_e('Help', 'ultimate-multisite'); ?>"
style="display: none;"
>
<span class="dashicons-wu-help-with-circle wu-align-baseline"></span>
<?php esc_html_e('Read More', 'ultimate-multisite'); ?>
</a>
</div>

<?php else : ?>

<a target="_blank" class="wu-no-underline wu-ml-2" href="<?php echo esc_url($req['help']); ?>" title="<?php esc_attr_e('Help', 'ultimate-multisite'); ?>">
<span class="dashicons-wu-help-with-circle wu-align-baseline"></span>
<?php esc_html_e('Read More', 'ultimate-multisite'); ?>
</a>

<?php endif; ?>

<?php endif; ?>
</td>
Expand All @@ -88,9 +116,68 @@
<?php if (\WP_Ultimo\Requirements::met() === false) : ?>

<div class="wu-mt-4 wu-p-4 wu-bg-red-100 wu-border wu-border-solid wu-border-red-200 wu-rounded-sm wu-text-red-500">
<?php esc_html_e('It looks like your hosting environment does not support the current version of Ultimate Multisite. Visit the <strong>Read More</strong> links on each item to see what steps you need to take to bring your environment up to the Ultimate Multisite current requirements.', 'ultimate-multisite'); ?>
<?php if ( ! empty($has_activate_button)) : ?>
<?php esc_html_e('Ultimate Multisite is not network active. Click the Network Activate button above to activate it automatically. If activation fails, use the Read More link that appears to resolve the issue manually.', 'ultimate-multisite'); ?>
<?php else : ?>
<?php esc_html_e('It looks like your hosting environment does not support the current version of Ultimate Multisite. Visit the Read More links on each item to see what steps you need to take to bring your environment up to the Ultimate Multisite current requirements.', 'ultimate-multisite'); ?>
<?php endif; ?>
</div>

<?php endif; ?>

</div>

<script type="text/javascript">
jQuery(function($) {

$(document).on('click', '.wu-network-activate-btn', function() {

var $btn = $(this);
var $wrapper = $btn.closest('div');
var nonce = $btn.data('nonce');
var $spinner = $wrapper.find('.wu-network-activate-spinner');
var $message = $wrapper.find('.wu-network-activate-message');
var $fallback = $wrapper.find('.wu-network-activate-fallback');

$btn.prop('disabled', true);
$spinner.addClass('is-active');
$message.text('');

$.post(
ajaxurl,
{
action: 'wu_setup_network_activate',
nonce: nonce,
},
function(response) {

if (response.success) {
window.location.reload();
return;
}

$spinner.removeClass('is-active');
$btn.hide();
$fallback.show();

var errorMsg = <?php echo wp_json_encode(__('Activation failed. Please activate the plugin manually.', 'ultimate-multisite')); ?>;

if (response.data && response.data.message) {
errorMsg = response.data.message;
}

$message.text(errorMsg);
}
).fail(function() {

$spinner.removeClass('is-active');
$btn.hide();
$fallback.show();
$message.text(<?php echo wp_json_encode(__('Activation failed. Please activate the plugin manually.', 'ultimate-multisite')); ?>);

});

});

});
</script>
Loading