Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Ab Laravel Package

filipe07/laravel-ab

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require filipe07/laravel-ab
    php artisan vendor:publish --provider="AbTesting\AbTestingServiceProvider"
    php artisan migrate
    
    • Verify migrations (ab_experiments, ab_goals) are created.
  2. First Experiment Setup:

    • Define an experiment in config/abtesting.php:
      'experiments' => [
          'logo' => [
              'variants' => ['logo-big', 'logo-grayscale', 'brand-name'],
              'default' => 'logo-big',
          ],
      ],
      
    • Publish the config if needed to customize further.
  3. First Use Case:

    • In a Blade view, check variants:
      @if (AbTesting::isVariant('logo-big'))
          <div class="logo-big"></div>
      @endif
      
    • Trigger a goal (e.g., in a controller):
      AbTesting::trackGoal('logo_click', $userId);
      

Implementation Patterns

Core Workflows

  1. Experiment Creation:

    • Define experiments in config/abtesting.php with variants and defaults.
    • Dynamically add experiments via code (extend AbTestingServiceProvider):
      AbTesting::addExperiment('header', ['variant1', 'variant2'], 'variant1');
      
  2. Variant Assignment:

    • Use AbTesting::getVariant($experimentName) to fetch the assigned variant for a user (persistent via cookie or session).
    • Example: Route-based experiments:
      route('home')->where('variant', '[A-Za-z0-9_-]+')->middleware(function ($request, $next) {
          AbTesting::setVariant('homepage', $request->variant);
          return $next($request);
      });
      
  3. Goal Tracking:

    • Track conversions in controllers or Blade:
      // Controller
      AbTesting::trackGoal('purchase', auth()->id());
      
      // Blade (e.g., for link clicks)
      <a href="{{ route('purchase') }}" onclick="AbTesting.trackGoal('add_to_cart', {{ auth()->id() }})">
      
  4. Reporting:

    • Fetch results via:
      $results = AbTesting::getExperimentResults('logo');
      // Returns: ['logo-big' => 42, 'logo-grayscale' => 58, ...]
      
    • Display in admin panels or dashboards.

Integration Tips

  • Blade Directives: Create a custom directive for cleaner syntax:

    Blade::directive('ab', function ($expression) {
        return "<?php if (AbTesting::isVariant({$expression})): ?>";
    });
    

    Usage:

    @ab('logo-big')
        <div class="logo-big"></div>
    @endab
    
  • Middleware for Forced Variants: Override variants for testing:

    public function handle($request, Closure $next) {
        AbTesting::forceVariant('logo', 'logo-grayscale');
        return $next($request);
    }
    
  • Database Seeding: Pre-populate experiments/results for testing:

    AbTesting::seedExperiment('logo', ['logo-big' => 100, 'logo-grayscale' => 0]);
    

Gotchas and Tips

Pitfalls

  1. Cookie/Session Persistence:

    • Variants are stored in cookies by default. Clear them for accurate testing:
      AbTesting::clearVariant('logo'); // Force re-randomization
      
    • Tip: Use AbTesting::useSessionStorage(true) in config to avoid cookie conflicts.
  2. Default Variant Fallback:

    • If no variant is assigned, the default from config is used. Ensure defaults are set:
      'experiments' => [
          'logo' => [
              'variants' => ['A', 'B'],
              'default' => 'A', // Required!
          ],
      ],
      
  3. Goal Tracking Granularity:

    • Track goals with user IDs (not just IP) to avoid duplicate counting:
      AbTesting::trackGoal('signup', auth()->id());
      
    • Gotcha: Anonymous users may skew results. Use null or a placeholder ID:
      AbTesting::trackGoal('view', $request->ip());
      
  4. Migration Conflicts:

    • If migrations fail, manually check for:
      • Duplicate table names (ab_experiments, ab_goals).
      • Database collation issues (use utf8mb4_unicode_ci for Laravel 8+).
  5. Performance:

    • Avoid calling AbTesting::getVariant() in loops or critical paths. Cache results:
      $variant = cache()->remember("ab_variant_{$experiment}", now()->addHours(1), fn() =>
          AbTesting::getVariant($experiment)
      );
      

Debugging

  • Variant Assignment: Log assigned variants to debug:

    \Log::debug('AB Variant', ['experiment' => 'logo', 'variant' => AbTesting::getVariant('logo')]);
    
    • Check cookies/session storage directly:
      \Log::debug('AB Cookie', ['variant' => request()->cookie('ab_logo')]);
      
  • Goal Tracking: Verify goals are recorded:

    $goals = \DB::table('ab_goals')->where('goal_name', 'purchase')->get();
    
  • Configuration: Validate config/abtesting.php:

    \Log::debug('AB Config', ['experiments' => config('abtesting.experiments')]);
    

Extension Points

  1. Custom Storage: Override storage engines (e.g., Redis) by binding a custom AbTesting\Contracts\Storage implementation:

    $this->app->bind(
        AbTesting\Contracts\Storage::class,
        AbTesting\Storage\RedisStorage::class
    );
    
  2. Event Listeners: Extend functionality via events (e.g., AbTesting\Events\VariantAssigned):

    event(new \AbTesting\Events\VariantAssigned($experiment, $variant));
    
  3. Custom Reports: Query the ab_goals table directly for advanced analytics:

    $results = \DB::table('ab_goals')
        ->where('experiment', 'logo')
        ->groupBy('variant')
        ->get();
    
  4. Multi-Tenant Support: Scope experiments to tenants by overriding the getUserIdentifier() method in a custom storage class:

    public function getUserIdentifier(): string
    {
        return auth()->user()->tenant_id . '_' . auth()->id();
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle