99use Flagsmith \Engine \Utils \Exceptions \FeatureStateNotFound ;
1010use Flagsmith \Engine \Utils \Hashing ;
1111use Flagsmith \Engine \Utils \Semver ;
12- use Flagsmith \Engine \Utils \StringValue ;
1312use Flagsmith \Engine \Utils \Types \Context \EvaluationContext ;
1413use Flagsmith \Engine \Utils \Types \Context \FeatureContext ;
1514use Flagsmith \Engine \Utils \Types \Context \SegmentRuleType ;
@@ -28,6 +27,8 @@ class Engine
2827 public const STRONGEST_PRIORITY = -INF ;
2928 public const WEAKEST_PRIORITY = +INF ;
3029
30+ private const VALID_CONTEXT_VALUE_TYPES = ['string ' , 'integer ' , 'boolean ' , 'double ' ];
31+
3132 /**
3233 * Get the evaluation result for a given context.
3334 *
@@ -247,6 +248,7 @@ private static function _contextMatchesCondition(
247248 $ segmentKey ,
248249 ): bool {
249250 $ contextValue = self ::_getContextValue ($ context , $ condition ->property );
251+ $ cast = self ::_getCaster ($ contextValue );
250252
251253 switch ($ condition ->operator ) {
252254 case SegmentConditionOperator::IN :
@@ -269,8 +271,7 @@ private static function _contextMatchesCondition(
269271 $ inValues = explode (', ' , $ condition ->value );
270272 }
271273 }
272- $ inValues = array_map (fn ($ value ) => StringValue::from ($ value ), $ inValues );
273- $ contextValue = StringValue::from ($ contextValue );
274+ $ inValues = array_map ($ cast , $ inValues );
274275 return in_array ($ contextValue , $ inValues , strict: true );
275276
276277 case SegmentConditionOperator::PERCENTAGE_SPLIT :
@@ -317,10 +318,12 @@ private static function _contextMatchesCondition(
317318 return $ contextValue !== null ;
318319
319320 case SegmentConditionOperator::CONTAINS :
320- return str_contains ($ contextValue , $ condition ->value );
321+ return is_string ($ contextValue ) && is_string ($ condition ->value )
322+ && str_contains ($ contextValue , $ condition ->value );
321323
322324 case SegmentConditionOperator::NOT_CONTAINS :
323- return !str_contains ($ contextValue , $ condition ->value );
325+ return is_string ($ contextValue ) && is_string ($ condition ->value )
326+ && !str_contains ($ contextValue , $ condition ->value );
324327
325328 case SegmentConditionOperator::REGEX :
326329 return (bool ) preg_match ("/ {$ condition ->value }/ " , (string ) $ contextValue );
@@ -350,12 +353,12 @@ private static function _contextMatchesCondition(
350353 }
351354
352355 return match ($ operator ) {
353- '== ' => $ contextValue == $ condition ->value ,
354- '!= ' => $ contextValue != $ condition ->value ,
355- '> ' => $ contextValue > $ condition ->value ,
356- '>= ' => $ contextValue >= $ condition ->value ,
357- '< ' => $ contextValue < $ condition ->value ,
358- '<= ' => $ contextValue <= $ condition ->value ,
356+ '== ' => $ contextValue === $ cast ( $ condition ->value ) ,
357+ '!= ' => $ contextValue !== $ cast ( $ condition ->value ) ,
358+ '> ' => $ contextValue > $ cast ( $ condition ->value ) ,
359+ '>= ' => $ contextValue >= $ cast ( $ condition ->value ) ,
360+ '< ' => $ contextValue < $ cast ( $ condition ->value ) ,
361+ '<= ' => $ contextValue <= $ cast ( $ condition ->value ) ,
359362 };
360363 }
361364
@@ -386,12 +389,33 @@ private static function _getContextValue($context, $property)
386389 return null ;
387390 }
388391
389- return $ results [0 ];
392+ if (in_array (gettype ($ results [0 ]), self ::VALID_CONTEXT_VALUE_TYPES )) {
393+ return $ results [0 ];
394+ };
390395 }
391396
392397 return null ;
393398 }
394399
400+ /**
401+ * Get a condition value type caster according to a context value
402+ * @param mixed $contextValue
403+ * @return ?callable
404+ */
405+ private static function _getCaster ($ contextValue ): ?callable
406+ {
407+ if (!in_array (gettype ($ contextValue ), self ::VALID_CONTEXT_VALUE_TYPES )) {
408+ return null ;
409+ }
410+
411+ return match (gettype ($ contextValue )) {
412+ 'boolean ' => fn ($ v ) => !in_array ($ v , ['False ' , 'false ' ]),
413+ 'string ' => 'strval ' ,
414+ 'integer ' => fn ($ v ) => is_numeric ($ v ) ? (int ) $ v : $ v ,
415+ 'double ' => fn ($ v ) => is_numeric ($ v ) ? (float ) $ v : $ v ,
416+ };
417+ }
418+
395419 /**
396420 * Get the environment feature states.
397421 * @param EnvironmentModel $environment
0 commit comments