From 3ec00c5d5418eb81fa059361bd6b2ec6390faeec Mon Sep 17 00:00:00 2001 From: "Martin S. Campos" Date: Thu, 1 Aug 2024 14:05:27 -0500 Subject: [PATCH 1/6] feat: add shouldTrackEvents property --- CHANGELOG.md | 4 +++ src/Contracts/AnalyticsTracker.php | 1 + src/Trackers/MixpanelTracker.php | 11 +++++- tests/Unit/Trackers/MixpanelTrackerTest.php | 38 +++++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e945a3..13f85e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add `shouldTrackEvents` property + ## [1.0.1] - 2024-04-26 ### Changed diff --git a/src/Contracts/AnalyticsTracker.php b/src/Contracts/AnalyticsTracker.php index 4c9fffe..db55a34 100644 --- a/src/Contracts/AnalyticsTracker.php +++ b/src/Contracts/AnalyticsTracker.php @@ -5,6 +5,7 @@ interface AnalyticsTracker { public function track(string $label, array $payload = []); + public function shouldTrackEvents(bool $shouldTrackEvents); public function setDefaultPayload(array $payload): self; diff --git a/src/Trackers/MixpanelTracker.php b/src/Trackers/MixpanelTracker.php index cb9feb3..db2f715 100644 --- a/src/Trackers/MixpanelTracker.php +++ b/src/Trackers/MixpanelTracker.php @@ -9,6 +9,7 @@ class MixpanelTracker implements AnalyticsTracker { private ?Mixpanel $mixpanel = null; private array $defaultPayload = []; + private bool $shouldTrackEvents = true; public function __construct() { @@ -26,7 +27,9 @@ public function __construct() public function track(string $label, array $payload = []): void { - $this->mixpanel?->track($label, array_merge($this->defaultPayload, $payload)); + if ($this->shouldTrackEvents) { + $this->mixpanel?->track($label, array_merge($this->defaultPayload, $payload)); + } } public function setDefaultPayload(array $payload): self @@ -35,6 +38,12 @@ public function setDefaultPayload(array $payload): self return $this; } + public function shouldTrackEvents(bool $shouldTrackEvents): self + { + $this->shouldTrackEvents = $shouldTrackEvents; + return $this; + } + private function enabled(): bool { return config('analytics-tracker.mixpanel.enabled'); diff --git a/tests/Unit/Trackers/MixpanelTrackerTest.php b/tests/Unit/Trackers/MixpanelTrackerTest.php index aea864f..6f40e99 100644 --- a/tests/Unit/Trackers/MixpanelTrackerTest.php +++ b/tests/Unit/Trackers/MixpanelTrackerTest.php @@ -101,6 +101,44 @@ public function it_does_not_track_when_disabled(): void $mixpanelTracker->track($label); } + /** + * @test + */ + public function it_does_not_track_when_should_not_track_events(): void + { + $label = $this->faker->word(); + + $mixpanelMock = $this->createMock(Mixpanel::class); + $mixpanelMock->expects($this->never()) + ->method('track') + ->with($label); + $this->app->offsetSet(Mixpanel::class, $mixpanelMock); + + $mixpanelTracker = new MixpanelTracker(); + $mixpanelTracker + ->shouldTrackEvents(false) + ->track($label); + } + + /** + * @test + */ + public function it_can_tracks_when_should_track_events(): void + { + $label = $this->faker->word(); + + $mixpanelMock = $this->createMock(Mixpanel::class); + $mixpanelMock->expects($this->once()) + ->method('track') + ->with($label); + $this->app->offsetSet(Mixpanel::class, $mixpanelMock); + + $mixpanelTracker = new MixpanelTracker(); + $mixpanelTracker + ->shouldTrackEvents(true) + ->track($label); + } + /** * @test */ From 09dd3b292730c4e2434aa7c4d802ba91f15c3d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Guzm=C3=A1n=20H=2E?= Date: Thu, 1 Aug 2024 15:25:40 -0500 Subject: [PATCH 2/6] Changes implementation to be a closure --- src/Contracts/AnalyticsTracker.php | 1 - src/Trackers/MixpanelTracker.php | 16 ++++-- tests/Unit/Trackers/MixpanelTrackerTest.php | 59 +++++++++++++++------ 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/Contracts/AnalyticsTracker.php b/src/Contracts/AnalyticsTracker.php index db55a34..4c9fffe 100644 --- a/src/Contracts/AnalyticsTracker.php +++ b/src/Contracts/AnalyticsTracker.php @@ -5,7 +5,6 @@ interface AnalyticsTracker { public function track(string $label, array $payload = []); - public function shouldTrackEvents(bool $shouldTrackEvents); public function setDefaultPayload(array $payload): self; diff --git a/src/Trackers/MixpanelTracker.php b/src/Trackers/MixpanelTracker.php index db2f715..2a237e1 100644 --- a/src/Trackers/MixpanelTracker.php +++ b/src/Trackers/MixpanelTracker.php @@ -2,6 +2,7 @@ namespace Placetopay\AnalyticsTracker\Trackers; +use Closure; use Mixpanel; use Placetopay\AnalyticsTracker\Contracts\AnalyticsTracker; @@ -9,7 +10,7 @@ class MixpanelTracker implements AnalyticsTracker { private ?Mixpanel $mixpanel = null; private array $defaultPayload = []; - private bool $shouldTrackEvents = true; + private ?Closure $shouldTrackEvents = null; public function __construct() { @@ -27,20 +28,27 @@ public function __construct() public function track(string $label, array $payload = []): void { - if ($this->shouldTrackEvents) { + if ($this->shouldTrack($label, $payload)) { $this->mixpanel?->track($label, array_merge($this->defaultPayload, $payload)); } } + private function shouldTrack(string $label, array $payload = []) + { + return is_callable($this->shouldTrackEvents) + ? ($this->shouldTrackEvents)($label, $payload) + : true; + } + public function setDefaultPayload(array $payload): self { $this->defaultPayload = $payload; return $this; } - public function shouldTrackEvents(bool $shouldTrackEvents): self + public function shouldTrackEvents(callable $shouldTrackEvents): self { - $this->shouldTrackEvents = $shouldTrackEvents; + $this->shouldTrackEvents = Closure::fromCallable($shouldTrackEvents); return $this; } diff --git a/tests/Unit/Trackers/MixpanelTrackerTest.php b/tests/Unit/Trackers/MixpanelTrackerTest.php index 6f40e99..290093c 100644 --- a/tests/Unit/Trackers/MixpanelTrackerTest.php +++ b/tests/Unit/Trackers/MixpanelTrackerTest.php @@ -104,39 +104,64 @@ public function it_does_not_track_when_disabled(): void /** * @test */ - public function it_does_not_track_when_should_not_track_events(): void + public function it_decides_to_track_events_with_function(): void { - $label = $this->faker->word(); - $mixpanelMock = $this->createMock(Mixpanel::class); - $mixpanelMock->expects($this->never()) + $mixpanelMock->expects($this->once()) ->method('track') - ->with($label); + ->with('EventTracked', ['prop1' => 'value1']); + $this->app->offsetSet(Mixpanel::class, $mixpanelMock); - $mixpanelTracker = new MixpanelTracker(); - $mixpanelTracker - ->shouldTrackEvents(false) - ->track($label); + $shouldTrackEvent = function (string $label, array $payload) { + $this->assertArrayHasKey('prop1', $payload); + + return $label === 'EventTracked'; + }; + + $mixpanelTracker = (new MixpanelTracker())->shouldTrackEvents($shouldTrackEvent); + $mixpanelTracker->track('EventDropped', ['prop1' => 'value1']); + $mixpanelTracker->track('EventTracked', ['prop1' => 'value1']); } /** * @test */ - public function it_can_tracks_when_should_track_events(): void + public function it_decides_to_track_events_with_an_invokable(): void { - $label = $this->faker->word(); - $mixpanelMock = $this->createMock(Mixpanel::class); $mixpanelMock->expects($this->once()) ->method('track') - ->with($label); + ->with('EventTracked', ['prop1' => 'value1']); + $this->app->offsetSet(Mixpanel::class, $mixpanelMock); - $mixpanelTracker = new MixpanelTracker(); - $mixpanelTracker - ->shouldTrackEvents(true) - ->track($label); + $shouldTrackEvent = new class { + public function __invoke(string $label, array $payload) + { + return $label === 'EventTracked'; + } + }; + + $mixpanelTracker = (new MixpanelTracker())->shouldTrackEvents($shouldTrackEvent); + $mixpanelTracker->track('EventDropped', ['prop1' => 'value1']); + $mixpanelTracker->track('EventTracked', ['prop1' => 'value1']); + } + + /** + * @test + */ + public function it_does_not_track_when_should_not_track_events(): void + { + $mixpanelMock = $this->createMock(Mixpanel::class); + $mixpanelMock->expects($this->never()) + ->method('track') + ->with('EventDropped', ['prop1' => 'value1']); + + $this->app->offsetSet(Mixpanel::class, $mixpanelMock); + + $mixpanelTracker = (new MixpanelTracker())->shouldTrackEvents(fn () => false); + $mixpanelTracker->track('EventDropped', ['prop1' => 'value1']); } /** From c47c4a0cb980bb047281575401222f57ef00ac67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Guzm=C3=A1n=20H=2E?= Date: Fri, 2 Aug 2024 09:37:30 -0500 Subject: [PATCH 3/6] Adds method to AnalyticsTracker contract --- src/Contracts/AnalyticsTracker.php | 2 ++ src/Trackers/MixpanelTracker.php | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Contracts/AnalyticsTracker.php b/src/Contracts/AnalyticsTracker.php index 4c9fffe..3faa79e 100644 --- a/src/Contracts/AnalyticsTracker.php +++ b/src/Contracts/AnalyticsTracker.php @@ -8,5 +8,7 @@ public function track(string $label, array $payload = []); public function setDefaultPayload(array $payload): self; + public function shouldTrackEvents(callable $shouldTrackEvents): self; + public function setIdentifier(string $identifier): self; } diff --git a/src/Trackers/MixpanelTracker.php b/src/Trackers/MixpanelTracker.php index 2a237e1..4ba173e 100644 --- a/src/Trackers/MixpanelTracker.php +++ b/src/Trackers/MixpanelTracker.php @@ -48,7 +48,8 @@ public function setDefaultPayload(array $payload): self public function shouldTrackEvents(callable $shouldTrackEvents): self { - $this->shouldTrackEvents = Closure::fromCallable($shouldTrackEvents); + $this->shouldTrackEvents = $shouldTrackEvents(...); + return $this; } From 8977584297fdb205da18b5bce8f912bce943d591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Guzm=C3=A1n=20H=2E?= Date: Fri, 2 Aug 2024 09:41:02 -0500 Subject: [PATCH 4/6] Update MixpanelTracker.php --- src/Trackers/MixpanelTracker.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Trackers/MixpanelTracker.php b/src/Trackers/MixpanelTracker.php index 4ba173e..5d8fba7 100644 --- a/src/Trackers/MixpanelTracker.php +++ b/src/Trackers/MixpanelTracker.php @@ -28,8 +28,12 @@ public function __construct() public function track(string $label, array $payload = []): void { + if ($this->mixpanel === null) { + return; + } + if ($this->shouldTrack($label, $payload)) { - $this->mixpanel?->track($label, array_merge($this->defaultPayload, $payload)); + $this->mixpanel->track($label, array_merge($this->defaultPayload, $payload)); } } From ad6faa12624a87cf5e30e0146218a9a0ab4727fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Guzm=C3=A1n=20H=2E?= Date: Fri, 2 Aug 2024 10:25:49 -0500 Subject: [PATCH 5/6] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13f85e1..b7791f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.1.0] - 2024-08-02 + ### Added - Add `shouldTrackEvents` property From 3b7e9d1a4114ad6504d2c349927e158708c68ed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Guzm=C3=A1n=20H=2E?= Date: Fri, 2 Aug 2024 10:49:01 -0500 Subject: [PATCH 6/6] Updates docs --- CHANGELOG.md | 2 +- README.md | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7791f3..f47fdbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Add `shouldTrackEvents` property +- Add `shouldTrackEvents` method to `AnalyticsTracker` contract. ## [1.0.1] - 2024-04-26 diff --git a/README.md b/README.md index 212c538..26c11af 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,24 @@ Add the following variables to your .env: use Placetopay\AnalyticsTracker\Facades\Analytics; Analytics::setIdentifier("user@company.com") // (optional) Associate a user to the tracked events -->setDefaultPayload(['key' => 'value']) // Set the default data to be sent on every track call -->track('Label', ['key' => 'value']); // Tracks an event + ->setDefaultPayload(['key' => 'value']) // Set the default data to be sent on every track call + ->track('Label', ['key' => 'value']); // Tracks an event +``` + +## Conditional tracking + +You may call the `shouldTrackEvents` method to define a condition for when to track events. The method receives a callback that should return a boolean value. + +```php +use Placetopay\AnalyticsTracker\Facades\Analytics; + +Analytics::setIdentifier("user@company.com") + ->shouldTrackEvents(fn($label, $payload) => $payload['siteId'] === '1234') + ->track('Label', ['siteId' => '5678']); + + +Analytics::setIdentifier("user@company.com") + ->shouldTrackEvents(new InvokableClass()) // May use an Invokable class + ->track('Label', ['siteId' => '5678']); + ``` \ No newline at end of file