Passed
Pull Request — develop (#97)
by BENARD
12:42
created

PlayerChartRankingHandler::getCountries()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace VideoGamesRecords\CoreBundle\Ranking\Command\Player;
6
7
use Doctrine\ORM\EntityManagerInterface;
8
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
9
use VideoGamesRecords\CoreBundle\Entity\Chart;
10
use VideoGamesRecords\CoreBundle\Entity\PlayerChart;
11
use VideoGamesRecords\CoreBundle\Event\PlayerChartEvent;
12
use VideoGamesRecords\CoreBundle\Ranking\Provider\Player\PlayerChartRankingProvider;
13
use VideoGamesRecords\CoreBundle\Ranking\Command\AbstractRankingHandler;
14
use VideoGamesRecords\CoreBundle\Tools\Ranking;
15
use VideoGamesRecords\CoreBundle\VideoGamesRecordsCoreEvents;
16
17
class PlayerChartRankingHandler extends AbstractRankingHandler
18
{
19
    private PlayerChartRankingProvider $playerChartRankingProvider;
20
    private array $players = [];
21
    private array $series = [];
22
    private array $games = [];
23
    private array $groups = [];
24
    private array $countries = [];
25
    private array $platforms = [];
26
27
    public function __construct(
28
        EntityManagerInterface $em,
29
        EventDispatcherInterface $eventDispatcher,
30
        PlayerChartRankingProvider $playerChartRankingProvider
31
    ) {
32
        $this->em = $em;
33
        $this->eventDispatcher = $eventDispatcher;
34
        $this->playerChartRankingProvider = $playerChartRankingProvider;
35
        parent::__construct($em, $eventDispatcher);
36
    }
37
38
    public function handle($mixed): void
39
    {
40
        /** @var Chart $chart */
41
        $chart = $this->em->getRepository('VideoGamesRecords\CoreBundle\Entity\Chart')->find($mixed);
42
        if (null == $chart) {
43
            return;
44
        }
45
46
        $game = $chart->getGroup()->getGame();
47
        $this->groups[$chart->getGroup()->getId()] = $chart->getGroup();
48
        $this->games[$game->getId()] = $game;
49
50
        if ($game->getSerie() !== null && $game->getSerie()->getSerieStatus()->isActive()) {
51
            $this->series[$game->getSerie()->getId()] = $game->getSerie();
52
        }
53
54
        $ranking     = $this->playerChartRankingProvider->getRanking($chart);
55
        $pointsChart = Ranking::chartPointProvider(count($ranking));
56
57
        $topScoreLibValue = '';
58
        $previousLibValue = '';
59
        $rank             = 1;
60
        $nbEqual          = 1;
61
        $playerChartEqual = [];
62
63
        $result = $this->em->getRepository('VideoGamesRecords\CoreBundle\Entity\PlayerChart')->getPlatforms($chart);
64
        $platforms = [];
65
        foreach ($result as $row) {
66
            $platforms[$row['id']] = [
67
                'count' => $row['nb'],
68
                'points' => Ranking::platformPointProvider($row['nb']),
69
                'previousLibValue' => '',
70
                'rank' => 0,
71
                'nbEqual' => 1,
72
                'playerChartEqual' => [],
73
            ];
74
        }
75
76
        foreach ($ranking as $k => $item) {
77
            $libValue = '';
78
            /** @var PlayerChart $playerChart */
79
            $playerChart = $item[0];
80
81
            $platform = $playerChart->getPlatform();
82
            if (null !== $platform) {
83
                $this->platforms[$platform->getId()] = $platform;
84
            }
85
86
            $country = $playerChart->getPlayer()->getCountry();
87
            if (null !== $country) {
88
                $this->countries[$country->getId()] = $country;
89
            }
90
91
            $this->players[$playerChart->getPlayer()->getId()] = $playerChart->getPlayer();
92
93
            // Lost position ?
94
            $oldRank = $playerChart->getRank();
95
            $oldNbEqual = $playerChart->getNbEqual();
96
            $playerChart->setIsTopScore(false);
97
98
            foreach ($chart->getLibs() as $lib) {
99
                $libValue .= $item['value_' . $lib->getId()] . '/';
100
            }
101
            if ($k === 0) {
102
                // Premier élément => topScore
103
                $playerChart->setIsTopScore(true);
104
                $topScoreLibValue = $libValue;
105
            } else {
106
                if ($libValue === $topScoreLibValue) {
107
                    $playerChart->setIsTopScore(true);
108
                }
109
                if ($previousLibValue === $libValue) {
110
                    ++$nbEqual;
111
                } else {
112
                    $rank += $nbEqual;
113
                    $nbEqual = 1;
114
                    $playerChartEqual = [];
115
                }
116
            }
117
            // Platform point
118
            if ($playerChart->getPlatform() != null) {
119
                $idPlatForm = $playerChart->getPlatform()->getId();
120
                if ($platforms[$idPlatForm]['previousLibValue'] === $libValue) {
121
                    ++$platforms[$idPlatForm]['nbEqual'];
122
                } else {
123
                    $platforms[$idPlatForm]['rank'] += $platforms[$idPlatForm]['nbEqual'];
124
                    $platforms[$idPlatForm]['nbEqual'] = 1;
125
                    $platforms[$idPlatForm]['playerChartEqual'] = [];
126
                }
127
                $platforms[$idPlatForm]['playerChartEqual'][] = $playerChart;
128
            }
129
130
            $playerChartEqual[] = $playerChart;
131
132
            $playerChart->setNbEqual($nbEqual);
133
            $playerChart->setRank($rank);
134
            $playerChart->setPointChart((int) (
135
                    array_sum(
136
                        array_slice(array_values($pointsChart), $playerChart->getRank() - 1, $playerChart->getNbEqual())
137
                    ) / $playerChart->getNbEqual()
138
                ));
139
140
            if ($nbEqual > 1) {
141
                // Pour les égalités déjà passées on met à jour le nbEqual et l'attribution des points
142
                foreach ($playerChartEqual as $playerChartToModify) {
143
                    $playerChartToModify->setNbEqual($nbEqual);
144
                    $playerChartToModify->setPointChart($playerChart->getPointChart());
145
                }
146
            }
147
148
            if ($playerChart->getPlatform() != null) {
149
                $idPlatForm = $playerChart->getPlatform()->getId();
150
                $playerChart->setPointPlatform((int) (
151
                    array_sum(
152
                        array_slice(array_values($platforms[$idPlatForm]['points']), $platforms[$idPlatForm]['rank'] - 1, $platforms[$idPlatForm]['nbEqual'])
153
                    ) / $platforms[$idPlatForm]['nbEqual']
154
                ));
155
                if ($platforms[$idPlatForm]['nbEqual'] > 1) {
156
                    // Pour les égalités déjà passées on met à jour le nbEqual et l'attribution des points
157
                    foreach ($platforms[$idPlatForm]['playerChartEqual'] as $playerChartToModify) {
158
                        $playerChartToModify
159
                            ->setPointPlatform($playerChart->getPointPlatform());
160
                    }
161
                }
162
            } else {
163
                $playerChart->setPointPlatform(0);
164
            }
165
166
167
            $event = new PlayerChartEvent($playerChart, $oldRank, $oldNbEqual);
168
            $this->eventDispatcher->dispatch($event, VideoGamesRecordsCoreEvents::PLAYER_CHART_MAJ_COMPLETED);
169
170
            $previousLibValue = $libValue;
171
172
            // Platform point
173
            if ($playerChart->getPlatform() != null) {
174
                $platforms[$playerChart->getPlatform()->getId()]['previousLibValue'] = $libValue;
175
            }
176
        }
177
        $this->em->flush();
178
    }
179
180
    public function getPlayers(): array
181
    {
182
        return $this->players;
183
    }
184
185
    public function getSeries(): array
186
    {
187
        return $this->series;
188
    }
189
190
    public function getGames(): array
191
    {
192
        return $this->games;
193
    }
194
195
    public function getGroups(): array
196
    {
197
        return $this->groups;
198
    }
199
200
    public function getCountries(): array
201
    {
202
        return $this->countries;
203
    }
204
205
    public function getPlatforms(): array
206
    {
207
        return $this->platforms;
208
    }
209
}
210