-
Notifications
You must be signed in to change notification settings - Fork 33
feat: support starts_with and ends_with operators in local evaluation #209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| "posthog-php": minor | ||
| --- | ||
|
|
||
| Support the `starts_with`, `not_starts_with`, `ends_with`, and `not_ends_with` property filter operators in feature flag local evaluation. Matching is case-insensitive and mirrors `icontains`. Previously, local evaluation treated these operators as unrecognized and silently evaluated their conditions to `false`; they now match correctly. | ||
|
|
||
| Operators local evaluation doesn't recognize now throw `InconclusiveMatchException`, deferring the flag to the `/flags` endpoint instead of producing a silently wrong `false` — so operators the server adds in the future degrade gracefully. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,6 +57,22 @@ public static function matchProperty($property, $propertyValues) | |
| return strpos(strtolower(FeatureFlag::valueToString($overrideValue)), strtolower(FeatureFlag::valueToString($value))) == false; | ||
| } | ||
|
|
||
| if ($operator == "starts_with") { | ||
| return str_starts_with(strtolower(FeatureFlag::valueToString($overrideValue)), strtolower(FeatureFlag::valueToString($value))); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I decided to match existing PHP conventions. In all the SDKs, I matched local conventions. I think we may want to try and match what happens on the server as closely as possible. I opened a separate issue on that: PostHog/posthog#78019 I'd rather do that as an all or nothing follow-up. |
||
| } | ||
|
|
||
| if ($operator == "not_starts_with") { | ||
| return !str_starts_with(strtolower(FeatureFlag::valueToString($overrideValue)), strtolower(FeatureFlag::valueToString($value))); | ||
| } | ||
|
|
||
| if ($operator == "ends_with") { | ||
| return str_ends_with(strtolower(FeatureFlag::valueToString($overrideValue)), strtolower(FeatureFlag::valueToString($value))); | ||
| } | ||
|
|
||
| if ($operator == "not_ends_with") { | ||
| return !str_ends_with(strtolower(FeatureFlag::valueToString($overrideValue)), strtolower(FeatureFlag::valueToString($value))); | ||
| } | ||
|
|
||
| if (in_array($operator, ["regex", "not_regex"])) { | ||
| $regexValue = FeatureFlag::prepareValueForRegex($value); | ||
| if (FeatureFlag::isRegularExpression($regexValue)) { | ||
|
|
@@ -157,7 +173,7 @@ public static function matchProperty($property, $propertyValues) | |
| && FeatureFlag::compareSemverTuples($overrideTuple, $upper) < 0; | ||
| } | ||
|
|
||
| return false; | ||
| throw new InconclusiveMatchException("Unknown operator: " . $operator); | ||
| } | ||
|
|
||
| /** | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous silent-
falsebehavior still applies to any future operator the server adds:matchProperty()reaches its finalreturn false, so the condition can produce an incorrect local result without triggering remote fallback. The other SDK implementations generally treat an unknown operator as inconclusive and fall back to/flags. Could we change the unknown-operator path to throwInconclusiveMatchExceptionand add a regression test using something likefuture_operator? This is pre-existing behavior, but this PR demonstrates the forward-compatibility risk.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!