Passed
Branch master (95c350)
by Matt
05:17
created

AdminController::buildPeriodicChart()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
eloc 17
nc 1
nop 2
dl 0
loc 30
rs 9.7
c 1
b 1
f 0
1
<?php
2
3
namespace App\Controller\Admin;
4
5
use App\Repository\ImageRepository;
6
use App\Repository\WanderRepository;
7
use App\Service\StatsService;
8
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Component\Routing\Annotation\Route;
12
use Symfony\Contracts\Cache\TagAwareCacheInterface;
13
use Symfony\UX\Chartjs\Builder\ChartBuilderInterface;
14
use Symfony\UX\Chartjs\Model\Chart;
15
16
/**
17
 * @Route("/admin", name="admin_")
18
 */
19
class AdminController extends AbstractController
20
{
21
    /**
22
     * @Route("/", name="index")
23
     */
24
    public function index(
25
        StatsService $statsService,
26
        ChartBuilderInterface $chartBuilder
27
    ): Response {
28
        $wanderStats = $statsService->getWanderStats();
29
        $imageStats = $statsService->getImageStats();
30
31
        $monthlyChart = $this->buildPeriodicChart($wanderStats['monthlyStats'], $chartBuilder);
32
        $yearlyChart = $this->buildPeriodicChart($wanderStats['yearlyStats'], $chartBuilder);
33
34
        return $this->render('admin/index.html.twig', [
35
            'imageStats' => $imageStats,
36
            'wanderStats' => $wanderStats,
37
            'monthlyChart' => $monthlyChart,
38
            'yearlyChart' => $yearlyChart
39
        ]);
40
    }
41
42
    /**
43
     * Builds the data for a periodic Chartjs stats chart, e.g. wanders/distance/etc per month or year.
44
     *
45
     * @return Chart
46
     * @param array<string, mixed> $periodicStats
47
     * @param ChartBuilderInterface $chartBuilder
48
     */
49
    private function buildPeriodicChart(
50
        array $periodicStats,
51
        ChartBuilderInterface $chartBuilder
52
    ): Chart {
53
        $chart = $chartBuilder->createChart(Chart::TYPE_BAR);
54
        $chart->setData([
55
            'labels' => array_map(fn($dp): string => $dp['periodLabel'], $periodicStats),
56
            'datasets' => [
57
                // TODO: These colours should be defined in CSS. Add class somehow?
58
                [
59
                    'label' => 'Number of Wanders',
60
                    'backgroundColor' => '#ff66b2',
61
                    'borderColor' => 'black',
62
                    'data' => array_map(fn($dp): int => $dp['numberOfWanders'], $periodicStats),
63
                ],
64
                [
65
                    'label' => 'Distance Walked (km)',
66
                    'backgroundColor' => '#66ffff',
67
                    'borderColor' => 'black',
68
                    'data' => array_map(fn($dp): string => number_format($dp['totalDistance'] / 1000.0, 2), $periodicStats),
69
                ],
70
                [
71
                    'label' => 'Photos Taken',
72
                    'backgroundColor' => '#ffb266',
73
                    'borderColor' => 'black',
74
                    'data' => array_map(fn($dp): int => $dp['numberOfImages'], $periodicStats),
75
                ]
76
            ]
77
        ]);
78
        return $chart;
79
    }
80
81
    /**
82
     * @Route("/clearStatsCache", name="clear_stats_cache")
83
     */
84
    public function clearStatsCache(Request $request, TagAwareCacheInterface $cache): Response
85
    {
86
        if ($this->isCsrfTokenValid('admin_clear_stats_cache', (string) $request->request->get('_token'))) {
87
            $cache->invalidateTags(['stats']);
88
            $this->addFlash(
89
                'notice',
90
                'Stats Cache Cleared.'
91
            );
92
        } else {
93
            $this->addFlash(
94
                'error',
95
                'Stats not cleared. Invalid Csrf token.'
96
            );
97
        }
98
        return $this->redirectToRoute('admin_index');
99
    }
100
}