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

Eloquent Viewable Laravel Package

cyrildewit/eloquent-viewable

Track page views on Eloquent models without third-party analytics. Record and count total or unique views, filter by date periods, order models by views, apply cooldowns, and optionally ignore crawlers. Stores each view as a DB record for flexible querying.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Seamless Eloquent Integration: The package leverages Laravel’s Eloquent ORM, making it a natural fit for applications already using Eloquent models. It extends functionality without requiring architectural overhauls.
  • Minimalist Design: The package avoids heavy dependencies (e.g., no third-party analytics services) and focuses on core view-tracking logic, aligning with Laravel’s "batteries-included" philosophy.
  • Database-Centric: Stores views in a dedicated table, enabling granular queries (e.g., time-based, unique, or cooldown-based counts). This is ideal for applications requiring precise analytics without external services.

Integration Feasibility

  • Laravel 6+ Compatibility: Supports modern Laravel versions (6.x–13.x) and PHP 7.4+, ensuring compatibility with most active Laravel projects.
  • Migration-First Approach: Publishes migrations and config files, simplifying adoption. The Viewable interface and InteractsWithViews trait enforce consistency across models.
  • Helper-First API: The views() helper method provides fluent syntax (e.g., views($post)->record()), reducing boilerplate and improving developer experience.

Technical Risk

  • Database Growth: Stores individual view records, which can bloat the database for high-traffic applications. Mitigation requires indexing (viewable_id, viewable_type, optionally visitor) and caching strategies.
  • Session Dependency: Cooldowns rely on session storage, which may not work for stateless APIs or distributed systems. Workarounds include custom visitor tracking (e.g., IP + User-Agent hashing).
  • Caching Complexity: Dynamic periods (e.g., Period::subHours(6)) complicate caching. The remember() method helps but requires manual cache invalidation for real-time updates.
  • Crawler Detection: Default crawler filtering (via CrawlerDetect) may misclassify legitimate traffic (e.g., Postman). Customization is possible via CrawlerDetectAdapter.

Key Questions

  1. Scalability Needs:
    • How will the application handle database growth? Are read replicas or archiving strategies needed?
    • Should views be aggregated (e.g., hourly/daily counts) to reduce row count?
  2. Real-Time Requirements:
    • Can cached view counts tolerate stale data (e.g., 5-minute refresh intervals)?
    • Are there use cases requiring sub-second latency for view counts?
  3. Visitor Uniqueness:
    • How should "unique views" be defined (e.g., IP + session, user account, or cookie-based)?
    • Will the application support anonymous vs. authenticated users differently?
  4. Extensibility:
    • Are there plans to customize the View or Visitor models (e.g., adding metadata like device type)?
    • Will the package need to integrate with other analytics tools (e.g., exporting to Google Analytics)?

Integration Approach

Stack Fit

  • Laravel Ecosystem: Optimized for Laravel applications using Eloquent. Works alongside Laravel’s caching (Redis/Memcached), queues, and scheduling systems.
  • PHP 7.4+: Leverages modern PHP features (e.g., typed properties, named arguments) for performance and maintainability.
  • Database Agnostic: Compatible with MySQL, PostgreSQL, SQLite, etc., via Eloquent’s database abstraction.

Migration Path

  1. Installation:
    • Composer install (composer require cyrildewit/eloquent-viewable).
    • Publish migrations and config (php artisan vendor:publish).
    • Run migrations (php artisan migrate).
  2. Model Preparation:
    • Implement Viewable interface and InteractsWithViews trait in target models (e.g., Post, Article).
    • Example:
      class Post extends Model implements Viewable {
          use InteractsWithViews;
          protected $removeViewsOnDelete = true; // Optional
      }
      
  3. View Recording:
    • Integrate views($model)->record() in controllers or middleware (e.g., ShowPost controller).
    • Example:
      public function show(Post $post) {
          views($post)->cooldown(now()->addHours(1))->record();
          return view('post.show', compact('post'));
      }
      
  4. Query Integration:
    • Replace manual view counts with fluent queries (e.g., views($post)->period(Period::pastWeek())->count()).
    • Add scopes to models for ordering (e.g., Post::orderByViews()->get()).

Compatibility

  • Laravel Services: Works with Laravel’s caching (remember()), queues (for batch processing), and scheduling (for periodic view aggregation).
  • Third-Party Tools: Can coexist with Google Analytics or other tools by treating this as a complementary data source.
  • Testing: Includes CI/CD workflows (GitHub Actions) and code coverage (Codecov), ensuring reliability.

Sequencing

  1. Phase 1: Core Integration
    • Implement in a non-critical model (e.g., BlogPost).
    • Test view recording and basic queries (count(), unique()).
  2. Phase 2: Advanced Features
    • Add cooldowns, periods, and collections for specific use cases.
    • Implement caching for high-traffic endpoints.
  3. Phase 3: Optimization
    • Add database indexes and consider view aggregation (e.g., hourly counts).
    • Set up scheduled jobs to update cached counts or clean old data.
  4. Phase 4: Monitoring
    • Track database growth and query performance.
    • Adjust caching strategies based on real-world usage.

Operational Impact

Maintenance

  • Dependencies: Minimal (Laravel core, no external services). Updates align with Laravel’s release cycle.
  • Configuration: Centralized via published config file (e.g., crawler detection, default cooldowns).
  • Extensibility: Supports custom View, Visitor, and CrawlerDetectAdapter classes for tailored behavior.

Support

  • Documentation: Comprehensive README with examples, API references, and optimization tips.
  • Community: Active GitHub repo (883 stars, recent updates) and Packagist metrics (38K+ downloads).
  • Debugging: Logs view recording and queries for troubleshooting (e.g., crawler filtering, cooldowns).

Scaling

  • Database:
    • Indexing: Critical for performance. Add indexes on viewable_id, viewable_type, and visitor (if tracking uniqueness).
    • Archiving: Implement a cron job to archive old views (e.g., retain only the last 2 years).
    • Read Replicas: Offload read-heavy queries (e.g., orderByViews) to replicas.
  • Caching:
    • Use Redis/Memcached for remember() to reduce database load.
    • Cache aggregated counts (e.g., daily views) separately from raw records.
  • Batch Processing:
    • Use Laravel queues to process views asynchronously (e.g., for analytics reports).

Failure Modes

Failure Scenario Impact Mitigation
Database downtime View recording fails Queue views and retry on recovery.
Cache failure Stale view counts Short TTL (e.g., 5 minutes) or fallback to DB.
Session storage issues Cooldowns fail Fallback to IP/User-Agent hashing.
High traffic spikes Database overload Rate-limiting, read replicas, or aggregation.
Crawler misclassification False positives/negatives Customize CrawlerDetectAdapter.

Ramp-Up

  • Developer Onboarding:
    • Time Estimate: 1–2 hours to integrate into a single model.
    • Key Tasks:
      1. Install and publish assets.
      2. Add Viewable trait to a model.
      3. Record views in the show() method.
      4. Test queries (count(), period(), unique()).
  • Performance Tuning:
    • Initial Setup: Add indexes and enable caching for critical endpoints.
    • Ongoing: Monitor query performance (e.g., EXPLAIN ANALYZE) and adjust TTLs.
  • Team Adoption:
    • Best Practices:
      • Standardize view recording (e.g., middleware for global tracking).
      • Document cooldown rules per model type.
      • Use collections for multi-purpose views (e.g., "editorial" vs. "user-generated").
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
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
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