Lines 100.00% 14 / 14
Functions and Methods 100.00% 1 / 1
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
Timeline 100.00% 14 / 14 100.00% 1 / 1 5 100.00% 1 / 1
 __invoke 100.00% 14 / 14 100.00% 1 / 1 5
1<?php
2
3declare(strict_types=1);
4
5namespace App\Controller\Agent;
6
7use App\Controller\BaseController;
8use App\Entity\User;
9use App\Enum\ProfilePart;
10use App\Enum\UserRole;
11use App\Repository\AgentStatRepository;
12use App\Repository\DoneBannerRepository;
13use App\Repository\TimelineEventRepository;
14use App\Repository\UserRepository;
15use App\Timeline\TimelineBuilder;
16use App\Timeline\TimelineChart;
17use Symfony\Component\HttpFoundation\Request;
18use Symfony\Component\HttpFoundation\Response;
19use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
20use Symfony\Component\Routing\Attribute\Route;
21use Symfony\Component\Security\Http\Attribute\IsGranted;
22
23/**
24 * An agent's timeline, read-only, as the own one: the chart and every upload, custom event and
25 * (with the Bannergress part) banner done with a day; 404 without the agent and stats history
26 * parts. With from and to (Y-m-d) the chart is zoomed to those days; with chart=1 only the chart,
27 * for the date filter.
28 */
29#[Route('/agents/{agentName}/timeline', name: 'app_agent_timeline', requirements: ['agentName' => '[A-Za-z0-9_]{1,50}'], methods: ['GET'])]
30#[IsGranted(UserRole::USER->value)]
31final class Timeline extends BaseController
32{
33    public function __invoke(
34        string $agentName,
35        Request $request,
36        UserRepository $userRepository,
37        AgentStatRepository $agentStatRepository,
38        TimelineEventRepository $timelineEventRepository,
39        TimelineBuilder $timelineBuilder,
40        DoneBannerRepository $doneBannerRepository,
41        #[MapQueryParameter(filter: \FILTER_VALIDATE_REGEXP, options: ['regexp' => TimelineChart::DAY])]
42        ?string $from = null,
43        #[MapQueryParameter(filter: \FILTER_VALIDATE_REGEXP, options: ['regexp' => TimelineChart::DAY])]
44        ?string $to = null,
45        #[MapQueryParameter]
46        bool $chart = false,
47    ): Response {
48        $agent = $userRepository->findOneByAgentName($agentName);
49        if (!$agent instanceof User || !$agent->isVisible(ProfilePart::STATS_HISTORY)) {
50            throw $this->createNotFoundException('No timeline of '.$agentName.' to show.');
51        }
52
53        $stats = $agentStatRepository->findByOwner($agent);
54        $events = $timelineEventRepository->findByOwner($agent);
55        $timelineChart = TimelineChart::build($stats, $events, $request->getLocale(), TimelineChart::date($from), TimelineChart::date($to));
56
57        if ($chart) {
58            return $this->render('agent_stat/_timeline_chart_frame.html.twig', ['chart' => $timelineChart]);
59        }
60
61        // Banners only with the Bannergress part
62        $banners = $agent->isVisible(ProfilePart::BANNERGRESS) ? $doneBannerRepository->findDatedByOwner($agent) : [];
63
64        return $this->render('agent/timeline.html.twig', [
65            'agent' => $agent,
66            'timeline' => $timelineBuilder->build($stats, $events, $banners),
67            'chart' => $timelineChart,
68        ]);
69    }
70}