@@ -10,6 +10,7 @@ class Rule
1010 private array $ event ;
1111 private array $ failureEvent ;
1212 private ?string $ name ;
13+ private array $ failedConditions = [];
1314
1415 public function __construct (array $ options )
1516 {
@@ -33,6 +34,8 @@ public function getName(): ?string
3334
3435 public function evaluate (Facts $ facts , array $ allRules ): bool
3536 {
37+ $ this ->failedConditions = []; // Reset failed conditions before evaluation
38+
3639 if (isset ($ this ->conditions ['all ' ])) {
3740 return $ this ->evaluateAll ($ this ->conditions ['all ' ], $ facts , $ allRules );
3841 } elseif (isset ($ this ->conditions ['any ' ])) {
@@ -52,25 +55,30 @@ private function evaluateAll(array $conditions, Facts $facts, array $allRules):
5255 if (isset ($ allRules [$ dependencyRuleName ])) {
5356 $ dependencyRule = $ allRules [$ dependencyRuleName ];
5457 if (!$ dependencyRule ->evaluate ($ facts , $ allRules )) {
58+ $ this ->failedConditions [] = $ condition ;
5559 return false ;
5660 }
5761 } else {
5862 throw new Exception ("Dependent rule ' $ dependencyRuleName' not found " );
5963 }
6064 } elseif (isset ($ condition ['all ' ])) {
6165 if (!$ this ->evaluateAll ($ condition ['all ' ], $ facts , $ allRules )) {
66+ $ this ->failedConditions [] = $ condition ;
6267 return false ;
6368 }
6469 } elseif (isset ($ condition ['any ' ])) {
6570 if (!$ this ->evaluateAny ($ condition ['any ' ], $ facts , $ allRules )) {
71+ $ this ->failedConditions [] = $ condition ;
6672 return false ;
6773 }
6874 } elseif (isset ($ condition ['not ' ])) {
6975 if ($ this ->evaluateCondition ($ condition ['not ' ], $ facts , $ allRules )) {
76+ $ this ->failedConditions [] = $ condition ;
7077 return false ; // Negate the condition
7178 }
7279 } else {
7380 if (!$ this ->evaluateCondition ($ condition , $ facts , $ allRules )) {
81+ $ this ->failedConditions [] = $ condition ;
7482 return false ;
7583 }
7684 }
@@ -87,31 +95,46 @@ private function evaluateAny(array $conditions, Facts $facts, array $allRules):
8795 $ dependencyRule = $ allRules [$ dependencyRuleName ];
8896 if ($ dependencyRule ->evaluate ($ facts , $ allRules )) {
8997 return true ;
98+ } else {
99+ $ this ->failedConditions [] = $ condition ;
90100 }
91101 } else {
92102 throw new Exception ("Dependent rule ' $ dependencyRuleName' not found " );
93103 }
94104 } elseif (isset ($ condition ['all ' ])) {
95105 if ($ this ->evaluateAll ($ condition ['all ' ], $ facts , $ allRules )) {
96106 return true ;
107+ } else {
108+ $ this ->failedConditions [] = $ condition ;
97109 }
98110 } elseif (isset ($ condition ['any ' ])) {
99111 if ($ this ->evaluateAny ($ condition ['any ' ], $ facts , $ allRules )) {
100112 return true ;
113+ } else {
114+ $ this ->failedConditions [] = $ condition ;
101115 }
102116 } elseif (isset ($ condition ['not ' ])) {
103117 if (!$ this ->evaluateCondition ($ condition ['not ' ], $ facts , $ allRules )) {
104118 return true ; // Negate the condition
119+ } else {
120+ $ this ->failedConditions [] = $ condition ;
105121 }
106122 } else {
107123 if ($ this ->evaluateCondition ($ condition , $ facts , $ allRules )) {
108124 return true ;
125+ } else {
126+ $ this ->failedConditions [] = $ condition ;
109127 }
110128 }
111129 }
112130 return false ;
113131 }
114132
133+ public function getFailedConditions (): array
134+ {
135+ return $ this ->failedConditions ;
136+ }
137+
115138 private function evaluateCondition (array $ condition , Facts $ facts , array $ allRules ): bool
116139 {
117140 $ factName = $ condition ['fact ' ] ?? null ;
@@ -125,26 +148,17 @@ private function evaluateCondition(array $condition, Facts $facts, array $allRul
125148
126149 $ factData = $ facts ->get ($ factName , $ path );
127150
128- switch ($ operator ) {
129- case 'equal ' :
130- return $ factData === $ value ;
131- case 'lessThanInclusive ' :
132- return $ factData <= $ value ;
133- case 'greaterThanInclusive ' :
134- return $ factData >= $ value ;
135- case 'lessThan ' :
136- return $ factData < $ value ;
137- case 'greaterThan ' :
138- return $ factData > $ value ;
139- case 'in ' :
140- return in_array ($ factData , $ value , true );
141- case 'notIn ' :
142- return !in_array ($ factData , $ value , true );
143- case 'contains ' :
144- return is_array ($ factData ) && in_array ($ value , $ factData );
145- default :
146- throw new Exception ("Unknown operator: $ operator " );
147- }
151+ return match ($ operator ) {
152+ 'equal ' => $ factData === $ value ,
153+ 'lessThanInclusive ' => $ factData <= $ value ,
154+ 'greaterThanInclusive ' => $ factData >= $ value ,
155+ 'lessThan ' => $ factData < $ value ,
156+ 'greaterThan ' => $ factData > $ value ,
157+ 'in ' => in_array ($ factData , $ value , true ),
158+ 'notIn ' => !in_array ($ factData , $ value , true ),
159+ 'contains ' => is_array ($ factData ) && in_array ($ value , $ factData ),
160+ default => throw new Exception ("Unknown operator: $ operator " ),
161+ };
148162 }
149163
150164 public function triggerEvent (Facts $ facts ): array
@@ -205,34 +219,18 @@ private function interpretCondition(array $condition): string
205219 }
206220
207221 // Mapping operator to a readable format
208- switch ($ operator ) {
209- case 'equal ' :
210- $ operatorText = 'is equal to ' ;
211- break ;
212- case 'greaterThanInclusive ' :
213- $ operatorText = 'is >= ' ;
214- break ;
215- case 'lessThanInclusive ' :
216- $ operatorText = 'is <= ' ;
217- break ;
218- case 'lessThan ' :
219- $ operatorText = 'is less than ' ;
220- break ;
221- case 'greaterThan ' :
222- $ operatorText = 'is greater than ' ;
223- break ;
224- case 'in ' :
225- $ operatorText = 'is in ' ;
226- break ;
227- case 'notIn ' :
228- $ operatorText = 'is not in ' ;
229- break ;
230- case 'contains ' :
231- $ operatorText = 'contains ' ;
232- break ;
233- default :
234- throw new Exception ("Unknown operator: $ operator " );
235- }
222+ $ operatorText = match ($ operator ) {
223+ 'equal ' => 'is equal to ' ,
224+ 'greaterThanInclusive ' => 'is >= ' ,
225+ 'lessThanInclusive ' => 'is <= ' ,
226+ 'lessThan ' => 'is less than ' ,
227+ 'greaterThan ' => 'is greater than ' ,
228+ 'in ' => 'is in ' ,
229+ 'notIn ' => 'is not in ' ,
230+ 'contains ' => 'contains ' ,
231+ default => throw new Exception ("Unknown operator: $ operator " ),
232+ };
233+
236234 return "$ factDisplay $ operatorText $ value " ;
237235 }
238236}
0 commit comments