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

Storyteller Bundle Laravel Package

captjm/storyteller-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require captjm/storyteller-bundle
    

    Register the bundle in config/app.php under extra.bundles:

    Captjm\StorytellerBundle\StorytellerBundle::class => ['all' => true],
    
  2. Basic Configuration Publish the default config:

    php artisan vendor:publish --provider="Captjm\StorytellerBundle\StorytellerBundle" --tag="config"
    

    Update config/storyteller.php with your preferred storage (e.g., database, filesystem, or s3).

  3. First Use Case: Logging a Story Inject the Storyteller service into a controller or command:

    use Captjm\StorytellerBundle\Storyteller;
    
    public function __construct(private Storyteller $storyteller) {}
    
    public function logStory()
    {
        $this->storyteller->story('user_registration', [
            'user_id' => 123,
            'ip' => request()->ip(),
        ]);
    }
    

Implementation Patterns

Workflow: Structured Event Logging

  1. Define Story Types Use consistent naming conventions (e.g., user_*., order_*.) for categorization.

    $this->storyteller->story('order_placed', ['order_id' => 456, 'amount' => 99.99]);
    
  2. Tagging for Filtering Attach metadata for later querying:

    $this->storyteller->story('payment_failed', [
        'user_id' => 123,
        'tags' => ['fraud_check', 'stripe'],
    ]);
    
  3. Integration with Laravel Events Dispatch events and log stories in listeners:

    public function handle(UserRegistered $event)
    {
        $this->storyteller->story('user_registered', [
            'user_id' => $event->user->id,
            'email' => $event->user->email,
        ]);
    }
    

Storage Strategies

  • Database: Useful for querying historical data.
    config(['storyteller.driver' => 'database']);
    
  • Filesystem: Lightweight, ideal for analytics.
    config(['storyteller.driver' => 'filesystem', 'path' => storage_path('logs/stories')]);
    
  • S3: Scalable for large-scale applications.
    config([
        'storyteller.driver' => 's3',
        'bucket' => 'your-bucket',
        'prefix' => 'stories',
    ]);
    

Retrieving Stories

Query stories via the Storyteller facade or service:

// Get all stories for a user
$stories = $this->storyteller->getStories(['user_id' => 123]);

// Filter by type and date range
$stories = $this->storyteller->getStories([
    'type' => 'order_*',
    'from' => now()->subDays(7),
    'to' => now(),
]);

Gotchas and Tips

Pitfalls

  1. Storage Permissions

    • Ensure the configured storage path (e.g., storage_path('logs/stories')) is writable.
    • For S3, verify AWS credentials and bucket permissions.
  2. Database Schema Mismatch

    • If using the database driver, run migrations:
      php artisan migrate
      
    • Customize the migration if extending the schema (e.g., adding metadata column).
  3. Performance with High Volume

    • Batch writes for bulk operations to avoid excessive I/O:
      $this->storyteller->batch(function () {
          $this->storyteller->story('event_a', [...]);
          $this->storyteller->story('event_b', [...]);
      });
      

Debugging

  • Check Storage Verify stories are being written to the expected location (e.g., storage/logs/stories/ or database table storyteller_stories).

  • Logging Errors Enable debug mode in config/storyteller.php:

    'debug' => env('APP_DEBUG', false),
    

    Errors will appear in Laravel’s log.

Extension Points

  1. Custom Drivers Extend the Captjm\StorytellerBundle\Contracts\Driver interface to support new storage backends (e.g., Elasticsearch).

  2. Story Validation Add validation rules via a service provider:

    Storyteller::extend(function ($story) {
        if (empty($story['user_id'])) {
            throw new \InvalidArgumentException('User ID is required.');
        }
    });
    
  3. Event Dispatching Trigger Laravel events when stories are logged:

    Storyteller::extend(function ($story) {
        event(new StoryLogged($story));
    });
    

Configuration Quirks

  • Default Driver If no driver is configured, the bundle defaults to filesystem with storage_path('logs/stories').

  • Serialization Story data is serialized using json_encode(). Ensure payloads are JSON-serializable (no resources or circular references).

Pro Tips

  • Use for Analytics Combine with Laravel’s analytics package to track user journeys:

    $this->storyteller->story('product_viewed', [
        'user_id' => auth()->id(),
        'product_id' => $product->id,
    ]);
    
  • Cleanup Old Stories Add a scheduled task to purge old stories (e.g., older than 6 months):

    // config/schedule.php
    $schedule->command('storyteller:prune')->daily();
    
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.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime