Browse Source

Some more analytics

imwald
Nuša Pukšič 2 months ago
parent
commit
e1af005803
  1. 4
      src/Controller/Administration/VisitorAnalyticsController.php
  2. 5
      src/EventListener/VisitTrackingListener.php
  3. 36
      src/Repository/VisitRepository.php
  4. 14
      templates/admin/analytics.html.twig

4
src/Controller/Administration/VisitorAnalyticsController.php

@ -63,6 +63,9 @@ class VisitorAnalyticsController extends AbstractController
]; ];
} }
// Article publish statistics
$articlePublishStats = $visitRepository->getArticlePublishStats();
return $this->render('admin/analytics.html.twig', [ return $this->render('admin/analytics.html.twig', [
'routeVisitCountsLast7Days' => $routeVisitCountsLast7Days, 'routeVisitCountsLast7Days' => $routeVisitCountsLast7Days,
'visitsLast24Hours' => $visitsLast24Hours, 'visitsLast24Hours' => $visitsLast24Hours,
@ -79,6 +82,7 @@ class VisitorAnalyticsController extends AbstractController
'recentVisitRecords' => $recentVisitRecords, 'recentVisitRecords' => $recentVisitRecords,
'dailyUniqueVisitorCountsLast7Days' => $dailyUniqueVisitorCountsLast7Days, 'dailyUniqueVisitorCountsLast7Days' => $dailyUniqueVisitorCountsLast7Days,
'topArticlesLast24Hours' => $topArticlesLast24Hours, 'topArticlesLast24Hours' => $topArticlesLast24Hours,
'articlePublishStats' => $articlePublishStats,
]); ]);
} }
} }

5
src/EventListener/VisitTrackingListener.php

@ -40,12 +40,17 @@ class VisitTrackingListener
$request = $event->getRequest(); $request = $event->getRequest();
$route = $request->getPathInfo(); $route = $request->getPathInfo();
// Exception: Always track article publish API calls
$isArticlePublish = str_starts_with($route, '/api/article/publish');
// Skip tracking for excluded routes (API, profiler, assets, etc.) // Skip tracking for excluded routes (API, profiler, assets, etc.)
if (!$isArticlePublish) {
foreach (self::EXCLUDED_ROUTES as $excludedRoute) { foreach (self::EXCLUDED_ROUTES as $excludedRoute) {
if (str_starts_with($route, $excludedRoute)) { if (str_starts_with($route, $excludedRoute)) {
return; return;
} }
} }
}
// Get session ID for all visitors (both logged-in and anonymous) // Get session ID for all visitors (both logged-in and anonymous)
$sessionId = null; $sessionId = null;

36
src/Repository/VisitRepository.php

@ -223,4 +223,40 @@ class VisitRepository extends ServiceEntityRepository
->setMaxResults($limit); ->setMaxResults($limit);
return $qb->getQuery()->getResult(); return $qb->getQuery()->getResult();
} }
/**
* Returns the number of times the article publish API was called since a given datetime.
*/
public function countArticlePublishSince(\DateTimeImmutable $since): int
{
$qb = $this->createQueryBuilder('v')
->select('COUNT(v.id)')
->where('v.route = :route')
->andWhere('v.visitedAt >= :since')
->setParameter('route', '/api/article/publish')
->setParameter('since', $since, \Doctrine\DBAL\Types\Types::DATETIME_IMMUTABLE);
return (int) $qb->getQuery()->getSingleScalarResult();
}
/**
* Returns article publish statistics for different time periods.
*/
public function getArticlePublishStats(): array
{
$qb = $this->createQueryBuilder('v')
->select('COUNT(v.id)')
->where('v.route = :route')
->setParameter('route', '/api/article/publish');
$allTime = (int) $qb->getQuery()->getSingleScalarResult();
return [
'last_hour' => $this->countArticlePublishSince(new \DateTimeImmutable('-1 hour')),
'last_24_hours' => $this->countArticlePublishSince(new \DateTimeImmutable('-24 hours')),
'last_7_days' => $this->countArticlePublishSince(new \DateTimeImmutable('-7 days')),
'last_30_days' => $this->countArticlePublishSince(new \DateTimeImmutable('-30 days')),
'all_time' => $allTime,
];
}
} }

14
templates/admin/analytics.html.twig

@ -6,6 +6,20 @@
<div class="analytics-container"> <div class="analytics-container">
<h1>Page Visit Analytics</h1> <h1>Page Visit Analytics</h1>
<div class="analytics-summary-row">
<div class="analytics-card">
<h2>Article Publish Activity</h2>
<ul class="analytics-stats">
<li><strong>Last hour:</strong> {{ articlePublishStats.last_hour|number_format }}</li>
<li><strong>Last 24 hours:</strong> {{ articlePublishStats.last_24_hours|number_format }}</li>
<li><strong>Last 7 days:</strong> {{ articlePublishStats.last_7_days|number_format }}</li>
<li><strong>Last 30 days:</strong> {{ articlePublishStats.last_30_days|number_format }}</li>
<li><strong>All time:</strong> {{ articlePublishStats.all_time|number_format }}</li>
</ul>
<p class="analytics-note">Number of times articles were published via the API endpoint</p>
</div>
</div>
<div class="analytics-summary-row"> <div class="analytics-summary-row">
<div class="analytics-card"> <div class="analytics-card">
<h2>Total Visits</h2> <h2>Total Visits</h2>

Loading…
Cancel
Save