Skip to content

ziming/laravel-statsig

Repository files navigation

laravel-statsig

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Laravel Package for Statsig. A Feature Gate & A/B Testing Platform

Update: As of Aug/Sept 2023, Statsig has decided to cut lots of features from their free tier. Which also mean that if you have a problem with the paid tier features, I will not be able to help you anymore as I am not a paid tier user.

Support us

Donations are welcomed too as an alternative. Anything goes.

You can also let Stasig know that this package referred you there

Installation

You can install the package via composer:

composer require ziming/laravel-statsig

Add the following 2 commands to your laravel project app/Console/Kernel.php

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Ziming\LaravelStatsig\Commands\StatsigSendCommand;
use Ziming\LaravelStatsig\Commands\StatsigSyncCommand;

class Kernel extends ConsoleKernel
{
    /**
     * Define the application's command schedule.
     */
    protected function schedule(Schedule $schedule): void
    {
        // https://docs.statsig.com/server/phpSDK#sync
        $schedule->command(StatsigSyncCommand::class)->everyMinute();
        
        // https://docs.statsig.com/server/phpSDK#send
        $schedule->command(StatsigSendCommand::class)->everyMinute();
    }

You can publish the config file with:

php artisan vendor:publish --tag="statsig-config"

This is the contents of the published config file:

use Statsig\Adapters\LocalFileDataAdapter;
use Statsig\Adapters\LocalFileLoggingAdapter;

return [
    'secret' => env('STATSIG_SECRET_KEY'),

    'data_adapter' => LocalFileDataAdapter::class,
    
    // arguments to the Data Adapter class constructor
    'data_adapter_arguments' => [
        // '/tmp/statsig/', // empty array for the default directory for the default Data Adapter
    ],

    'logging_adapter' => LocalFileLoggingAdapter::class,
    
    // arguments to the Logging Adapter class constructor
    'logging_adapter_arguments' => [
        // '/tmp/statsig.logs', // empty array for the default file path for the default Logging Adapter
    ],
];

Usage

use Illuminate\Support\Facades\App;
use Illuminate\Foundation\Auth\User;
use Illuminate\Support\Facades\Auth;
use Statsig\StatsigUser;
use Ziming\LaravelStatsig\Facades\LaravelStatsig;
use Ziming\LaravelStatsig\LaravelStatsigEvent;
use Ziming\LaravelStatsig\LaravelStatsigUserConfiguration;

$laravelStatsig = new Ziming\LaravelStatsig();
$user = Auth::user();
$laravelStatsig->checkGate($user, 'gate_name');

// The Facade Version is fine too
LaravelStatsig::checkGate($user, 'gate_name');

// You can set add this to 1 of your ServiceProviders boot() method to
// override the default laravel user to Statsig user conversion code too if you want
LaravelStatsigUserConfiguration::setConversionCallable(function (User $laravelUser): StatsigUser {
        $statsigUser = StatsigUser::withUserID((string) $laravelUser->getAuthIdentifier());
        $statsigUser->setEmail($laravelUser->getEmailForVerification());
        $statsigUser->setIP(request()->ip());
        $statsigUser->setLocale(App::currentLocale());
        $statsigUser->setUserAgent(request()->userAgent());
        
        // $statsigUser->setCountry('US');
        
        return $statsigUser;
});

// Lastly you can also use LaravelStatsigEvent instead of StatsigEvent
// as it accepts a laravel user object
// See Useful References at the end of the read me for some best practices to follow for events naming conventions

$statsigEvent = new LaravelStatsigEvent('event_name');

// Giving it a value is optional
$statsigEvent->setValue('string-or-float-or-int-or-whatever-primitive-type');

// Extra event metadata is optional too. See the official Statsig docs on how many you can send
$statsigEvent->setMetadata([
    'key' => 'value' 
]);

// You can also use this convenience method
LaravelStatsig::logEventWithAuthUser($statsigEvent);

// or this
$statsigEvent->setUser(Auth::user());
$laravelStatsig->logEvent($statsigEvent);

A handy blade directive is also provided to check against Statsig Feature Gates in your frontend blade templates

It is confusingly named in all lowercase to match the official laravel naming conventions for blade directives.

@statsigcheckgate('gate_name')
    <p>This is shown if this statsig gate return true for the authenticated user</p>
@endstatsigcheckgate

@statsigcheckgate('gate_name', 'user-identifier')
    <p>This is usually used for guest user but can be ur authenticated user identifier too</p>
@endstatsigcheckgate

@statsigcheckgate('gate_name', $user)
    <p>$user can be a StatsigUser or a laravel user instance</p>
@endstatsigcheckgate

Lastly, a helper function is also provided if you want to be even more concise in your blade templates. It is named in snake case, following laravel naming conventions for global helper functions.

Like the blade directive, currently it can only be used if the user is logged in.

<div class="{{ statsig_check_gate('gate_name') ? 'border-red' : '' }}">
The Authenticated user will be used to check if it passes this gate
</div>

<div class="{{ statsig_check_gate('gate_name', 'user-identifier') ? 'border-red' : '' }}">
This is usually used for guest user but can be ur authenticated user identifier too
</div>

<div class="{{ statsig_check_gate('gate_name', $user) ? 'border-red' : '' }}">
Use this is you want to pass in a statsig user or laravel user instance
</div>

Testing

No tests currently, feel free to PR

composer test

Useful References

Below are links to some good reads that I think would benefit you in getting started:

Experimentation

Event Naming Best Practices

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.