From 711e0c2402a0278c7577645fff23e9a80db20cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nu=C5=A1a=20Puk=C5=A1i=C4=8D?= Date: Sun, 12 Oct 2025 20:20:37 +0200 Subject: [PATCH] Analytics, continued --- config/packages/security.yaml | 1 + .../VisitorAnalyticsController.php | 61 ++++++------ src/Security/CustomAccessDeniedHandler.php | 32 +++++++ templates/admin/analytics.html.twig | 94 +++++++++---------- .../TwigBundle/Exception/error403.html.twig | 10 ++ 5 files changed, 120 insertions(+), 78 deletions(-) create mode 100644 src/Security/CustomAccessDeniedHandler.php create mode 100644 templates/bundles/TwigBundle/Exception/error403.html.twig diff --git a/config/packages/security.yaml b/config/packages/security.yaml index b66c7bc..8264202 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -17,6 +17,7 @@ security: logout: path: /logout entry_point: App\Security\NostrAuthenticator + access_denied_handler: App\Security\CustomAccessDeniedHandler # activate different ways to authenticate # https://symfony.com/doc/current/security.html#the-firewall diff --git a/src/Controller/Administration/VisitorAnalyticsController.php b/src/Controller/Administration/VisitorAnalyticsController.php index 37520ab..29f263d 100644 --- a/src/Controller/Administration/VisitorAnalyticsController.php +++ b/src/Controller/Administration/VisitorAnalyticsController.php @@ -17,32 +17,32 @@ class VisitorAnalyticsController extends AbstractController public function index(VisitRepository $visitRepository): Response { // Counters for the last 24 hours and last 7 days - $last24h = new \DateTimeImmutable('-24 hours'); - $last7d = new \DateTimeImmutable('-7 days'); + $visitsLast24Hours = $visitRepository->countVisitsSince(new \DateTimeImmutable('-24 hours')); + $visitsLast7Days = $visitRepository->countVisitsSince(new \DateTimeImmutable('-7 days')); - $visitStats = $visitRepository->getVisitCountByRoute($last7d); + // Visits by route for the last 7 days + $routeVisitCountsLast7Days = $visitRepository->getVisitCountByRoute(new \DateTimeImmutable('-7 days')); - $last24hCount = $visitRepository->countVisitsSince($last24h); - $last7dCount = $visitRepository->countVisitsSince($last7d); - - // Unique session tracking - $uniqueVisitors24h = $visitRepository->countUniqueSessionsSince($last24h); - $uniqueVisitors7d = $visitRepository->countUniqueSessionsSince($last7d); + // Unique visitors + $uniqueVisitorsLast24Hours = $visitRepository->countUniqueSessionsSince(new \DateTimeImmutable('-24 hours')); + $uniqueVisitorsLast7Days = $visitRepository->countUniqueSessionsSince(new \DateTimeImmutable('-7 days')); $totalUniqueVisitors = $visitRepository->countUniqueVisitors(); - // Session-based visit breakdown - $sessionStats = $visitRepository->getVisitsBySession($last7d); + // Visits by session for the last 7 days + $visitsBySessionLast7Days = $visitRepository->getVisitsBySession(new \DateTimeImmutable('-7 days')); - // New metrics for improved dashboard + // Summary metrics $totalVisits = $visitRepository->getTotalVisits(); - $avgVisitsPerSession = $visitRepository->getAverageVisitsPerSession(); + $averageVisitsPerSession = $visitRepository->getAverageVisitsPerSession(); $bounceRate = $visitRepository->getBounceRate(); - $visitsPerDay = $visitRepository->getVisitsPerDay(30); - $mostPopularRoutes = $visitRepository->getMostPopularRoutes(5); - $recentVisits = $visitRepository->getRecentVisits(10); - // Calculate unique visitors per day for the last 7 days - $uniqueVisitorsPerDay = []; + // Time series and top metrics + $dailyVisitCountsLast30Days = $visitRepository->getVisitsPerDay(30); + $topRoutesAllTime = $visitRepository->getMostPopularRoutes(5); + $recentVisitRecords = $visitRepository->getRecentVisits(10); + + // Unique visitors per day for the last 7 days + $dailyUniqueVisitorCountsLast7Days = []; for ($i = 6; $i >= 0; $i--) { $day = (new \DateTimeImmutable("today"))->modify("-{$i} days"); $start = $day->setTime(0, 0, 0); @@ -54,28 +54,27 @@ class VisitorAnalyticsController extends AbstractController ->setParameter('start', $start) ->setParameter('end', $end); $count = (int) $qb->getQuery()->getSingleScalarResult(); - $uniqueVisitorsPerDay[] = [ + $dailyUniqueVisitorCountsLast7Days[] = [ 'day' => $day->format('Y-m-d'), 'count' => $count ]; } return $this->render('admin/analytics.html.twig', [ - 'visitStats' => $visitStats, - 'last24hCount' => $last24hCount, - 'last7dCount' => $last7dCount, - 'uniqueVisitors24h' => $uniqueVisitors24h, - 'uniqueVisitors7d' => $uniqueVisitors7d, + 'routeVisitCountsLast7Days' => $routeVisitCountsLast7Days, + 'visitsLast24Hours' => $visitsLast24Hours, + 'visitsLast7Days' => $visitsLast7Days, + 'uniqueVisitorsLast24Hours' => $uniqueVisitorsLast24Hours, + 'uniqueVisitorsLast7Days' => $uniqueVisitorsLast7Days, 'totalUniqueVisitors' => $totalUniqueVisitors, - 'sessionStats' => $sessionStats, - // New variables for dashboard + 'visitsBySessionLast7Days' => $visitsBySessionLast7Days, 'totalVisits' => $totalVisits, - 'avgVisitsPerSession' => $avgVisitsPerSession, + 'averageVisitsPerSession' => $averageVisitsPerSession, 'bounceRate' => $bounceRate, - 'visitsPerDay' => $visitsPerDay, - 'mostPopularRoutes' => $mostPopularRoutes, - 'recentVisits' => $recentVisits, - 'uniqueVisitorsPerDay' => $uniqueVisitorsPerDay, + 'dailyVisitCountsLast30Days' => $dailyVisitCountsLast30Days, + 'topRoutesAllTime' => $topRoutesAllTime, + 'recentVisitRecords' => $recentVisitRecords, + 'dailyUniqueVisitorCountsLast7Days' => $dailyUniqueVisitorCountsLast7Days, ]); } } diff --git a/src/Security/CustomAccessDeniedHandler.php b/src/Security/CustomAccessDeniedHandler.php new file mode 100644 index 0000000..e624b18 --- /dev/null +++ b/src/Security/CustomAccessDeniedHandler.php @@ -0,0 +1,32 @@ +twig = $twig; + $this->router = $router; + } + + public function handle(Request $request, \Exception $accessDeniedException): ?Response + { + // If not logged in, redirect to login + if (!$request->getUser()) { + return new RedirectResponse($this->router->generate('app_login')); + } + // Otherwise, render a custom error page + $content = $this->twig->render('bundles/TwigBundle/Exception/error403.html.twig'); + return new Response($content, 403); + } +} diff --git a/templates/admin/analytics.html.twig b/templates/admin/analytics.html.twig index c42c02a..d8e16f5 100644 --- a/templates/admin/analytics.html.twig +++ b/templates/admin/analytics.html.twig @@ -10,8 +10,8 @@

Total Visits

@@ -19,58 +19,58 @@

Unique Visitors

Tracked by session ID (includes both anonymous and logged-in visitors)

+
+

Unique Visitors Per Day (Last 7 Days)

+ + +
+ + + + + + + + + {% for stat in dailyUniqueVisitorCountsLast7Days %} + + + + + {% endfor %} + +
DateUnique Visitors
{{ stat.day }}{{ stat.count }}
+
+

Engagement

-
-

Unique Visitors Per Day (Last 7 Days)

- - -
- - - - - - - - - {% for stat in uniqueVisitorsPerDay %} - - - - - {% endfor %} - -
DateUnique Visitors
{{ stat.day }}{{ stat.count }}
-
-

Visits Per Day (Last 30 Days)

- {% if visitsPerDay|length > 0 %} + {% if dailyVisitCountsLast30Days|length > 0 %}