From 79da2e912f1233f020119c19155e96ee4b61367b Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Thu, 7 May 2026 15:57:47 -0700 Subject: [PATCH] fix: include experiment key on local-eval exposure events Local evaluation exposure events emit `metadata.experimentKey` inside the metadata blob but never lift it onto a top-level event property. Custom reports keying off `[Experiment] Experiment Key` therefore see no value for customers using local evaluation. When `variant.metadata['experimentKey']` is present, set `event_properties['[Experiment] Experiment Key']`. Mirrors the equivalent fix in the Node SDK (amplitude/experiment-node-server#83). Co-Authored-By: Claude Opus 4.7 --- src/Exposure/Exposure.php | 4 ++++ tests/Exposure/ExposureServiceTest.php | 26 ++++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/Exposure/Exposure.php b/src/Exposure/Exposure.php index 98f51b3..791bec5 100644 --- a/src/Exposure/Exposure.php +++ b/src/Exposure/Exposure.php @@ -93,6 +93,10 @@ public function toEvents(): array } elseif ($variant->value) { $event->eventProperties['[Experiment] Variant'] = $variant->value; } + $experimentKey = $variant->metadata['experimentKey'] ?? null; + if ($experimentKey) { + $event->eventProperties['[Experiment] Experiment Key'] = $experimentKey; + } if ($variant->metadata) { $event->eventProperties['metadata'] = $variant->metadata; } diff --git a/tests/Exposure/ExposureServiceTest.php b/tests/Exposure/ExposureServiceTest.php index 63154e2..0148151 100644 --- a/tests/Exposure/ExposureServiceTest.php +++ b/tests/Exposure/ExposureServiceTest.php @@ -69,6 +69,13 @@ public function testToEventsCreatesOneEventPerFlag() ]); $emptyMetadata = new Variant('on', 'on'); $emptyVariant = new Variant(); + $withExperimentKey = new Variant('treatment', 'treatment', null, null, [ + 'segmentName' => 'All Other Users', + 'flagType' => 'experiment', + 'flagVersion' => 10, + 'default' => false, + 'experimentKey' => 'exp-1' + ]); $results = [ 'basic' => $basic, 'different_value' => $differentValue, @@ -77,23 +84,24 @@ public function testToEventsCreatesOneEventPerFlag() 'holdout' => $holdout, 'partial_metadata' => $partialMetadata, 'empty_metadata' => $emptyMetadata, - 'empty_variant' => $emptyVariant + 'empty_variant' => $emptyVariant, + 'with_experiment_key' => $withExperimentKey ]; $exposure = new Exposure($user, $results); $events = $exposure->toEvents(); // Should exclude default (default=true) only - // basic, different_value, mutex, holdout, partial_metadata, empty_metadata, empty_variant = 7 events - $this->assertCount(7, $events); - + // basic, different_value, mutex, holdout, partial_metadata, empty_metadata, empty_variant, with_experiment_key = 8 events + $this->assertCount(8, $events); + foreach ($events as $event) { $this->assertEquals('[Experiment] Exposure', $event->eventType); $this->assertEquals($user->userId, $event->userId); $this->assertEquals($user->deviceId, $event->deviceId); - + $flagKey = $event->eventProperties['[Experiment] Flag Key']; $this->assertArrayHasKey($flagKey, $results); $variant = $results[$flagKey]; - + // Validate event properties if ($variant->key) { $this->assertEquals($variant->key, $event->eventProperties['[Experiment] Variant']); @@ -103,6 +111,12 @@ public function testToEventsCreatesOneEventPerFlag() if ($variant->metadata) { $this->assertEquals($variant->metadata, $event->eventProperties['metadata']); } + + if ($flagKey === 'with_experiment_key') { + $this->assertEquals('exp-1', $event->eventProperties['[Experiment] Experiment Key']); + } else { + $this->assertArrayNotHasKey('[Experiment] Experiment Key', $event->eventProperties); + } // Validate user properties $flagType = $variant->metadata['flagType'] ?? null;