LeaderboardOutfitsCommand::playerLeaderboards()   D
last analyzed

Complexity

Conditions 13
Paths 72

Size

Total Lines 89
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 53
nc 72
nop 1
dl 0
loc 89
rs 4.9922
c 0
b 0
f 0

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 Ps2alerts\Api\Command;
4
5
use Ps2alerts\Api\Command\BaseCommand;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Console\Output\OutputInterface;
8
9
class LeaderboardOutfitsCommand extends BaseCommand
10
{
11
    protected $redis;
12
13
    protected function configure()
14
    {
15
        parent::configure(); // See BaseCommand.php
16
        $this
17
            ->setName('Leaderboards:Outfits')
18
            ->setDescription('Processes all outfit leaderboards');
19
20
        $this->redis = $this->container->get('redis');
21
    }
22
23 View Code Duplication
    protected function execute(InputInterface $input, OutputInterface $output)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
24
    {
25
        $start = microtime(true);
26
        $output->writeln("Running Player Leaderboards");
27
28
        $this->playerLeaderboards($output);
29
30
        $end = microtime(true);
31
        $output->writeln("Processing took ".gmdate("H:i:s", ($end - $start)));
32
    }
33
34
    public function playerLeaderboards(OutputInterface $output)
35
    {
36
        $metrics = [
37
            'playerKills',
38
            'playerDeaths',
39
            'playerTeamkills',
40
            'playerSuicides',
41
            'headshots'
42
        ];
43
        $servers = [0, 1, 10, 13, 17, 25, 1000, 2000];
44
45
        foreach ($servers as $server) {
46
            foreach ($metrics as $metric) {
47
                $this->markAsBeingUpdated($metric, $server);
48
            }
49
        }
50
51
        foreach ($servers as $server) {
52
            foreach ($metrics as $metric) {
53
                $count = 0;
54
                $limit = 10000;
55
                $ladderLimit = 10000;
56
                $pos = 1;
57
58
                $output->writeln("Running metric: {$metric} for server {$server}");
59
60
                $list = "ps2alerts:api:leaderboards:players:{$metric}:list-{$server}";
61
62
                // Delete the list for reprocessing
63
                if ($this->redis->exists($list)) {
64
                    $this->redis->del($list);
65
                }
66
67
                // Continue with loop until we don't have a count % modulus returning from the query
68
                while ($count < $ladderLimit && $count % $limit === 0 || $count === 0) {
69
                    $per = ($count / $ladderLimit) * 100;
70
                    $output->writeln("========= {$count} / {$ladderLimit} ({$per}%) =========");
71
72
                    $query = $this->auraFactory->newSelect();
73
                    $query->cols(['*']);
74
                    $query->from('ws_players_total');
75
76
                    if ($server !== 0) {
77
                        $query->where('playerServer', $server);
78
                    }
79
80
                    $query->orderBy([$metric . ' DESC']);
81
                    $query->limit($limit);
82
                    $query->offset($count);
83
84
                    $statement = $this->db->prepare($query->getStatement());
85
                    $statement->execute($query->getBindValues());
86
87
                    $count = $count + $statement->rowCount();
88
89
                    while ($player = $statement->fetch(\PDO::FETCH_OBJ)) {
90
                        $playerPosKey = "ps2alerts:api:leaderboards:players:pos:{$player->playerID}";
91
92
                        // If player record doesn't exist
93
                        if (!$this->redis->exists($playerPosKey)) {
94
                            $data = [
95
                                'id'      => $player->playerID,
96
                                'updated' => date('U', strtotime('now'))
97
                            ];
98
                        } else {
99
                            $data = json_decode($this->redis->get($playerPosKey), true);
100
                        }
101
102
                        // For first time running
103
                        if (!empty($data[$server][$metric])) {
104
                            $data[$server][$metric]['old'] = $data[$server][$metric]['new'];
105
                        } else {
106
                            $data[$server][$metric]['old'] = 0;
107
                        }
108
109
                        $data[$server][$metric]['new'] = $pos;
110
                        $data['updated'] = date('U', strtotime('now'));
111
112
                        $this->redis->set($playerPosKey, json_encode($data));
113
                        $this->redis->rpush($list, $player->playerID);
114
115
                        $pos++;
116
                    }
117
                }
118
119
                $this->markAsComplete($metric, $server);
120
            }
121
        }
122
    }
123
124
    /**
125
     * @param string $metric
126
     * @param integer $server
127
     */
128
    public function markAsBeingUpdated($metric, $server)
129
    {
130
        $key = "ps2alerts:api:leaderboards:status:{$metric}:{$server}";
131
132
        // Create the key if it doesn't exist for some reason (1st runs)
133
        if (!$this->redis->exists($key)) {
134
            $data = [
135
                'beingUpdated' => 1,
136
                'lastUpdated'  => 'never'
137
            ];
138
        } else {
139
            $data = $this->redis->get($key);
140
            $data['beingUpdated'] = 1;
141
        }
142
143
        $this->redis->set($key, json_encode($data));
144
    }
145
146
    /**
147
     * @param string $metric
148
     * @param integer $server
149
     */
150
    public function markAsComplete($metric, $server)
151
    {
152
        $key = "ps2alerts:api:leaderboards:status:{$metric}:{$server}";
153
154
        $data = [
155
            'beingUpdated' => 0,
156
            'lastUpdated'  => date('U', strtotime('now'))
157
        ];
158
159
        $this->redis->set($key, json_encode($data));
160
    }
161
}
162