From 717112f829020ec2f3ea3cb459fea256ebfdb2d9 Mon Sep 17 00:00:00 2001 From: David Stone Date: Wed, 4 Mar 2026 18:34:13 -0700 Subject: [PATCH] fix(checkout): convert template IDs to integers in get_available_site_templates Fixes #351 - Template validation failing with 'The selected template is not available for this product' error. Root cause: Template IDs stored as string keys in the limitations array were not being converted to integers, causing type mismatch with the validation rule which uses absint() on the submitted template ID. Changes: - Updated get_available_site_templates() to convert site_id to integer - Updated get_pre_selected_site_template() to convert site_id to integer - Added regression test to ensure template IDs are returned as integers - Test validates strict type checking with in_array(..., true) This ensures consistent integer comparison in the Site_Template validation rule (inc/helpers/validation-rules/class-site-template.php:104). --- .../class-limit-site-templates.php | 6 ++- tests/WP_Ultimo/Objects/Limitations_Test.php | 38 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/inc/limitations/class-limit-site-templates.php b/inc/limitations/class-limit-site-templates.php index 18441650..8fafb34b 100644 --- a/inc/limitations/class-limit-site-templates.php +++ b/inc/limitations/class-limit-site-templates.php @@ -221,7 +221,8 @@ public function get_available_site_templates() { if (self::BEHAVIOR_AVAILABLE === $site_settings->behavior || self::BEHAVIOR_PRE_SELECTED === $site_settings->behavior || self::MODE_DEFAULT === $this->mode) { - $available[] = $site_id; + // Convert to integer to match type used in validation (absint) + $available[] = absint($site_id); } } @@ -248,7 +249,8 @@ public function get_pre_selected_site_template() { $site_settings = (object) $site_settings; if (self::BEHAVIOR_PRE_SELECTED === $site_settings->behavior) { - $pre_selected_site_template = $site_id; + // Convert to integer to match type used in validation (absint) + $pre_selected_site_template = absint($site_id); } } diff --git a/tests/WP_Ultimo/Objects/Limitations_Test.php b/tests/WP_Ultimo/Objects/Limitations_Test.php index 9fba84a5..9c94683d 100644 --- a/tests/WP_Ultimo/Objects/Limitations_Test.php +++ b/tests/WP_Ultimo/Objects/Limitations_Test.php @@ -910,4 +910,42 @@ public function test_checkout_plan_plus_addon_preserves_templates(): void { // Disk space should be additive $this->assertEquals(600, $limits->disk_space->get_limit(), 'Disk space should be summed'); } + + /** + * Test that get_available_site_templates returns integers, not strings. + * + * Regression test for issue #351: When template IDs are stored as string keys + * in the limit array, they must be converted to integers for proper comparison + * in the Site_Template validation rule. + */ + public function test_available_site_templates_returns_integers(): void { + + $limitations = new Limitations([ + 'site_templates' => [ + 'enabled' => true, + 'mode' => 'choose_available_templates', + 'limit' => [ + '123' => ['behavior' => 'available'], + '456' => ['behavior' => 'pre_selected'], + '789' => ['behavior' => 'not_available'], + ], + ], + ]); + + $available = $limitations->site_templates->get_available_site_templates(); + + // Should return integers, not strings + $this->assertContains(123, $available, 'Template 123 should be in available array as integer'); + $this->assertContains(456, $available, 'Template 456 should be in available array as integer'); + $this->assertNotContains(789, $available, 'Template 789 should not be available'); + + // Verify strict type checking + foreach ($available as $template_id) { + $this->assertIsInt($template_id, 'All template IDs should be integers'); + } + + // Verify in_array works with strict comparison + $this->assertTrue(in_array(123, $available, true), 'in_array with strict=true should find integer 123'); + $this->assertTrue(in_array(456, $available, true), 'in_array with strict=true should find integer 456'); + } }