Lines 100.00% 23 / 23
Methods 100.00% 3 / 3
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 __invoke 100.00% 17 / 17 100.00% 1 / 1 8
 agent 100.00% 4 / 4 100.00% 1 / 1 3
 timelineCounts 100.00% 2 / 2 100.00% 1 / 1 2
31final class Read extends BaseController
32{
33    public function __invoke(
34        string $agentName,
35        UserRepository $userRepository,
36        AgentStatRepository $agentStatRepository,
37        TimelineEventRepository $timelineEventRepository,
38        MedalChecker $medalChecker,
39        TimelineBuilder $timelineBuilder,
40        DoneBannerRepository $doneBannerRepository,
41    ): Response {
42        $agent = $this->agent($agentName, $userRepository);
43        $stats = $agentStatRepository->findByOwner($agent);
44        $latest = $stats[0] ?? null;
45        $showLatestStats = $latest instanceof AgentStat && $agent->isVisible(ProfilePart::LATEST_STATS);
46        $showHistory = $agent->isVisible(ProfilePart::STATS_HISTORY);
47
48        return $this->render('agent/show.html.twig', [
49            'agent' => $agent,
50            'latest' => $latest,
51            // The first import tells about the history: only with it
52            'first' => $showHistory ? \array_last($stats) : null,
53            'timelineCounts' => $showHistory ? $this->timelineCounts($agent, $stats, $timelineEventRepository, $doneBannerRepository, $timelineBuilder) : null,
54            'showLatestStats' => $showLatestStats,
55            'medals' => $showLatestStats ? $medalChecker->medalLevels($latest) : [],
56            'coreBadges' => $showLatestStats ? $medalChecker->coreBadges($latest->getStats()['months_subscribed'] ?? 0) : [],
57            'customMedals' => $agent->isVisible(ProfilePart::CUSTOM_MEDALS) ? $medalChecker->customMedalTiers($agent->getCustomMedals()) : null,
58            'bannergress' => $agent->isVisible(ProfilePart::BANNERGRESS) ? Bannergress::fromStored($agent->getBannergress()) : null,
59            'isOwn' => $agent->id === $this->getUser()->id,
60        ]);
61    }
62
63    /** The agent, 404 when there is none with the name or the agent part is private. */
64    private function agent(string $agentName, UserRepository $userRepository): User
65    {
66        $agent = $userRepository->findOneByAgentName($agentName);
67        if (!$agent instanceof User || !$agent->isVisible(ProfilePart::AGENT)) {
68            throw $this->createNotFoundException('No agent '.$agentName.' to show.');
69        }
70
71        return $agent;
72    }
73
74    /**
75     * The number of timeline entries of each kind, for the summary.
76     *
77     * @param list<AgentStat> $stats newest first
78     *
79     * @return array<string, int> by kind
80     */
81    private function timelineCounts(
82        User $agent,
83        array $stats,
84        TimelineEventRepository $timelineEventRepository,
85        DoneBannerRepository $doneBannerRepository,
86        TimelineBuilder $timelineBuilder,
87    ): array {
88        // Banners are on the timeline only with the Bannergress part
89        $banners = $agent->isVisible(ProfilePart::BANNERGRESS) ? $doneBannerRepository->findDatedByOwner($agent) : [];
90
91        return TimelineEntry::counts($timelineBuilder->build($stats, $timelineEventRepository->findByOwner($agent), $banners));
92    }
93}