Weave 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

View Counter Bundle Laravel Package

tchoulom/view-counter-bundle

A Symfony bundle for counting and tracking page or entity views. It records each visit, stores statistics in Doctrine, and lets you display total view counts and popularity metrics with simple Twig helpers and configurable counters.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the bundle with Composer:
    composer require tchoulom/view-counter-bundle
    
  2. Register it in config/bundles.php if Symfony Flex does not do it automatically:
    Tchoulom\ViewCounterBundle\TchoulomViewCounterBundle::class => ['all' => true],
    
  3. Read the package README first, then inspect these files to understand the real API for your installed version:
    • DependencyInjection/Configuration.php — available config keys
    • Resources/config/services.yaml — service IDs and autowiring aliases
    • Entity/ — persistence model and required schema
    • Twig/ — helpers, if any
  4. Add the bundle configuration under config/packages/ and run Doctrine migrations if the bundle ships its own entity/table.
  5. First practical use case: count views on an article/product detail page. Inject the bundle’s counter service into the controller, call its count method for the displayed entity, and pass the resulting count to Twig.

If the README is thin, treat Configuration.php and services.yaml as the source of truth. Confirm the supported Symfony and Doctrine versions before wiring it into a real project.

Implementation Patterns

  • Explicit controller counting
    Count only on the detail action, not on every request:

    public function show(Article $article): Response
    {
        $this->viewCounter->count($article);
    
        return $this->render('article/show.html.twig', [
            'article' => $article,
            'views' => $this->viewCounter->getCount($article),
        ]);
    }
    

    Use the exact service ID/class from your installed version; older examples often reference a service like tchoulom.view_counter.

  • Automatic counting with an event subscriber
    For consistent behavior across many controllers, listen to kernel.controller or kernel.request, resolve the entity from route attributes, and count only for configured routes/entities. Keep an allowlist of routes to avoid counting admin, API, or asset requests.

  • Twig integration
    If the bundle provides a Twig extension, use it for display. Otherwise, pass the count from the controller. Avoid calling the counter service directly from templates because it hides write side effects inside rendering.

  • Duplicate-view protection
    Combine the bundle count with session, cookie, or cache checks:

    • session key per entity ID
    • short-lived cache key per IP/user agent
    • “count once per day” logic This is usually application-level behavior, not something the bundle handles for you.
  • Popular-content queries
    If the bundle stores counts in a Doctrine entity/table, query it from a repository or custom service for “most viewed” lists. Join back to your domain entity and cache the result for listing pages.

  • Admin dashboards
    Expose counts through a read-only service or repository. Keep dashboard queries separate from write-path counting so a slow report does not affect page rendering.

  • Asynchronous counting
    For high-traffic pages, dispatch a Symfony Messenger message from the controller and let a handler call the counter service. This keeps the page response fast and makes retries/debugging easier.

  • Testing
    In functional tests, disable automatic counting unless the test is specifically about views. Assert that one page view increments by one, and that repeat views follow your duplicate-protection rules.

Gotchas and Tips

  • Low adoption risk
    This package has very few stars and zero known dependents. Audit the code before production use, pin the version in composer.json, and be prepared to fork or replace it. Check compatibility with your Symfony, Doctrine, and PHP versions.

  • Service visibility and autowiring
    Older bundles often define private services without autowiring aliases. If injection fails, inspect services.yaml, use the explicit service ID, or add an alias in your app config.

  • Schema and migrations
    The bundle may ship entity mappings but not migrations. Generate and review migrations yourself. Verify table names, indexes on the counted entity, and whether counts are stored on your entity or in a separate table.

  • Double counting
    Browser prefetching, bots, refreshes, and AJAX partial renders can inflate counts. Count only on the final HTML detail response, exclude known bots, and add session/cache-based deduplication.

  • Doctrine flush timing
    If the counter mutates a managed entity, the count may be flushed later than expected or combined with other updates. Call the bundle’s persistence method deliberately and test inside transactions.

  • Concurrency
    Read-modify-write counters can lose increments under load. Prefer an atomic SQL increment or a dedicated counter table if accuracy matters. Treat the bundle’s default behavior as “best effort” until proven otherwise.

  • Configuration drift
    Config key names and bundle aliases can change between versions. Copy the exact YAML key from Configuration.php, not from a blog post. Clear cache after config changes:

    php bin/console cache:clear
    
  • Debugging
    Use debug:container to find the real service ID:

    php bin/console debug:container view_counter
    

    Use debug:router and Symfony Profiler to confirm which requests are being counted.

  • Extension points
    The safest extension points are usually:

    • a kernel event subscriber in your app for counting rules
    • a custom repository/service for reporting
    • a Twig extension in your app for display Avoid editing vendor code; wrap or decorate the bundle service instead.
  • Graceful degradation
    If counting fails, do not break the page. Wrap the counter call in a try/catch or move it to an async handler, and log the failure. A view counter should be non-critical infrastructure.

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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log