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

Visitor Laravel Package

shetabit/visitor

Track and log Laravel visitors: browser, platform, device, IP, languages, user agent, and request data. Use visitor() helper or $request->visitor(). Record visits for any model via Visitable trait, count views/unique visitors, and detect online users.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Installation:

    composer require shetabit/visitor
    php artisan vendor:publish --provider="Shetabit\Visitor\Provider\VisitorServiceProvider"
    php artisan migrate
    
    • For Laravel ≥5.5, no manual provider/alias registration is needed.
  2. First Use Case: Access visitor data in a controller:

    use Illuminate\Http\Request;
    
    public function show(Request $request) {
        $browser = $request->visitor()->browser(); // e.g., "Chrome"
        $ip = $request->visitor()->ip(); // e.g., "192.168.1.1"
    }
    

    Or globally via helper:

    $device = visitor()->device(); // e.g., "iPhone"
    
  3. Key Initial Steps:

    • Add LogVisits middleware to app/Http/Kernel.php for automatic logging.
    • Use Visitable trait on models to enable visit tracking:
      use Shetabit\Visitor\Traits\Visitable;
      
      class Post extends Model {
          use Visitable;
      }
      

Implementation Patterns

1. Visitor Data Access

  • Request-Based:
    $request->visitor()->browser(); // "Firefox"
    $request->visitor()->platform(); // "Windows"
    
  • Global Helper:
    visitor()->languages(); // ["en-US", "fr"]
    
  • User-Agent Parsing: Leverage built-in parsers (e.g., UAParser) without manual regex. Extend via service providers:
    // config/visitor.php
    'driver' => 'ua-parser', // or 'custom'
    

2. Visit Logging

  • Global Logs:
    visitor()->visit(); // Logs current request
    visitor()->visit($post); // Logs visit to a model
    
  • Model-Specific Logs:
    $post->createVisitLog(); // Logs via trait
    $post->createVisitLog($user); // Attributes to a user
    
  • Middleware Automation: Add LogVisits to routes/models to auto-log visits:
    Route::middleware(['web', 'logVisits'])->get('/posts/{post}', ...);
    

3. Online User Detection

  • Query Online Users:
    visitor()->onlineVisitors(User::class); // Collection of active users
    User::online()->get(); // Scoped query
    
  • Check User Status:
    visitor()->isOnline($user); // bool
    $user->isOnline(); // bool (via Visitor trait)
    

4. Analytics Workflows

  • Count Visits:
    $post->visitLogs()->count(); // Total visits
    $post->visitLogs()->distinct('ip')->count('ip'); // Unique IPs
    
  • Filter by Time:
    $post->visitLogs()->where('created_at', '>', now()->subDays(7))->count();
    
  • User-Specific Analytics:
    $user->visits()->where('model_type', Post::class)->count();
    

5. Customization

  • Extend Visitor Data: Add custom fields to logs via migrations or model observers:
    // app/Observers/VisitLogObserver.php
    public function saving($log) {
        $log->custom_field = request()->input('custom_field');
    }
    
  • Override Parsers: Implement Shetabit\Visitor\Contracts\VisitorDriver for custom logic (e.g., IP geolocation).

Gotchas and Tips

Pitfalls

  1. Middleware Placement:

    • Place LogVisits after auth middleware to avoid logging guest visits twice.
    • Exclude sensitive routes (e.g., /admin) by adding to config/visitor.php:
      'except' => [
          'admin/*',
          'api/auth/*',
      ],
      
  2. Bot Detection:

    • The package flags bots via isBot() (e.g., curl, Googlebot). Exclude them from analytics:
      if (!$request->visitor()->isBot()) {
          visitor()->visit($post);
      }
      
  3. Performance:

    • Avoid eager-loading visitLogs on models with high traffic (e.g., Post::with('visitLogs')->get()). Use lazy loading:
      $post->visitLogs()->count(); // Loads only count
      
    • Index ip and user_id in visit_logs table for large datasets:
      Schema::table('visit_logs', function (Blueprint $table) {
          $table->index('ip');
          $table->index('user_id');
      });
      
  4. User-Agent Parsing:

    • Default driver (ua-parser) may misclassify edge cases. Test with:
      $request->visitor()->useragent(); // Raw string for debugging
      
  5. Online User Logic:

    • Online status is determined by last activity (configurable in config/visitor.php):
      'online_timeout' => 300, // 5 minutes (seconds)
      
    • Race Conditions: Use transactions for critical operations (e.g., updating online status):
      DB::transaction(function () use ($user) {
          $user->update(['last_seen_at' => now()]);
      });
      

Debugging Tips

  1. Log Raw Data:
    \Log::info('Visitor data:', $request->visitor()->toArray());
    
  2. Check Migrations:
    • Ensure visit_logs table exists after php artisan migrate.
    • Verify user_id and model_type columns are present for polymorphic relations.
  3. Middleware Debugging:
    • Temporarily disable LogVisits to isolate issues:
      // app/Http/Kernel.php
      'logVisits' => false,
      

Extension Points

  1. Custom Visit Logs:

    • Extend Shetabit\Visitor\Models\VisitLog to add fields:
      php artisan make:model VisitLogExtension --extend=Shetabit\Visitor\Models\VisitLog
      
    • Publish and modify the migration:
      php artisan vendor:publish --tag=visitor-migrations
      
  2. Driver Customization:

    • Create a custom driver for advanced parsing (e.g., geolocation):
      class CustomDriver implements VisitorDriver {
          public function parse(Request $request) {
              return [
                  'ip' => $request->ip(),
                  'geo' => $this->getGeoData($request->ip()),
              ];
          }
      }
      
    • Register in config/visitor.php:
      'driver' => 'custom',
      
  3. Event Listeners:

    • Listen for visit events to trigger actions (e.g., notifications):
      VisitLog::created(function ($log) {
          if ($log->model_type === Post::class) {
              event(new PostViewed($log->model));
          }
      });
      

Configuration Quirks

  1. GeoIP Stub:

    • If using geoip driver, ensure stubs are published:
      php artisan vendor:publish --tag=visitor-config
      
    • Update config/visitor.php with your GeoIP database path.
  2. Polymorphic Relations:

    • Ensure models using Visitable have a visits() relation defined:
      public function visits() {
          return $this->morphMany(VisitLog::class, 'model');
      }
      
  3. Request Data Sanitization:

    • The package excludes sensitive fields (e.g., password) by default. Customize via:
      'exclude_request_fields' => ['api_token', 'secret_key'],
      

Pro Tips

  1. Segmented Analytics: Combine with Laravel Scout for real-time dashboards:
    $post->visits()->search('browser:Chrome')->count();
    
  2. A/B Testing: Track visitor attributes (e.g., visitor()->platform()) to segment tests:
    $platform = visitor()->platform();
    ABTest::record($platform, 'conversion_rate');
    
  3. Maintenance:
    • Schedule log cleanup:
      VisitLog::where('created_at', '<', now()->subYears(1))->delete();
      
    • Monitor visit_logs table size for large-scale apps (consider archiving).
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4
php-http/client-implementation
phpcr/phpcr-implementation
cucumber/gherkin-monorepo
haydenpierce/class-finder
psr/simple-cache-implementation