Browse Source

Analytics

imwald
Nuša Pukšič 3 months ago
parent
commit
7d00d90335
  1. 4
      src/Controller/Administration/VisitorAnalyticsController.php
  2. 19
      src/Repository/VisitRepository.php
  3. 24
      templates/admin/analytics.html.twig

4
src/Controller/Administration/VisitorAnalyticsController.php

@ -20,6 +20,9 @@ class VisitorAnalyticsController extends AbstractController
$visitsLast24Hours = $visitRepository->countVisitsSince(new \DateTimeImmutable('-24 hours')); $visitsLast24Hours = $visitRepository->countVisitsSince(new \DateTimeImmutable('-24 hours'));
$visitsLast7Days = $visitRepository->countVisitsSince(new \DateTimeImmutable('-7 days')); $visitsLast7Days = $visitRepository->countVisitsSince(new \DateTimeImmutable('-7 days'));
// Most read articles in the last 24 hrs
$topArticlesLast24Hours = $visitRepository->getMostVisitedArticlesSince(new \DateTimeImmutable('-24 hours'), 5);
// Visits by route for the last 7 days // Visits by route for the last 7 days
$routeVisitCountsLast7Days = $visitRepository->getVisitCountByRoute(new \DateTimeImmutable('-7 days')); $routeVisitCountsLast7Days = $visitRepository->getVisitCountByRoute(new \DateTimeImmutable('-7 days'));
@ -75,6 +78,7 @@ class VisitorAnalyticsController extends AbstractController
'topRoutesAllTime' => $topRoutesAllTime, 'topRoutesAllTime' => $topRoutesAllTime,
'recentVisitRecords' => $recentVisitRecords, 'recentVisitRecords' => $recentVisitRecords,
'dailyUniqueVisitorCountsLast7Days' => $dailyUniqueVisitorCountsLast7Days, 'dailyUniqueVisitorCountsLast7Days' => $dailyUniqueVisitorCountsLast7Days,
'topArticlesLast24Hours' => $topArticlesLast24Hours,
]); ]);
} }
} }

19
src/Repository/VisitRepository.php

@ -204,4 +204,23 @@ class VisitRepository extends ServiceEntityRepository
} }
return round(($singleVisitSessions / $totalSessions) * 100, 2); return round(($singleVisitSessions / $totalSessions) * 100, 2);
} }
/**
* Returns the top N most visited articles since a given datetime.
* Only considers routes matching /article/d/{slug}.
* Returns array: [ 'route' => string, 'count' => int ]
*/
public function getMostVisitedArticlesSince(\DateTimeImmutable $since, int $limit = 5): array
{
$qb = $this->createQueryBuilder('v')
->select('v.route, COUNT(v.id) as count')
->where('v.visitedAt >= :since')
->andWhere('v.route LIKE :articlePath')
->setParameter('since', $since, \Doctrine\DBAL\Types\Types::DATETIME_IMMUTABLE)
->setParameter('articlePath', '/article/d/%')
->groupBy('v.route')
->orderBy('count', 'DESC')
->setMaxResults($limit);
return $qb->getQuery()->getResult();
}
} }

24
templates/admin/analytics.html.twig

@ -64,6 +64,30 @@
</div> </div>
</div> </div>
<div class="analytics-card">
<h2>Top 5 Visited Articles (Last 24 Hours)</h2>
{% if topArticlesLast24Hours|length > 0 %}
<table class="analytics-table">
<thead>
<tr>
<th>Article Path</th>
<th class="text-right">Visits</th>
</tr>
</thead>
<tbody>
{% for stat in topArticlesLast24Hours %}
<tr>
<td><a href="{{ stat.route }}" target="_blank">{{ stat.route }}</a></td>
<td class="text-right">{{ stat.count }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No article visits recorded in the last 24 hours.</p>
{% endif %}
</div>
<div class="analytics-card"> <div class="analytics-card">
<h2>Visits Per Day (Last 30 Days)</h2> <h2>Visits Per Day (Last 30 Days)</h2>
{% if dailyVisitCountsLast30Days|length > 0 %} {% if dailyVisitCountsLast30Days|length > 0 %}

Loading…
Cancel
Save