Passed
Push — develop ( 3838fa...073e77 )
by BENARD
18:12 queued 06:21
created

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