cengizhancaliskan/views-counter-bundle
Installation
composer require cengizhancaliskan/views-counter-bundle
Add to config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3):
Cengizhan\ViewsCounterBundle\CengizhanViewsCounterBundle::class => ['all' => true],
Annotate an Entity
Implement VisitableInterface and use VisitableEntityTrait:
use Cengizhan\ViewsCounterBundle\Model\VisitableInterface;
use Cengizhan\ViewsCounterBundle\Traits\VisitableEntityTrait;
class Article implements VisitableInterface
{
use VisitableEntityTrait;
// ...
}
First Use Case Increment views in a controller:
$this->get('views_counter.views_counter')->count($article);
View Tracking
Call count() in your controller after rendering the view (e.g., in showAction):
public function show(Article $article)
{
return $this->render('article/show.html.twig', ['article' => $article]);
// Then increment:
$this->get('views_counter.views_counter')->count($article);
}
Event-Based Integration
Use Symfony events to automate counting (e.g., kernel.view):
# config/services.yaml
services:
App\EventListener\ViewCounterListener:
tags:
- { name: kernel.event_listener, event: kernel.view, method: onKernelView }
// src/EventListener/ViewCounterListener.php
public function onKernelView(GetResponseForControllerResultEvent $event)
{
$controller = $event->getController();
if (is_array($controller) && $controller[0] instanceof ArticleController) {
$article = $controller[1]->getArticle(); // Adjust based on your logic
$this->get('views_counter.views_counter')->count($article);
}
}
Query Builder Integration Fetch top-viewed entities:
$topArticles = $this->getDoctrine()
->getRepository(Article::class)
->createQueryBuilder('a')
->orderBy('a.views', 'DESC')
->setMaxResults(5)
->getQuery()
->getResult();
VisitableEntityTrait methods (e.g., getViewsColumn()).$em = $this->getDoctrine()->getManager();
$articles = $em->getRepository(Article::class)->findAll();
foreach ($articles as $article) {
$article->incrementViews();
}
$em->flush();
Double Counting
count() multiple times in a single request (e.g., AJAX + page load).RequestStack to check for duplicates.Outdated ORM
IDENTITY strategy (deprecated in Doctrine 2.5+). Update to AUTO or SEQUENCE if needed.Performance
flush() calls on high-traffic pages.Archived Status
views column exists in your database table:
php bin/console doctrine:schema:validate
php bin/console debug:container views_counter.views_counter
$this->get('logger')->info('Incremented views for article ID: ' . $article->getId());
Custom Columns
Override getViewsColumn() in your entity to use a non-standard column name.
Conditional Counting
Extend the VisitableInterface to add logic (e.g., skip counting for admins):
public function shouldCountView(): bool
{
return !$this->isAdminView();
}
Alternative Storage
Replace the Doctrine-based counter with a Redis-backed solution by extending the ViewsCounter service.
Symfony 5+ Compatibility
Update composer.json to require ^5.0 and adjust autowiring if needed:
# config/services.yaml
Cengizhan\ViewsCounterBundle\ViewsCounter:
arguments:
$entityManager: '@doctrine.orm.entity_manager'
How can I help you explore Laravel packages today?