LeaderboardOutfitsCommand::execute()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 10
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 2
dl 10
loc 10
rs 9.4285
c 0
b 0
f 0
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