From a5b38dc695db60aa50fe0dfea52050739ae18dce Mon Sep 17 00:00:00 2001 From: David Stone Date: Fri, 22 May 2026 12:46:03 -0600 Subject: [PATCH] feat: add sovereign-mode disable for remaining customer-facing UI elements Extends the sovereign-mode disable pattern (established in #1257, #1258, #1261) to the remaining 8 customer-facing UI elements. When WU_MT_SOVEREIGN_TENANT is defined, each element renders a single 'Manage on main site' link instead of its normal output. Changes: - Add sovereign helper function wu_mt_main_site_account_url() in inc/functions/sovereign.php - Add sovereign-redirect template in views/elements/sovereign-redirect.php - Add sovereign-mode short-circuit to output() method in 8 UI elements: * Account_Summary_Element * Billing_Info_Element * Invoices_Element * My_Sites_Element * Current_Membership_Element * Current_Site_Element * Template_Switching_Element * Domain_Mapping_Element - Add comprehensive unit tests for sovereign-mode functionality Resolves #1263 Resolves Ultimate-Multisite/ultimate-multisite-multi-tenancy#86 Resolves Ultimate-Multisite/ultimate-multisite-multi-tenancy#87 --- inc/functions/sovereign.php | 31 +++ inc/ui/class-account-summary-element.php | 11 ++ inc/ui/class-billing-info-element.php | 11 ++ inc/ui/class-current-membership-element.php | 11 ++ inc/ui/class-current-site-element.php | 11 ++ inc/ui/class-domain-mapping-element.php | 11 ++ inc/ui/class-invoices-element.php | 11 ++ inc/ui/class-my-sites-element.php | 11 ++ inc/ui/class-template-switching-element.php | 11 ++ .../UI/Sovereign_Mode_Elements_Test.php | 179 ++++++++++++++++++ views/elements/sovereign-redirect.php | 17 ++ 11 files changed, 315 insertions(+) create mode 100644 inc/functions/sovereign.php create mode 100644 tests/WP_Ultimo/UI/Sovereign_Mode_Elements_Test.php create mode 100644 views/elements/sovereign-redirect.php diff --git a/inc/functions/sovereign.php b/inc/functions/sovereign.php new file mode 100644 index 000000000..abdfc9401 --- /dev/null +++ b/inc/functions/sovereign.php @@ -0,0 +1,31 @@ + wu_mt_main_site_account_url(), + 'element_label' => __('Your account', 'ultimate-multisite'), + ] + ); + return; + } + $this->ensure_setup(); // Return empty if no site available (e.g., during SEO processing) diff --git a/inc/ui/class-billing-info-element.php b/inc/ui/class-billing-info-element.php index e073b7b2c..dc6e8df5d 100644 --- a/inc/ui/class-billing-info-element.php +++ b/inc/ui/class-billing-info-element.php @@ -270,6 +270,17 @@ public function setup_preview() { */ public function output($atts, $content = null) { + if (defined('WU_MT_SOVEREIGN_TENANT') && WU_MT_SOVEREIGN_TENANT) { + echo wu_get_template_contents( + 'elements/sovereign-redirect', + [ + 'main_site_account_url' => wu_mt_main_site_account_url(), + 'element_label' => __('Billing information', 'ultimate-multisite'), + ] + ); + return; + } + $this->ensure_setup(); // Return empty if no membership available (e.g., during SEO processing) diff --git a/inc/ui/class-current-membership-element.php b/inc/ui/class-current-membership-element.php index ffd4352c9..7277155eb 100644 --- a/inc/ui/class-current-membership-element.php +++ b/inc/ui/class-current-membership-element.php @@ -300,6 +300,17 @@ public function setup_preview() { */ public function output($atts, $content = null) { + if (defined('WU_MT_SOVEREIGN_TENANT') && WU_MT_SOVEREIGN_TENANT) { + echo wu_get_template_contents( + 'elements/sovereign-redirect', + [ + 'main_site_account_url' => wu_mt_main_site_account_url(), + 'element_label' => __('Subscription', 'ultimate-multisite'), + ] + ); + return; + } + $atts['membership'] = $this->membership; $atts['plan'] = $this->plan; $atts['element'] = $this; diff --git a/inc/ui/class-current-site-element.php b/inc/ui/class-current-site-element.php index 155132a66..d66ec2de4 100644 --- a/inc/ui/class-current-site-element.php +++ b/inc/ui/class-current-site-element.php @@ -352,6 +352,17 @@ public function register_scripts() { */ public function output($atts, $content = null) { + if (defined('WU_MT_SOVEREIGN_TENANT') && WU_MT_SOVEREIGN_TENANT) { + echo wu_get_template_contents( + 'elements/sovereign-redirect', + [ + 'main_site_account_url' => wu_mt_main_site_account_url(), + 'element_label' => __('Site actions', 'ultimate-multisite'), + ] + ); + return; + } + $this->ensure_setup(); // Return empty if no site available (e.g., during SEO processing) diff --git a/inc/ui/class-domain-mapping-element.php b/inc/ui/class-domain-mapping-element.php index 8bf15e0ec..26f3693a2 100644 --- a/inc/ui/class-domain-mapping-element.php +++ b/inc/ui/class-domain-mapping-element.php @@ -1097,6 +1097,17 @@ public function setup_preview() { */ public function output($atts, $content = null) { + if (defined('WU_MT_SOVEREIGN_TENANT') && WU_MT_SOVEREIGN_TENANT) { + echo wu_get_template_contents( + 'elements/sovereign-redirect', + [ + 'main_site_account_url' => wu_mt_main_site_account_url(), + 'element_label' => __('Domain mapping', 'ultimate-multisite'), + ] + ); + return; + } + $current_site = $this->site; $all_domains = wu_get_domains( diff --git a/inc/ui/class-invoices-element.php b/inc/ui/class-invoices-element.php index fa5ab2821..d4bdeee79 100644 --- a/inc/ui/class-invoices-element.php +++ b/inc/ui/class-invoices-element.php @@ -272,6 +272,17 @@ public function setup_preview() { */ public function output($atts, $content = null) { + if (defined('WU_MT_SOVEREIGN_TENANT') && WU_MT_SOVEREIGN_TENANT) { + echo wu_get_template_contents( + 'elements/sovereign-redirect', + [ + 'main_site_account_url' => wu_mt_main_site_account_url(), + 'element_label' => __('Invoices', 'ultimate-multisite'), + ] + ); + return; + } + $this->ensure_setup(); // Return empty if no membership available (e.g., during SEO processing) diff --git a/inc/ui/class-my-sites-element.php b/inc/ui/class-my-sites-element.php index f27592478..16e882f96 100644 --- a/inc/ui/class-my-sites-element.php +++ b/inc/ui/class-my-sites-element.php @@ -323,6 +323,17 @@ public function setup_preview() { */ public function output($atts, $content = null) { + if (defined('WU_MT_SOVEREIGN_TENANT') && WU_MT_SOVEREIGN_TENANT) { + echo wu_get_template_contents( + 'elements/sovereign-redirect', + [ + 'main_site_account_url' => wu_mt_main_site_account_url(), + 'element_label' => __('My sites', 'ultimate-multisite'), + ] + ); + return; + } + $atts['customer'] = $this->customer; $atts['sites'] = $this->get_sites(wu_get_isset($atts, 'site_show')); diff --git a/inc/ui/class-template-switching-element.php b/inc/ui/class-template-switching-element.php index bb83da9f6..1ee231d8b 100644 --- a/inc/ui/class-template-switching-element.php +++ b/inc/ui/class-template-switching-element.php @@ -430,6 +430,17 @@ public function switch_template() { */ public function output($atts, $content = null) { + if (defined('WU_MT_SOVEREIGN_TENANT') && WU_MT_SOVEREIGN_TENANT) { + echo wu_get_template_contents( + 'elements/sovereign-redirect', + [ + 'main_site_account_url' => wu_mt_main_site_account_url(), + 'element_label' => __('Template switching', 'ultimate-multisite'), + ] + ); + return; + } + if ( ! $this->site || self::STATE_NOT_ALLOWED === $this->permission_state) { $this->render_not_allowed_notice(); diff --git a/tests/WP_Ultimo/UI/Sovereign_Mode_Elements_Test.php b/tests/WP_Ultimo/UI/Sovereign_Mode_Elements_Test.php new file mode 100644 index 000000000..8b74d8f1d --- /dev/null +++ b/tests/WP_Ultimo/UI/Sovereign_Mode_Elements_Test.php @@ -0,0 +1,179 @@ +output([]); + $output = ob_get_clean(); + + $this->assertStringContainsString('wu-sovereign-redirect', $output); + $this->assertStringContainsString('manage on main site', $output); + $this->assertStringContainsString('Your account', $output); + } + + /** + * Test Billing_Info_Element outputs redirect in sovereign mode. + */ + public function test_billing_info_element_sovereign_mode(): void { + $element = Billing_Info_Element::get_instance(); + + ob_start(); + $element->output([]); + $output = ob_get_clean(); + + $this->assertStringContainsString('wu-sovereign-redirect', $output); + $this->assertStringContainsString('manage on main site', $output); + $this->assertStringContainsString('Billing information', $output); + } + + /** + * Test Invoices_Element outputs redirect in sovereign mode. + */ + public function test_invoices_element_sovereign_mode(): void { + $element = Invoices_Element::get_instance(); + + ob_start(); + $element->output([]); + $output = ob_get_clean(); + + $this->assertStringContainsString('wu-sovereign-redirect', $output); + $this->assertStringContainsString('manage on main site', $output); + $this->assertStringContainsString('Invoices', $output); + } + + /** + * Test My_Sites_Element outputs redirect in sovereign mode. + */ + public function test_my_sites_element_sovereign_mode(): void { + $element = My_Sites_Element::get_instance(); + + ob_start(); + $element->output([]); + $output = ob_get_clean(); + + $this->assertStringContainsString('wu-sovereign-redirect', $output); + $this->assertStringContainsString('manage on main site', $output); + $this->assertStringContainsString('My sites', $output); + } + + /** + * Test Current_Membership_Element outputs redirect in sovereign mode. + */ + public function test_current_membership_element_sovereign_mode(): void { + $element = Current_Membership_Element::get_instance(); + + ob_start(); + $element->output([]); + $output = ob_get_clean(); + + $this->assertStringContainsString('wu-sovereign-redirect', $output); + $this->assertStringContainsString('manage on main site', $output); + $this->assertStringContainsString('Subscription', $output); + } + + /** + * Test Current_Site_Element outputs redirect in sovereign mode. + */ + public function test_current_site_element_sovereign_mode(): void { + $element = Current_Site_Element::get_instance(); + + ob_start(); + $element->output([]); + $output = ob_get_clean(); + + $this->assertStringContainsString('wu-sovereign-redirect', $output); + $this->assertStringContainsString('manage on main site', $output); + $this->assertStringContainsString('Site actions', $output); + } + + /** + * Test Template_Switching_Element outputs redirect in sovereign mode. + */ + public function test_template_switching_element_sovereign_mode(): void { + $element = Template_Switching_Element::get_instance(); + + ob_start(); + $element->output([]); + $output = ob_get_clean(); + + $this->assertStringContainsString('wu-sovereign-redirect', $output); + $this->assertStringContainsString('manage on main site', $output); + $this->assertStringContainsString('Template switching', $output); + } + + /** + * Test Domain_Mapping_Element outputs redirect in sovereign mode. + */ + public function test_domain_mapping_element_sovereign_mode(): void { + $element = Domain_Mapping_Element::get_instance(); + + ob_start(); + $element->output([]); + $output = ob_get_clean(); + + $this->assertStringContainsString('wu-sovereign-redirect', $output); + $this->assertStringContainsString('manage on main site', $output); + $this->assertStringContainsString('Domain mapping', $output); + } + + /** + * Test redirect output contains button element. + */ + public function test_redirect_output_contains_button(): void { + $element = Account_Summary_Element::get_instance(); + + ob_start(); + $element->output([]); + $output = ob_get_clean(); + + $this->assertStringContainsString('assertStringContainsString('href=', $output); + } + + /** + * Test redirect output contains main site URL. + */ + public function test_redirect_output_contains_main_site_url(): void { + $element = Account_Summary_Element::get_instance(); + + ob_start(); + $element->output([]); + $output = ob_get_clean(); + + $this->assertStringContainsString('admin.php?page=account', $output); + $this->assertStringContainsString('return_to=', $output); + } +} diff --git a/views/elements/sovereign-redirect.php b/views/elements/sovereign-redirect.php new file mode 100644 index 000000000..6f50b1183 --- /dev/null +++ b/views/elements/sovereign-redirect.php @@ -0,0 +1,17 @@ + +
+ + + +