Skip to content

Commit 06bc628

Browse files
committed
Improve architecture with feature metadata
1 parent cf4fb6f commit 06bc628

10 files changed

Lines changed: 38 additions & 14 deletions

File tree

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[submodule "tests/Engine/EngineTests/EngineTestData"]
22
path = tests/Engine/EngineTests/EngineTestData
33
url = git@github.com:Flagsmith/engine-test-data.git
4-
tag = v2.4.0
4+
tag = v2.5.0

src/Engine/Engine.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public static function getEvaluationResult($context): EvaluationResult
5757
$segmentResult = new SegmentResult();
5858
$segmentResult->key = $segment->key;
5959
$segmentResult->name = $segment->name;
60-
$segmentResult->metadata = $segment->metadata ?? null;
60+
$segmentResult->metadata = $segment->metadata;
6161
$evaluatedSegments[] = $segmentResult;
6262

6363
foreach ($segment->overrides as $overrideFeature) {
@@ -152,6 +152,7 @@ private static function getFlagResultFromFeatureContext($feature, $splitKey)
152152
$flag->enabled = $feature->enabled;
153153
$flag->value = $variant->value;
154154
$flag->reason = "SPLIT; weight={$variant->weight}";
155+
$flag->metadata = $feature->metadata;
155156
return $flag;
156157
}
157158
$startPercentage = $limit;
@@ -164,6 +165,7 @@ private static function getFlagResultFromFeatureContext($feature, $splitKey)
164165
$flag->enabled = $feature->enabled;
165166
$flag->value = $feature->value;
166167
$flag->reason = 'DEFAULT';
168+
$flag->metadata = $feature->metadata;
167169
return $flag;
168170
}
169171

@@ -180,6 +182,7 @@ private static function getFlagResultFromSegmentContext($feature, $segment)
180182
$flag->enabled = $feature->enabled;
181183
$flag->value = $feature->value;
182184
$flag->reason = "TARGETING_MATCH; segment={$segment->name}";
185+
$flag->metadata = $feature->metadata;
183186
return $flag;
184187
}
185188

src/Engine/Utils/Types/Context/EvaluationContext.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ private static function _convertFeatures($jsonFeatures): array
109109
$feature->enabled = $jsonFeature->enabled;
110110
$feature->value = $jsonFeature->value;
111111
$feature->priority = $jsonFeature->priority ?? null;
112+
$feature->metadata = (array) ($jsonFeature->metadata ?? []);
112113
$feature->variants = [];
113114
foreach ($jsonFeature->variants ?? [] as $jsonVariant) {
114115
$variant = new FeatureValue();

src/Engine/Utils/Types/Context/FeatureContext.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,7 @@ class FeatureContext
2424

2525
/** @var array<FeatureValue> */
2626
public $variants;
27+
28+
/** @var ?array<string,mixed> */
29+
public $metadata;
2730
}

src/Engine/Utils/Types/Result/FlagResult.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Flagsmith\Engine\Utils\Types\Result;
44

5-
class FlagResult
5+
class FlagResult implements \JsonSerializable
66
{
77
/** @var string */
88
public $feature_key;
@@ -18,4 +18,19 @@ class FlagResult
1818

1919
/** @var ?string */
2020
public $reason;
21+
22+
/** @var ?array<string,mixed> */
23+
public $metadata;
24+
25+
public function jsonSerialize(): array
26+
{
27+
$data = get_object_vars($this);
28+
29+
// 'metadata' is only added if there is any
30+
if (empty($this->metadata)) {
31+
unset($data['metadata']);
32+
}
33+
34+
return $data;
35+
}
2136
}

src/Engine/Utils/Types/Result/SegmentResult.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,11 @@ class SegmentResult implements \JsonSerializable
1515

1616
public function jsonSerialize(): array
1717
{
18-
$data = [
19-
'key' => $this->key,
20-
'name' => $this->name,
21-
];
18+
$data = get_object_vars($this);
2219

2320
// 'metadata' is only added if there is any
24-
if (!empty($this->metadata)) {
25-
$data['metadata'] = $this->metadata;
21+
if (empty($this->metadata)) {
22+
unset($data['metadata']);
2623
}
2724

2825
return $data;

src/Models/Flags.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public static function fromEvaluationResult(
9696
foreach ($evaluationResult->flags as $flagResult) {
9797
$flag = new Flag();
9898
$flag->feature_name = $flagResult->name;
99-
$flag->feature_id = (int) $flagResult->feature_key;
99+
$flag->feature_id = $flagResult->metadata['flagsmith_id'];
100100
$flag->enabled = $flagResult->enabled;
101101
$flag->value = $flagResult->value;
102102
$flags[$flagResult->name] = $flag;

src/Utils/Mappers.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ private static function _mapEnvironmentDocumentFeatureStatesToFeatureContexts($f
117117
$feature->enabled = $featureState->enabled;
118118
$feature->value = $featureState->feature_state_value;
119119
$feature->priority = $featureState->feature_segment?->priority ?? null;
120-
120+
$feature->metadata = ['flagsmith_id' => $featureState->feature->id];
121121
$feature->variants = [];
122122
$multivariateFeatureStateValues = ((array) $featureState->multivariate_feature_state_values) ?? [];
123123
$multivariateFeatureStateValueUUIDs = array_column($multivariateFeatureStateValues, 'mv_fs_value_uuid');
@@ -187,14 +187,15 @@ private static function _mapIdentityOverridesToSegments($identityOverrides)
187187

188188
$segment->overrides = [];
189189
foreach (unserialize($serializedOverridesKey) as $overrideKey) {
190-
[$featureKey, $featureName, $enabled, $value] = $overrideKey;
190+
[$featureId, $featureName, $enabled, $value] = $overrideKey;
191191
$feature = new FeatureContext();
192192
$feature->key = ''; // Not used in identity overrides
193-
$feature->feature_key = $featureKey;
193+
$feature->feature_key = (string) $featureId;
194194
$feature->name = $featureName;
195195
$feature->enabled = $enabled;
196196
$feature->value = $value;
197197
$feature->priority = Engine::STRONGEST_PRIORITY;
198+
$feature->metadata = ['flagsmith_id' => $featureId];
198199
$segment->overrides[] = $feature;
199200
}
200201

tests/Utils/MappersTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public function testMapEnvironmentDocumentToContextProducesEvaluationContext():
6969
$this->assertEquals('some-overridden-value', $context->segments[$overrideKey]->overrides[0]->value);
7070
$this->assertEquals(-INF, $context->segments[$overrideKey]->overrides[0]->priority);
7171
$this->assertNull($context->segments[$overrideKey]->overrides[0]->variants);
72+
$this->assertEquals(['flagsmith_id' => 1], $context->segments[$overrideKey]->overrides[0]->metadata);
7273

7374
$this->assertCount(3, $context->features);
7475
$this->assertArrayHasKey('some_feature', $context->features);
@@ -79,6 +80,7 @@ public function testMapEnvironmentDocumentToContextProducesEvaluationContext():
7980
$this->assertEquals('some-value', $context->features['some_feature']->value);
8081
$this->assertNull($context->features['some_feature']->priority);
8182
$this->assertEmpty($context->features['some_feature']->variants);
83+
$this->assertEquals(['flagsmith_id' => 1], $context->features['some_feature']->metadata);
8284

8385
// Test multivariate feature with IDs - priority should be based on ID
8486
$this->assertArrayHasKey('mv_feature_with_ids', $context->features);
@@ -90,6 +92,7 @@ public function testMapEnvironmentDocumentToContextProducesEvaluationContext():
9092
$this->assertEquals('default_value', $mvFeatureWithIds->value);
9193
$this->assertNull($mvFeatureWithIds->priority);
9294
$this->assertCount(2, $mvFeatureWithIds->variants);
95+
$this->assertEquals(['flagsmith_id' => 2], $mvFeatureWithIds->metadata);
9396

9497
// First variant: ID=100, should have priority 100
9598
$this->assertEquals('variant_a', $mvFeatureWithIds->variants[0]->value);
@@ -111,6 +114,7 @@ public function testMapEnvironmentDocumentToContextProducesEvaluationContext():
111114
$this->assertEquals('fallback_value', $mvFeatureWithoutIds->value);
112115
$this->assertNull($mvFeatureWithoutIds->priority);
113116
$this->assertCount(3, $mvFeatureWithoutIds->variants);
117+
$this->assertEquals(['flagsmith_id' => 3], $mvFeatureWithoutIds->metadata);
114118

115119
// Variants should be ordered by UUID alphabetically
116120
$this->assertEquals('option_y', $mvFeatureWithoutIds->variants[0]->value);

0 commit comments

Comments
 (0)