diff --git a/inc/checkout/class-cart.php b/inc/checkout/class-cart.php index c327976b5..066538fc1 100644 --- a/inc/checkout/class-cart.php +++ b/inc/checkout/class-cart.php @@ -1195,7 +1195,7 @@ protected function calculate_prorate_credits() { */ /* - * If the membership is in trial period theres nothing to prorate. + * If the membership is in trial period there's nothing to prorate. */ if ($this->membership->get_status() === Membership_Status::TRIALING) { return; diff --git a/inc/limitations/class-limit-domain-mapping.php b/inc/limitations/class-limit-domain-mapping.php index 0957c2d93..e9a3cc354 100644 --- a/inc/limitations/class-limit-domain-mapping.php +++ b/inc/limitations/class-limit-domain-mapping.php @@ -10,6 +10,8 @@ namespace WP_Ultimo\Limitations; // Exit if accessed directly +use WP_Ultimo\Managers\Domain_Manager; + defined('ABSPATH') || exit; /** @@ -167,7 +169,12 @@ public function get_current_domain_count($site_id = null) { $active_count = 0; foreach ($domains as $domain) { - if ($domain->is_active()) { + $domain_url = $domain->get_domain(); + if (str_starts_with($domain_url, 'www.')) { + $domain_url = substr($domain_url, 4); + } + + if (Domain_Manager::is_main_domain($domain_url) && $domain->is_active()) { ++$active_count; } } diff --git a/inc/managers/class-domain-manager.php b/inc/managers/class-domain-manager.php index 5fa99498d..5857dc8ad 100644 --- a/inc/managers/class-domain-manager.php +++ b/inc/managers/class-domain-manager.php @@ -54,6 +54,38 @@ class Domain_Manager extends Base_Manager { */ protected $integrations = []; + /** + * Checks if this is a main domain or a subdomain. + * + * @param string $domain the domain. + * + * @return bool + */ + public static function is_main_domain(string $domain) { + // Normalize: lowercase, trim spaces, drop trailing dot + $domain = strtolower(trim(rtrim($domain, '.'))); + // Check if this is a main domain (no subdomain parts) + // A main domain has only 2 parts when split by dots (e.g., example.com) + // or 3 parts if it's a known TLD structure (e.g., example.co.uk) + $parts = explode('.', $domain); + + // Simple heuristic: if domain has only 2 parts, it's definitely a main domain + if (count($parts) <= 2) { + return true; // e.g., example.com + } + + // For 3+ parts, check if it's a main domain with multi-part TLD + $known_multi_part_tlds = apply_filters('wu_multi_part_tlds', ['.co.uk', '.com.au', '.co.nz', '.com.br', '.co.in']); + $last_two_parts = '.' . $parts[ count($parts) - 2 ] . '.' . $parts[ count($parts) - 1 ]; + + // If it has exactly 3 parts and matches a known multi-part TLD, it's a main domain + if (count($parts) === 3 && in_array($last_two_parts, $known_multi_part_tlds, true)) { + return true; // e.g., example.co.uk + } + // Must be a subdomain. + return false; + } + /** * Returns the list of available host integrations. * @@ -441,27 +473,7 @@ public function should_create_www_subdomain($domain) { return false; case 'main_only': - // Check if this is a main domain (no subdomain parts) - // A main domain has only 2 parts when split by dots (e.g., example.com) - // or 3 parts if it's a known TLD structure (e.g., example.co.uk) - $parts = explode('.', $domain); - - // Simple heuristic: if domain has only 2 parts, it's definitely a main domain - if (count($parts) <= 2) { - return true; // e.g., example.com - } - - // For 3+ parts, check if it's a main domain with multi-part TLD - $known_multi_part_tlds = apply_filters('wu_multi_part_tlds', ['.co.uk', '.com.au', '.co.nz', '.com.br', '.co.in']); - $last_two_parts = '.' . $parts[ count($parts) - 2 ] . '.' . $parts[ count($parts) - 1 ]; - - // If it has exactly 3 parts and matches a known multi-part TLD, it's a main domain - if (count($parts) === 3 && in_array($last_two_parts, $known_multi_part_tlds, true)) { - return true; // e.g., example.co.uk - } - - // Otherwise, it's a subdomain - return false; + return self::is_main_domain($domain); case 'always': default: diff --git a/tests/WP_Ultimo/Checkout/Cart_Test.php b/tests/WP_Ultimo/Checkout/Cart_Test.php index aa18f0076..0d4ce323d 100644 --- a/tests/WP_Ultimo/Checkout/Cart_Test.php +++ b/tests/WP_Ultimo/Checkout/Cart_Test.php @@ -275,7 +275,7 @@ public function test_domain_mapping_downgrade_validation_over_limit() { $domain1 = wu_create_domain( [ 'blog_id' => $site->get_id(), - 'domain' => 'custom1.example.com', + 'domain' => 'www.example.com', 'active' => true, 'primary_domain' => true, 'stage' => 'done', @@ -285,7 +285,7 @@ public function test_domain_mapping_downgrade_validation_over_limit() { $domain2 = wu_create_domain( [ 'blog_id' => $site->get_id(), - 'domain' => 'custom2.example.com', + 'domain' => 'www.example.co.uk', 'active' => true, 'primary_domain' => false, 'stage' => 'done', @@ -295,7 +295,7 @@ public function test_domain_mapping_downgrade_validation_over_limit() { $domain3 = wu_create_domain( [ 'blog_id' => $site->get_id(), - 'domain' => 'custom3.example.com', + 'domain' => 'example.co', 'active' => true, 'primary_domain' => false, 'stage' => 'done', @@ -534,7 +534,7 @@ public function test_domain_mapping_downgrade_validation_disabled_in_new_plan() $site = wu_create_site( [ 'title' => 'Test Site for Domain Validation 3', - 'domain' => 'domain-test-3.example.com', + 'domain' => 'sub.example.ro', 'template_id' => 1, ] ); @@ -561,7 +561,7 @@ public function test_domain_mapping_downgrade_validation_disabled_in_new_plan() $domain1 = wu_create_domain( [ 'blog_id' => $site->get_id(), - 'domain' => 'custom-disabled.example.com', + 'domain' => 'example.eu', 'active' => true, 'primary_domain' => true, 'stage' => 'done',