Passed
Push — develop ( 462fa0...bd18e2 )
by BENARD
04:27
created

PlayerChartRankingHandler::handle()   F

Complexity

Conditions 16
Paths 723

Size

Total Lines 128
Code Lines 83

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 83
dl 0
loc 128
rs 1.7986
c 0
b 0
f 0
cc 16
nc 723
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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