Lines
79.31%
46 / 58
Functions and Methods
83.33%
5 / 6
Classes and Traits
0.00%
0 / 1
| Name | Lines | Functions and Methods | CRAP | Classes and Traits | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| AgentProvider | 79.31% | 46 / 58 | 83.33% | 5 / 6 | 18.27 | 0.00% | 0 / 1 | |||
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| provide | 100.00% | 8 / 8 | 100.00% | 1 / 1 | 4 | |||||
| item | 100.00% | 19 / 19 | 100.00% | 1 / 1 | 8 | |||||
| doneBanners | 0.00% | 0 / 12 | 0.00% | 0 / 1 | 2 | |||||
| agent | 100.00% | 12 / 12 | 100.00% | 1 / 1 | 1 | |||||
| row | 100.00% | 6 / 6 | 100.00% | 1 / 1 | 1 | |||||
| 1 | <?php | |
| 2 | ||
| 3 | declare(strict_types=1); | |
| 4 | ||
| 5 | namespace App\State; | |
| 6 | ||
| 7 | use ApiPlatform\Metadata\CollectionOperationInterface; | |
| 8 | use ApiPlatform\Metadata\Operation; | |
| 9 | use ApiPlatform\State\ProviderInterface; | |
| 10 | use App\ApiResource\Agent; | |
| 11 | use App\ApiResource\Bannergress; | |
| 12 | use App\ApiResource\CustomMedals; | |
| 13 | use App\Dto\AgentStatInput; | |
| 14 | use App\Entity\AgentStat; | |
| 15 | use App\Entity\DoneBanner; | |
| 16 | use App\Entity\TimelineEvent; | |
| 17 | use App\Entity\User; | |
| 18 | use App\Enum\ProfilePart; | |
| 19 | use App\Repository\AgentStatRepository; | |
| 20 | use App\Repository\DoneBannerRepository; | |
| 21 | use App\Repository\TimelineEventRepository; | |
| 22 | use App\Repository\UserRepository; | |
| 23 | ||
| 24 | /** | |
| 25 | * GET /api/agents and /api/agents/{agentName}: the agents who show the agent part, with what | |
| 26 | * they show (as web's Agent controllers). | |
| 27 | * | |
| 28 | * @implements ProviderInterface<Agent> | |
| 29 | */ | |
| 30 | final readonly class AgentProvider implements ProviderInterface | |
| 31 | { | |
| 32 | public function __construct( | |
| 33 | private UserRepository $userRepository, | |
| 34 | private AgentStatRepository $agentStatRepository, | |
| 35 | private TimelineEventRepository $timelineEventRepository, | |
| 36 | private DoneBannerRepository $doneBannerRepository, | |
| 37 | ) { | |
| 38 | } | |
| 39 | ||
| 40 | /** | |
| 41 | * @return list<Agent>|Agent|null | |
| 42 | */ | |
| 43 | public function provide(Operation $operation, array $uriVariables = [], array $context = []): array|Agent|null | |
| 44 | { | |
| 45 | if ($operation instanceof CollectionOperationInterface) { | |
| 46 | $users = $this->userRepository->findVisibleAgents(); | |
| 47 | $latest = $this->agentStatRepository->findLatestByOwners($users); | |
| 48 | ||
| 49 | return \array_values(\array_map(fn (User $user): Agent => $this->agent($user, $latest[(int) $user->id] ?? null), $users)); | |
| 50 | } | |
| 51 | ||
| 52 | $user = $this->userRepository->findOneByAgentName((string) ($uriVariables['agentName'] ?? '')); | |
| 53 | if (!$user instanceof User || !$user->isVisible(ProfilePart::AGENT)) { | |
| 54 | return null; | |
| 55 | } | |
| 56 | ||
| 57 | return $this->item($user); | |
| 58 | } | |
| 59 | ||
| 60 | /** An agent with the parts they show. */ | |
| 61 | private function item(User $user): Agent | |
| 62 | { | |
| 63 | $stats = $this->agentStatRepository->findByOwner($user); | |
| 64 | $showHistory = $user->isVisible(ProfilePart::STATS_HISTORY); | |
| 65 | ||
| 66 | return $this->agent( | |
| 67 | $user, | |
| 68 | $stats[0] ?? null, | |
| 69 | $user->isVisible(ProfilePart::LATEST_STATS) && isset($stats[0]) ? $this->row($stats[0]) : null, | |
| 70 | $showHistory ? \array_map($this->row(...), $stats) : null, | |
| 71 | $showHistory ? \array_map( | |
| 72 | static fn (TimelineEvent $event): array => [ | |
| 73 | 'date' => $event->date?->format(TimelineEvent::DATE_FORMAT) ?? '', | |
| 74 | 'endDate' => $event->endDate?->format(TimelineEvent::DATE_FORMAT), | |
| 75 | 'text' => $event->text, | |
| 76 | ], | |
| 77 | $this->timelineEventRepository->findByOwner($user), | |
| 78 | ) : null, | |
| 79 | $user->isVisible(ProfilePart::CUSTOM_MEDALS) ? CustomMedals::fromArray($user->getCustomMedals()) : null, | |
| 80 | $user->isVisible(ProfilePart::BANNERGRESS) ? Bannergress::fromStored($user->getBannergress()) : null, | |
| 81 | $user->isVisible(ProfilePart::BANNERGRESS) ? $this->doneBanners($user) : null, | |
| 82 | ); | |
| 83 | } | |
| 84 | ||
| 85 | /** | |
| 86 | * @return list<array{bannerId: string, title: string, missions: int, picture: string|null, startLatitude: float|null, startLongitude: float|null, doneAt: string|null}> | |
| 87 | */ | |
| 88 | private function doneBanners(User $user): array | |
| 89 | { | |
| 90 | return \array_map( | |
| 91 | static fn (DoneBanner $banner): array => [ | |
| 92 | 'bannerId' => $banner->bannerId, | |
| 93 | 'title' => $banner->title, | |
| 94 | 'missions' => $banner->missions, | |
| 95 | 'picture' => $banner->picture, | |
| 96 | 'startLatitude' => $banner->startLatitude, | |
| 97 | 'startLongitude' => $banner->startLongitude, | |
| 98 | 'doneAt' => $banner->doneAt?->format(TimelineEvent::DATE_FORMAT), | |
| 99 | ], | |
| 100 | $this->doneBannerRepository->findByOwner($user), | |
| 101 | ); | |
| 102 | } | |
| 103 | ||
| 104 | /** | |
| 105 | * @param array<string, int|string|null>|null $latestStats | |
| 106 | * @param list<array<string, int|string|null>>|null $history | |
| 107 | * @param list<array{date: string, endDate: string|null, text: string}>|null $events | |
| 108 | * @param list<array{bannerId: string, title: string, missions: int, picture: string|null, startLatitude: float|null, startLongitude: float|null, doneAt: string|null}>|null $doneBanners | |
| 109 | */ | |
| 110 | private function agent(User $user, ?AgentStat $latest, ?array $latestStats = null, ?array $history = null, ?array $events = null, ?CustomMedals $customMedals = null, ?Bannergress $bannergress = null, ?array $doneBanners = null): Agent | |
| 111 | { | |
| 112 | return new Agent( | |
| 113 | (string) $user->getAgentName(), | |
| 114 | $latest?->faction, | |
| 115 | $latest?->level, | |
| 116 | $user->getVisibleAvatar(), | |
| 117 | $latestStats, | |
| 118 | $history, | |
| 119 | $events, | |
| 120 | $customMedals, | |
| 121 | $bannergress, | |
| 122 | $doneBanners, | |
| 123 | ); | |
| 124 | } | |
| 125 | ||
| 126 | /** | |
| 127 | * A stats row as /api/agent-stats has it, without the id (that is the owner's only). | |
| 128 | * | |
| 129 | * @return array<string, int|string|null> | |
| 130 | */ | |
| 131 | private function row(AgentStat $stat): array | |
| 132 | { | |
| 133 | return [ | |
| 134 | 'datetime' => $stat->datetime->format(AgentStatInput::DATETIME_FORMAT), | |
| 135 | 'nickname' => $stat->nickname, | |
| 136 | 'faction' => $stat->faction, | |
| 137 | ...$stat->getStats(), | |
| 138 | ]; | |
| 139 | } | |
| 140 | } |