diff --git a/.changeset/great-groups-capture.md b/.changeset/great-groups-capture.md new file mode 100644 index 0000000..7195743 --- /dev/null +++ b/.changeset/great-groups-capture.md @@ -0,0 +1,5 @@ +--- +"posthog-php": patch +--- + +Copy capture `groups` input to the `$groups` event property so grouped events are associated correctly. diff --git a/lib/Client.php b/lib/Client.php index 9c73f8e..7dccb58 100644 --- a/lib/Client.php +++ b/lib/Client.php @@ -295,6 +295,7 @@ public function capture(array $message) { $flagsSnapshot = $message["flags"] ?? null; unset($message["flags"]); + $hasGroups = array_key_exists("groups", $message); $usedGeneratedPersonlessDistinctId = false; if ($this->shouldApplyCaptureContext($message)) { @@ -302,6 +303,10 @@ public function capture(array $message) } $message = $this->message($message); + if (!array_key_exists('$groups', $message) && $hasGroups) { + $message['$groups'] = $message['groups']; + } + if (array_key_exists('$groups', $message)) { $message["properties"]['$groups'] = $message['$groups']; } diff --git a/test/PostHogTest.php b/test/PostHogTest.php index 264a280..a36dd30 100644 --- a/test/PostHogTest.php +++ b/test/PostHogTest.php @@ -58,6 +58,18 @@ private function getConsumer(Client $client): object return $consumerProp->getValue($client); } + private function firstBatchEvent(): array + { + foreach ($this->http_client->calls as $call) { + if (($call["path"] ?? null) === "/batch/") { + $decoded = json_decode($call["payload"], true); + return $decoded["batch"][0]; + } + } + + self::fail("Expected a /batch/ call to have been made"); + } + private function withEnvApiKey(?string $apiKey, callable $callback): void { $previousApiKey = getenv(PostHog::ENV_API_KEY); @@ -96,6 +108,14 @@ public static function initNoOpApiKeyCases(): array ]; } + public static function captureGroupsCases(): array + { + return [ + 'groups key' => ["groups"], + '$groups key' => ['$groups'], + ]; + } + public static function disabledClientNoRequestCases(): array { return [ @@ -499,6 +519,27 @@ public function testCapture(): void ); } + /** + * @dataProvider captureGroupsCases + */ + public function testCaptureAddsGroupsProperty(string $groupsKey): void + { + self::assertTrue( + PostHog::capture( + array( + "distinctId" => "john", + "event" => "grouped event", + $groupsKey => array("team" => 1), + ) + ) + ); + PostHog::flush(); + + $event = $this->firstBatchEvent(); + + self::assertSame(array("team" => 1), $event["properties"]['$groups']); + } + public function testCaptureFlushesOnNextEnqueueAfterDefaultFlushInterval(): void { $mockClock = new MockClock(new \DateTimeImmutable('2022-05-01 00:00:00'));