From 4ff9435588e5925efff357266be32b4368f2e20f Mon Sep 17 00:00:00 2001 From: wadii Date: Thu, 7 May 2026 10:19:48 +0200 Subject: [PATCH] fix: respect rule type for sub-rules in segment evaluation Sub-rules were always evaluated with ALL logic, ignoring the parent rule's type field (ANY/ALL/NONE). Now uses type-aware matching for sub-rules, matching the existing conditions behavior. Also fixes premature false return for ANY rules with no conditions but with sub-rules, which prevented sub-rule evaluation. Bumps engine-test-data from v3.5.0 to v3.7.0 which includes test cases for this fix. Equivalent fix to flagsmith-engine#313. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitmodules | 2 +- src/Engine/Engine.php | 29 +++++++++++++++++++++---- tests/Engine/EngineTests/EngineTestData | 2 +- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/.gitmodules b/.gitmodules index 5e04c6d..6450f1e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "tests/Engine/EngineTests/EngineTestData"] path = tests/Engine/EngineTests/EngineTestData url = git@github.com:Flagsmith/engine-test-data.git - tag = v3.5.0 + tag = v3.7.0 diff --git a/src/Engine/Engine.php b/src/Engine/Engine.php index 9056701..f092b78 100644 --- a/src/Engine/Engine.php +++ b/src/Engine/Engine.php @@ -219,21 +219,42 @@ private static function _contextMatchesRule( } } - if ($rule->type === SegmentRuleType::ANY && !$any) { + if ($rule->type === SegmentRuleType::ANY && !$any && !empty($rule->conditions)) { return false; } + $anySubRule = false; foreach ($rule->rules as $subRule) { - $ruleMatches = self::_contextMatchesRule( + $subRuleMatches = self::_contextMatchesRule( $context, $subRule, $segmentKey, ); - if (!$ruleMatches) { - return false; + + switch ($rule->type) { + case SegmentRuleType::ALL: + if (!$subRuleMatches) { + return false; + } + break; + case SegmentRuleType::NONE: + if ($subRuleMatches) { + return false; + } + break; + case SegmentRuleType::ANY: + if ($subRuleMatches) { + $anySubRule = true; + break 2; + } + break; } } + if ($rule->type === SegmentRuleType::ANY && !$anySubRule && !empty($rule->rules)) { + return false; + } + return true; } diff --git a/tests/Engine/EngineTests/EngineTestData b/tests/Engine/EngineTests/EngineTestData index 7840a13..4b29dc7 160000 --- a/tests/Engine/EngineTests/EngineTestData +++ b/tests/Engine/EngineTests/EngineTestData @@ -1 +1 @@ -Subproject commit 7840a1349b601df3b6b4a089f40864f659801afb +Subproject commit 4b29dc772a764364af2dd504ecefbdf74cf5473f