-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
christian
committed
Mar 24, 2023
0 parents
commit 4266d41
Showing
12 changed files
with
390 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
.idea | ||
.phpunit.cache | ||
build | ||
composer.lock | ||
coverage | ||
docs | ||
node_modules | ||
phpstan.neon | ||
phpunit.xml | ||
testbench.yaml | ||
vendor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Changelog | ||
|
||
## 24-03-2023 | ||
|
||
Initial release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# Laravel Posthog implementation | ||
|
||
--- | ||
This package provides a simple integration of Posthog in Laravel applications. | ||
|
||
The small package covers both Identify as Capture (events) requests which can be triggered manual or automatically using an Event Listener. | ||
|
||
This package uses the [PostHog / posthog-php](https://github.com/PostHog/posthog-php) package. For more information about Posthog, check their [documentation](https://posthog.com/docs). | ||
|
||
## Installation | ||
|
||
You can install the package via composer: | ||
|
||
```bash | ||
composer require qodenl/laravel-posthog | ||
``` | ||
|
||
You can publish the config file with: | ||
|
||
```bash | ||
php artisan vendor:publish --provider="QodeNL\LaravelPosthog\PosthogServiceProvider" | ||
``` | ||
|
||
After publishing the content, set your API key and Host in your .env file: | ||
|
||
```bash | ||
POSTHOG_KEY= | ||
POSTHOG_HOST=https://posthog.com | ||
POSTHOG_ENABLED=true | ||
``` | ||
|
||
Make sure you copy the correct host from Posthog. | ||
|
||
Posthog is enabled by default, but you can disable it with the POSTHOG_ENABLED env variable. | ||
|
||
Make sure to disable Posthog for local/testing environments. | ||
|
||
## Usage | ||
|
||
### Manual events | ||
|
||
```php | ||
use QodeNL\LaravelPosthog\Facades\Posthog; | ||
|
||
Posthog::capture('event name', ['property' => 'value']); | ||
``` | ||
|
||
### Automatic events | ||
|
||
You can add the `PosthogListener::class` listener to your `EventServiceProvider`. The package will create an capture automatically when the event happens. | ||
|
||
By default, all `fillable` attributes from a model (available in the event) will be sent to Posthog as properties. | ||
|
||
You can specify which attributes you want to send to Posthog by adding a `PosthogAttributes` property to your Model. | ||
|
||
```php | ||
public $posthogAttributes = [ | ||
'first_name', | ||
'last_name', | ||
]; | ||
``` | ||
|
||
Attributes in the `hidden` property will always be ignored. | ||
|
||
### Identify | ||
|
||
Events will be sent to Posthog with a unique ID for anonymous users. When the user is recognized (usually on log in), | ||
you should trigger the `identify` method to link the unique ID to the user. | ||
|
||
You can pass additional information about the user to be stored in his profile. | ||
|
||
```php | ||
use QodeNL\LaravelPosthog\Facades\Posthog; | ||
|
||
Posthog::identify('email@user.com', ['first_name' => 'John', 'last_name' => 'Doe']); | ||
``` | ||
|
||
### Queue / jobs | ||
|
||
All above actions will be executed by jobs. Be sure you've enabled and configured [queues](https://laravel.com/docs/10.x/queues) for your applications. | ||
|
||
## Changelog | ||
|
||
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. | ||
|
||
## Credits | ||
|
||
- Christian Schoenmakers (Qode BV - Netherlands) (https://github.com/christianschoenmakers) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"name": "qodenl/laravel-posthog", | ||
"description": "Laravel implementation for Posthog", | ||
"autoload": { | ||
"psr-4": { | ||
"QodeNL\\LaravelPosthog\\": "src/" | ||
} | ||
}, | ||
"authors": [ | ||
{ | ||
"name": "Christian Schoenmakers", | ||
"email": "info@qode.io" | ||
} | ||
], | ||
"keywords": [ | ||
"posthog", | ||
"laravel" | ||
], | ||
"require": { | ||
"php": "^8.0", | ||
"illuminate/support": "^9.0|^10.0", | ||
"posthog/posthog-php": "^3.0" | ||
}, | ||
"require-dev": { | ||
"roave/security-advisories": "dev-latest" | ||
}, | ||
"extra": { | ||
"laravel": { | ||
"providers": [ | ||
"QodeNL\\LaravelPosthog\\PosthogServiceProvider" | ||
], | ||
"aliases": { | ||
"Posthog": "QodeNL\\LaravelPosthog\\Facades\\Posthog" | ||
} | ||
} | ||
}, | ||
"minimum-stability": "dev", | ||
"prefer-stable": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<?php | ||
|
||
return [ | ||
'enabled' => env('POSTHOG_ENABLED', true), | ||
'key' => env('POSTHOG_KEY', ''), | ||
'host' => env('POSTHOG_HOST', 'https://app.posthog.com'), | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
namespace QodeNL\LaravelPosthog\Facades; | ||
|
||
use Illuminate\Support\Facades\Facade; | ||
|
||
class Posthog extends Facade | ||
{ | ||
protected static function getFacadeAccessor() | ||
{ | ||
return 'LaravelPosthog'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
namespace QodeNL\LaravelPosthog\Jobs; | ||
|
||
use Exception; | ||
use Illuminate\Support\Facades\Log; | ||
use PostHog\PostHog; | ||
|
||
class PosthogBaseJob | ||
{ | ||
public function init(): void | ||
{ | ||
try { | ||
PostHog::init(config('posthog.key'), | ||
['host' => config('posthog.host')] | ||
); | ||
} catch (Exception $e) { | ||
Log::error('Posthog initialization failed: ' . $e->getMessage()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
|
||
namespace QodeNL\LaravelPosthog\Jobs; | ||
|
||
use Exception; | ||
use Illuminate\Contracts\Queue\ShouldQueue; | ||
use Illuminate\Bus\Queueable; | ||
use Illuminate\Foundation\Bus\Dispatchable; | ||
use Illuminate\Queue\InteractsWithQueue; | ||
use Illuminate\Queue\SerializesModels; | ||
use Illuminate\Support\Facades\Log; | ||
use PostHog\PostHog; | ||
|
||
class PosthogCaptureJob extends PosthogBaseJob implements ShouldQueue | ||
{ | ||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | ||
|
||
public function __construct(private string $sessionId, private string $event, private array $properties = []) | ||
{ | ||
} | ||
|
||
public function handle(): void | ||
{ | ||
$this->init(); | ||
|
||
try { | ||
Posthog::capture([ | ||
'distinctId' => $this->sessionId, | ||
'event' => $this->event, | ||
'properties' => $this->properties, | ||
]); | ||
} catch (Exception $e) { | ||
Log::info('Posthog capture call failed:' . $e->getMessage()); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
namespace QodeNL\LaravelPosthog\Jobs; | ||
|
||
use Exception; | ||
use Illuminate\Contracts\Queue\ShouldQueue; | ||
use Illuminate\Bus\Queueable; | ||
use Illuminate\Foundation\Bus\Dispatchable; | ||
use Illuminate\Queue\InteractsWithQueue; | ||
use Illuminate\Queue\SerializesModels; | ||
use Illuminate\Support\Facades\Log; | ||
use PostHog\PostHog; | ||
|
||
class PosthogIdentifyJob extends PosthogBaseJob implements ShouldQueue | ||
{ | ||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | ||
|
||
public function __construct(private string $sessionId, private string $email, private array $properties = []) | ||
{ | ||
} | ||
|
||
public function handle(): void | ||
{ | ||
$this->init(); | ||
|
||
try { | ||
Posthog::identify([ | ||
'distinctId' => $this->sessionId, | ||
'properties' => ['email' => $this->email] + $this->properties, | ||
]); | ||
} catch (Exception $e) { | ||
Log::info('Posthog identify call failed:' . $e->getMessage()); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
namespace QodeNL\LaravelPosthog; | ||
|
||
use Log; | ||
use QodeNL\LaravelPosthog\Jobs\PosthogCaptureJob; | ||
use QodeNL\LaravelPosthog\Jobs\PosthogIdentifyJob; | ||
|
||
class LaravelPosthog | ||
{ | ||
|
||
protected string $sessionId; | ||
|
||
public function __construct() | ||
{ | ||
$this->sessionId = sha1(session()->getId()); | ||
} | ||
|
||
private function posthogEnabled(): bool | ||
{ | ||
if (!config('posthog.enabled')) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
public function identify(string $email, array $properties = []): void | ||
{ | ||
if ($this->posthogEnabled()) { | ||
PosthogIdentifyJob::dispatch($this->sessionId, $email, $properties); | ||
} else { | ||
Log::debug('PosthogIdentifyJob not dispatched because posthog is disabled'); | ||
} | ||
} | ||
|
||
public function capture(string $event, array $properties = []): void | ||
{ | ||
if ($this->posthogEnabled()) { | ||
PosthogCaptureJob::dispatch($this->sessionId, $event, $properties); | ||
} else { | ||
Log::debug('PosthogCaptureJob not dispatched because posthog is disabled'); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
|
||
namespace QodeNL\LaravelPosthog\Listeners; | ||
|
||
use Illuminate\Database\Eloquent\Model; | ||
use QodeNL\LaravelPosthog\LaravelPosthog; | ||
use ReflectionClass; | ||
use ReflectionNamedType; | ||
|
||
class PosthogListener | ||
{ | ||
public function handle($event): void | ||
{ | ||
$eventParameters = []; | ||
|
||
$reflectionClass = new ReflectionClass(get_class($event)); | ||
$reflectionClassProps = $reflectionClass->getConstructor()->getParameters(); | ||
|
||
if (is_array($reflectionClassProps) && count($reflectionClassProps) > 0) { | ||
foreach ($reflectionClassProps as $property) { | ||
|
||
$parameterName = $property->getName(); | ||
|
||
$classType = $property->getType(); | ||
if (!$classType instanceof ReflectionNamedType) { | ||
continue; | ||
} | ||
|
||
$className = $classType->getName(); | ||
|
||
if (!$className) { | ||
continue; | ||
} | ||
$class = new $className(); | ||
|
||
if (!$class || !is_subclass_of($class, Model::class)) { | ||
continue; | ||
} | ||
|
||
$modelAttributes = collect(); | ||
if (property_exists($class, 'posthogAttributes')) { | ||
$modelAttributes = collect($class->posthogAttributes); | ||
} elseif (method_exists($class, 'getFillable')) { | ||
$modelAttributes = collect($class->getFillable()); | ||
} | ||
|
||
if (method_exists($class, 'getHidden')) { | ||
$hidden = collect($class->getHidden()); | ||
$modelAttributes = $modelAttributes->diff($hidden); | ||
} | ||
|
||
if ($modelAttributes->count() > 0) { | ||
$eventParameters[$parameterName] = $event->$parameterName->only($modelAttributes->toArray()) ?? []; | ||
} | ||
} | ||
} | ||
|
||
$posthog = new LaravelPosthog(); | ||
$posthog->capture( | ||
get_class($event), | ||
$eventParameters | ||
); | ||
|
||
} | ||
} |
Oops, something went wrong.