Skip to content

Conversation

@superdav42
Copy link
Collaborator

@superdav42 superdav42 commented Sep 23, 2025

Summary by CodeRabbit

  • New Features
    • Added a Multisite Setup wizard to guide enabling and configuring WordPress Multisite, with automatic configuration where possible and manual instructions as fallback.
  • Refactor
    • Updated setup redirection: non-multisite installs go to the Multisite Setup wizard; multisite installs with pending setup go to the network setup wizard.
  • Bug Fixes
    • Prevented template site creation logic from running on non-multisite installations.
  • Documentation
    • Corrected a minor typo in admin page capability documentation.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 23, 2025

Walkthrough

Adds a new Multisite Setup admin wizard, wires it into initialization, and updates redirect logic to route non-multisite installs to this wizard. Introduces multisite creation/configuration routines, completion views, and manual instructions. Also includes a small docblock fix and a multisite guard in a default content installer.

Changes

Cohort / File(s) Summary of changes
Docblock correction
inc/admin-pages/class-base-admin-page.php
Fixed a docblock typo in get_capability() text. No functional changes.
Multisite setup wizard (new)
inc/admin-pages/class-multisite-setup-admin-page.php
Added Multisite_Setup_Admin_Page with sections (welcome/configure/complete), network config fields, wp-config.php edits, network creation, final constants append, manual instructions, transient handling, and script registration.
Setup redirect logic
inc/admin-pages/class-setup-wizard-admin-page.php
Split redirect_to_wizard(): non‑multisite redirects to multisite setup page; multisite with unfinished setup redirects to network setup. Added explicit exits.
Initialization wiring
inc/class-wp-ultimo.php
Instantiates the new Multisite_Setup_Admin_Page during init after the existing setup wizard.
Installer multisite guard
inc/installers/class-default-content-installer.php
Added early return in done_creating_template_site() when not multisite; removed unused variable.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Admin
  participant WP as WP Admin
  participant SW as Setup_Wizard_Admin_Page
  participant MS as Multisite_Setup_Admin_Page

  Admin->>WP: Access admin
  WP->>SW: redirect_to_wizard()
  alt Multisite disabled
    SW-->>WP: wp_redirect(admin.php?page=wp-ultimo-multisite-setup)
    WP->>MS: Load wizard (welcome)
  else Multisite enabled AND setup not finished
    SW-->>WP: wp_redirect(wu_network_admin_url('wp-ultimo-setup'))
  else Multisite enabled AND setup finished
    SW-->>WP: No redirect
  end
Loading
sequenceDiagram
  autonumber
  actor Admin
  participant MS as Multisite_Setup_Admin_Page
  participant FS as Filesystem
  participant WP as WordPress (Install/Network)

  Admin->>MS: Configure (structure, sitename, email) + Submit
  MS->>MS: Validate & store transients
  MS->>FS: modify_wp_config() (initial multisite constants)
  alt Write OK
    MS->>WP: create_network(subdomain?, sitename, email)
    alt Network created
      MS->>FS: add_final_multisite_constants()
      MS-->>Admin: Redirect to Complete
    else Creation failed
      MS-->>Admin: Show manual instructions
    end
  else Write failed
    MS-->>Admin: Show manual instructions
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

I thump my paws—new paths to hop,
A multisite moon atop my crop.
Redirects align, the trails are clear,
Configs nibble close and near.
If writes won’t budge, I scribble notes—
Then bound to “Complete” with fluffy quotes. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "WIP Create network wiz" clearly refers to the main change — adding a network-creation/setup wizard — so it is related to and summarizes the primary change, though it is informal and uses shorthand ("WIP", "wiz") instead of a final clear phrasing.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch create-network-wiz

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (3)
inc/class-wp-ultimo.php (1)

143-147: Gate Multisite Setup page instantiation to non‑multisite to avoid duplicate top‑level menus

Right now both Setup Wizard and Multisite Setup pages register as top-level in single-site, causing duplicate “Multisite Ultimate” menus. Instantiate the Multisite Setup page only when multisite is disabled.

-		/*
-		 * Multisite Setup for non-multisite installations
-		 */
-		new WP_Ultimo\Admin_Pages\Multisite_Setup_Admin_Page();
+		/*
+		 * Multisite Setup for non-multisite installations
+		 */
+		if (! is_multisite()) {
+			new WP_Ultimo\Admin_Pages\Multisite_Setup_Admin_Page();
+		}
inc/admin-pages/class-multisite-setup-admin-page.php (2)

382-394: Subdomain vs subdirectory .htaccess rules differ

Provide rules based on selected structure; current rules are subdirectory-only.

-		$htaccess_rules = 'RewriteEngine On
+		$htaccess_rules = $subdomain_install ? 'RewriteEngine On
+RewriteBase /
+RewriteRule ^index\.php$ - [L]
+
+RewriteRule ^wp-admin$ wp-admin/ [R=301,L]
+RewriteCond %{REQUEST_FILENAME} -f [OR]
+RewriteCond %{REQUEST_FILENAME} -d
+RewriteRule ^ - [L]
+RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
+RewriteRule ^(.*\.php)$ $1 [L]
+RewriteRule . index.php [L]' : 'RewriteEngine On
 RewriteRule ^index\.php$ - [L]
 
 # add a trailing slash to /wp-admin
 RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
 
 RewriteCond %{REQUEST_FILENAME} -f [OR]
 RewriteCond %{REQUEST_FILENAME} -d
 RewriteRule ^ - [L]
 RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
 RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
 RewriteRule . index.php [L]';

Please verify these match WordPress Network Setup output for your server environment.

Also applies to: 368-375


74-83: Optional: Auto-redirect away if multisite is already enabled

Prevents showing this page after success.

 	public function __construct() {
 
+		if (is_multisite()) {
+			wp_safe_redirect(wu_network_admin_url('wp-ultimo-setup'));
+			exit;
+		}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 20bccf7 and f844d95.

📒 Files selected for processing (5)
  • inc/admin-pages/class-base-admin-page.php (1 hunks)
  • inc/admin-pages/class-multisite-setup-admin-page.php (1 hunks)
  • inc/admin-pages/class-setup-wizard-admin-page.php (1 hunks)
  • inc/class-wp-ultimo.php (1 hunks)
  • inc/installers/class-default-content-installer.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
inc/class-wp-ultimo.php (1)
inc/admin-pages/class-multisite-setup-admin-page.php (1)
  • Multisite_Setup_Admin_Page (21-626)
inc/admin-pages/class-setup-wizard-admin-page.php (2)
inc/class-requirements.php (1)
  • run_setup (101-120)
inc/functions/helper.php (1)
  • wu_request (132-137)
inc/admin-pages/class-multisite-setup-admin-page.php (4)
inc/admin-pages/class-wizard-admin-page.php (3)
  • Wizard_Admin_Page (23-392)
  • render_submit_box (373-383)
  • get_next_section_link (266-275)
inc/admin-pages/class-base-admin-page.php (4)
  • __construct (173-205)
  • get_title (718-718)
  • get_menu_title (726-726)
  • register_scripts (694-694)
inc/functions/helper.php (1)
  • wu_request (132-137)
inc/functions/url.php (1)
  • wu_network_admin_url (53-60)
inc/installers/class-default-content-installer.php (1)
inc/class-requirements.php (1)
  • is_multisite (228-237)
🔇 Additional comments (3)
inc/admin-pages/class-base-admin-page.php (1)

219-224: Docblock fix looks good

Accurate and clarifies the method purpose.

inc/installers/class-default-content-installer.php (1)

55-57: Good guard to avoid fatal in single-site

Early return prevents calling domain_exists() outside multisite. Nice.

inc/admin-pages/class-setup-wizard-admin-page.php (1)

224-236: Redirect split is correct and avoids loops

Clear separation of single-site vs network flows, with exits. LGTM.

Comment on lines +123 to +151
return [
'welcome' => [
'title' => __('Multisite Required', 'multisite-ultimate'),
'description' => implode(
'<br><br>',
[
__('WordPress Multisite is required for Multisite Ultimate to function properly.', 'multisite-ultimate'),
__('This wizard will guide you through enabling WordPress Multisite and configuring your network.', 'multisite-ultimate'),
__('We recommend creating a backup of your files and database before proceeding.', 'multisite-ultimate'),
]
),
'next_label' => __('Get Started &rarr;', 'multisite-ultimate'),
'back' => false,
],
'configure' => [
'title' => __('Network Configuration', 'multisite-ultimate'),
'description' => __('Configure your network settings. These settings determine how your sites will be structured.', 'multisite-ultimate'),
'next_label' => __('Create Network', 'multisite-ultimate'),
'handler' => [$this, 'handle_configure'],
'fields' => [$this, 'get_network_configuration_fields'],
],
'complete' => [
'title' => __('Setup Complete', 'multisite-ultimate'),
'description' => __('WordPress Multisite setup is now complete!', 'multisite-ultimate'),
'view' => [$this, 'section_complete'],
'back' => false,
'next' => false,
],
];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick

Welcome view defined but not used

section_welcome() won’t run because the 'welcome' section lacks a 'view' entry. Wire it up.

-			'welcome'   => [
+			'welcome'   => [
 				'title'       => __('Multisite Required', 'multisite-ultimate'),
 				'description' => implode(
 					'<br><br>',
 					[
 						__('WordPress Multisite is required for Multisite Ultimate to function properly.', 'multisite-ultimate'),
 						__('This wizard will guide you through enabling WordPress Multisite and configuring your network.', 'multisite-ultimate'),
 						__('We recommend creating a backup of your files and database before proceeding.', 'multisite-ultimate'),
 					]
 				),
 				'next_label'  => __('Get Started &rarr;', 'multisite-ultimate'),
 				'back'        => false,
+				'view'        => [$this, 'section_welcome'],
 			],

Also applies to: 160-208

🤖 Prompt for AI Agents
inc/admin-pages/class-multisite-setup-admin-page.php around lines 123-151 (and
similarly 160-208): the "welcome" section currently has no 'view' entry so the
section_welcome() callback is never invoked; add a 'view' => [$this,
'section_welcome'] key to the welcome array, and review other section arrays in
the 160-208 range to ensure each section that has a corresponding section_*
method is wired with a 'view' => [$this, 'section_<name>'] entry (or remove
unused section_* methods) so the defined view callbacks are actually used.

Comment on lines +228 to +239
'subdomain_install' => [
'type' => 'radio',
'title' => __('Site Structure', 'multisite-ultimate'),
'desc' => __('Choose between subdirectories or subdomains for your network sites.', 'multisite-ultimate'),
'options' => [
'sub0' => sprintf(__('Sites will use sub-directories like %s (Recommended)', 'multisite-ultimate'), '<code>' . esc_html($base_domain) . '/site1</code>'),

'sub1' => sprintf(__('Sites will use sub-domains like %s (Requires wildcard DNS)', 'multisite-ultimate'), '<code>site1.' . esc_html($base_domain) . '</code>'),

],
'default' => '0',
],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Radio values → boolean conversion bug (always true)

Options use 'sub0'/'sub1' but the code casts the string directly to bool, making both truthy. Use '0'/'1' (or map explicitly) and compare string values.

-			'subdomain_install'        => [
+			'subdomain_install'        => [
 				'type'    => 'radio',
 				'title'   => __('Site Structure', 'multisite-ultimate'),
 				'desc'    => __('Choose between subdirectories or subdomains for your network sites.', 'multisite-ultimate'),
 				'options' => [
-					'sub0' => sprintf(__('Sites will use sub-directories like %s (Recommended)', 'multisite-ultimate'), '<code>' . esc_html($base_domain) . '/site1</code>'),
-					
-					'sub1'  => sprintf(__('Sites will use sub-domains like %s (Requires wildcard DNS)', 'multisite-ultimate'), '<code>site1.' . esc_html($base_domain) . '</code>'),
+					'0' => sprintf(__('Sites will use sub-directories like %s (Recommended)', 'multisite-ultimate'), '<code>' . esc_html($base_domain) . '/site1</code>'),
+					'1' => sprintf(__('Sites will use sub-domains like %s (Requires wildcard DNS)', 'multisite-ultimate'), '<code>site1.' . esc_html($base_domain) . '</code>'),
 				],
-				'default' => '0',
+				'default' => '0',
 			],
-		$subdomain_install = (bool) wu_request('subdomain_install', 0);
+		$subdomain_install = wu_request('subdomain_install', '0') === '1';

Also applies to: 287-290

🤖 Prompt for AI Agents
inc/admin-pages/class-multisite-setup-admin-page.php lines ~228-239 and
~287-290: the radio options currently use keys 'sub0'/'sub1' but elsewhere the
code casts the selected value to boolean (making both keys truthy), so selection
is always treated as true; change the option keys to simple '0' and '1' (and
keep 'default' => '0'), or explicitly map 'sub0'/'sub1' to boolean values and
update any checks to compare the string value (use strict equality to '1' or
'0') instead of casting to bool; apply the same fix to the block at lines
~287-290 so selection logic works correctly.

Comment on lines +465 to +501
$wp_config_path = ABSPATH . 'wp-config.php';

if (! file_exists($wp_config_path) || ! is_writable($wp_config_path)) {
return false;
}

$config_content = file_get_contents($wp_config_path);

if ($config_content === false) {
return false;
}

// Check if WP_ALLOW_MULTISITE is already defined
if (strpos($config_content, 'WP_ALLOW_MULTISITE') !== false) {
return true; // Already configured
}

// Find the location to insert the constant
$search = "/* That's all, stop editing! Happy publishing. */";
$insert_position = strpos($config_content, $search);

if ($insert_position === false) {
// Fallback: look for the wp-settings.php include
$search = "require_once ABSPATH . 'wp-settings.php';";
$insert_position = strpos($config_content, $search);
}

if ($insert_position === false) {
return false; // Can't find a safe place to insert
}

$constant_to_add = "\n// Multisite Ultimate: Enable WordPress Multisite\ndefine( 'WP_ALLOW_MULTISITE', true );\n\n";

$new_content = substr_replace($config_content, $constant_to_add, $insert_position, 0);

return file_put_contents($wp_config_path, $new_content) !== false;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Support wp-config.php one level above ABSPATH

Many installs place wp-config.php in the parent directory. Add a fallback search before giving up.

-		$wp_config_path = ABSPATH . 'wp-config.php';
-
-		if (! file_exists($wp_config_path) || ! is_writable($wp_config_path)) {
+		$paths = [
+			ABSPATH . 'wp-config.php',
+			trailingslashit(dirname(ABSPATH)) . 'wp-config.php',
+		];
+		$wp_config_path = null;
+		foreach ($paths as $candidate) {
+			if (file_exists($candidate) && is_writable($candidate)) {
+				$wp_config_path = $candidate;
+				break;
+			}
+		}
+		if ($wp_config_path === null) {
 			return false;
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$wp_config_path = ABSPATH . 'wp-config.php';
if (! file_exists($wp_config_path) || ! is_writable($wp_config_path)) {
return false;
}
$config_content = file_get_contents($wp_config_path);
if ($config_content === false) {
return false;
}
// Check if WP_ALLOW_MULTISITE is already defined
if (strpos($config_content, 'WP_ALLOW_MULTISITE') !== false) {
return true; // Already configured
}
// Find the location to insert the constant
$search = "/* That's all, stop editing! Happy publishing. */";
$insert_position = strpos($config_content, $search);
if ($insert_position === false) {
// Fallback: look for the wp-settings.php include
$search = "require_once ABSPATH . 'wp-settings.php';";
$insert_position = strpos($config_content, $search);
}
if ($insert_position === false) {
return false; // Can't find a safe place to insert
}
$constant_to_add = "\n// Multisite Ultimate: Enable WordPress Multisite\ndefine( 'WP_ALLOW_MULTISITE', true );\n\n";
$new_content = substr_replace($config_content, $constant_to_add, $insert_position, 0);
return file_put_contents($wp_config_path, $new_content) !== false;
}
$paths = [
ABSPATH . 'wp-config.php',
trailingslashit(dirname(ABSPATH)) . 'wp-config.php',
];
$wp_config_path = null;
foreach ($paths as $candidate) {
if (file_exists($candidate) && is_writable($candidate)) {
$wp_config_path = $candidate;
break;
}
}
if ($wp_config_path === null) {
return false;
}
$config_content = file_get_contents($wp_config_path);
if ($config_content === false) {
return false;
}
// Check if WP_ALLOW_MULTISITE is already defined
if (strpos($config_content, 'WP_ALLOW_MULTISITE') !== false) {
return true; // Already configured
}
// Find the location to insert the constant
$search = "/* That's all, stop editing! Happy publishing. */";
$insert_position = strpos($config_content, $search);
if ($insert_position === false) {
// Fallback: look for the wp-settings.php include
$search = "require_once ABSPATH . 'wp-settings.php';";
$insert_position = strpos($config_content, $search);
}
if ($insert_position === false) {
return false; // Can't find a safe place to insert
}
$constant_to_add = "\n// Multisite Ultimate: Enable WordPress Multisite\ndefine( 'WP_ALLOW_MULTISITE', true );\n\n";
$new_content = substr_replace($config_content, $constant_to_add, $insert_position, 0);
return file_put_contents($wp_config_path, $new_content) !== false;
}

Comment on lines +535 to +538
// Add final multisite constants to wp-config.php
$this->add_final_multisite_constants($subdomain_install, $domain);

return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Don’t ignore failure to write MULTISITE constants; add insertion fallback

  • add_final_multisite_constants() returns false if the exact WP_ALLOW_MULTISITE line isn’t found. Provide a fallback insertion point.
  • In create_network(), treat a failure to add constants as a failure overall.
-			// Add final multisite constants to wp-config.php
-			$this->add_final_multisite_constants($subdomain_install, $domain);
-
-			return true;
+			// Add final multisite constants to wp-config.php
+			$constants_ok = $this->add_final_multisite_constants($subdomain_install, $domain);
+			return (bool) $constants_ok;
-		// Find the location to insert the constants (after WP_ALLOW_MULTISITE)
-		$search          = "define( 'WP_ALLOW_MULTISITE', true );";
-		$insert_position = strpos($config_content, $search);
-
-		if ($insert_position !== false) {
-			$insert_position += strlen($search);
-			$new_content      = substr_replace($config_content, $constants_to_add, $insert_position, 0);
-			return file_put_contents($wp_config_path, $new_content) !== false;
-		}
-
-		return false;
+		// Prefer inserting after WP_ALLOW_MULTISITE, otherwise before "That's all" or wp-settings
+		$anchors = [
+			"define( 'WP_ALLOW_MULTISITE', true );",
+			"/* That's all, stop editing! Happy publishing. */",
+			"require_once ABSPATH . 'wp-settings.php';",
+		];
+		foreach ($anchors as $anchor) {
+			$pos = strpos($config_content, $anchor);
+			if ($pos !== false) {
+				$pos += ($anchor === $anchors[0]) ? strlen($anchor) : 0;
+				$new_content = substr_replace($config_content, $constants_to_add, $pos, 0);
+				return file_put_contents($wp_config_path, $new_content) !== false;
+			}
+		}
+		return false;

Also applies to: 579-590

🤖 Prompt for AI Agents
inc/admin-pages/class-multisite-setup-admin-page.php lines 535-538 and 579-590:
add_final_multisite_constants() can return false when the exact
WP_ALLOW_MULTISITE anchor isn’t found, so update create_network() to check its
return value and treat a false as an overall failure (return false and surface
an error). If add_final_multisite_constants() fails, implement a fallback
insertion strategy: attempt to insert the MULTISITE constants at a secondary
anchor (for example before "/* That's all, stop editing! */" or immediately
before the require_once for wp-settings.php), and only if both primary and
fallback insertions fail return false; ensure proper logging of the failure and
that create_network() propagates that failure instead of returning true.

Comment on lines +538 to +541
return true;
} catch (Exception $e) {
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Namespace issue: catching Exception will fatal

Use the global Exception class or import it. Otherwise PHP looks for WP_Ultimo\Admin_Pages\Exception.

-		} catch (Exception $e) {
+		} catch (\Exception $e) {
 			return false;
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return true;
} catch (Exception $e) {
return false;
}
return true;
} catch (\Exception $e) {
return false;
}
🤖 Prompt for AI Agents
In inc/admin-pages/class-multisite-setup-admin-page.php around lines 538 to 541,
the catch block currently references Exception without qualification which makes
PHP look for WP_Ultimo\Admin_Pages\Exception and will fatal; change the catch to
use the global Exception class (e.g. catch (\Exception $e)) or add a top-level
import (use Exception;) at the file namespace header so the global Exception is
correctly referenced; update the catch signature accordingly and keep existing
handling (return false).

Comment on lines +600 to +625
if (get_current_screen()->id !== 'toplevel_page_wp-ultimo-multisite-setup') {
return;
}

wp_add_inline_script(
'wp-admin',
'
// Copy to clipboard functionality
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll("button[onclick*=\'navigator.clipboard.writeText\']").forEach(function(button) {
button.addEventListener("click", function() {
var textarea = this.nextElementSibling;
if (textarea && textarea.tagName === "TEXTAREA") {
navigator.clipboard.writeText(textarea.value).then(function() {
button.textContent = "Copied!";
setTimeout(function() {
button.textContent = "Copy to clipboard";
}, 2000);
});
}
});
});
});
'
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick

Inline script attached to a non‑existent handle

wp_add_inline_script('wp-admin', ...) won’t run. Attach to a registered/enqueued handle (e.g., 'jquery') or enqueue a small handle for this page and attach to it.

-		wp_add_inline_script(
-			'wp-admin',
+		wp_add_inline_script(
+			'jquery',
 			'
 			// Copy to clipboard functionality
 			document.addEventListener("DOMContentLoaded", function() {
 				document.querySelectorAll("button[onclick*=\'navigator.clipboard.writeText\']").forEach(function(button) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (get_current_screen()->id !== 'toplevel_page_wp-ultimo-multisite-setup') {
return;
}
wp_add_inline_script(
'wp-admin',
'
// Copy to clipboard functionality
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll("button[onclick*=\'navigator.clipboard.writeText\']").forEach(function(button) {
button.addEventListener("click", function() {
var textarea = this.nextElementSibling;
if (textarea && textarea.tagName === "TEXTAREA") {
navigator.clipboard.writeText(textarea.value).then(function() {
button.textContent = "Copied!";
setTimeout(function() {
button.textContent = "Copy to clipboard";
}, 2000);
});
}
});
});
});
'
);
}
if (get_current_screen()->id !== 'toplevel_page_wp-ultimo-multisite-setup') {
return;
}
wp_add_inline_script(
'jquery',
'
// Copy to clipboard functionality
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll("button[onclick*=\'navigator.clipboard.writeText\']").forEach(function(button) {
button.addEventListener("click", function() {
var textarea = this.nextElementSibling;
if (textarea && textarea.tagName === "TEXTAREA") {
navigator.clipboard.writeText(textarea.value).then(function() {
button.textContent = "Copied!";
setTimeout(function() {
button.textContent = "Copy to clipboard";
}, 2000);
});
}
});
});
});
'
);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants