Completed
Push — feature/player-elo ( 8f2bc8...21fda9 )
by Vladimir
04:08
created

PlayerEloCalculations::up()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 85
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 22.7855

Importance

Changes 0
Metric Value
dl 0
loc 85
ccs 17
cts 44
cp 0.3864
rs 5.8037
c 0
b 0
f 0
cc 8
eloc 49
nc 6
nop 0
crap 22.7855

How to fix   Long Method   

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
use Phinx\Migration\AbstractMigration;
4
5
class PlayerEloCalculations extends AbstractMigration
6
{
7
    /**
8
     * {@inheritdoc}
9
     */
10 1
    public function up()
11
    {
12 1
        $kernel = new AppKernel('prod', false);
13 1
        $kernel->boot();
14 1
        $qb = new MatchQueryBuilder('Match', [
15 1
            'columns' => [
16
                'team_a_players' => 'team_a_players',
17
                'team_b_players' => 'team_b_players',
18
                'match_type' => 'match_type',
19
                'timestamp'  => 'timestamp',
20
                'status'     => 'status',
21
            ],
22
        ]);
23
24
        $query = $qb
25 1
            ->where('team_a_players')->isNotNull()
26 1
            ->where('team_a_players')->notEquals('')
27 1
            ->where('team_b_players')->isNotNull()
28 1
            ->where('team_b_players')->notEquals('')
29 1
            ->where('match_type')->equals('official')
30 1
            ->where('status')->equals('entered')
31 1
            ->sortBy('timestamp')
32 1
            ->limit(1000)
33
        ;
34
35 1
        $pageCount = $query->countPages();
36 1
        $lastSeason = [];
37
38 1
        for ($i = 1; $i <= $pageCount; $i++) {
39
            $matches = $query
40
                ->fromPage($i)
41
                ->getModels($fast = true)
42
            ;
43
44
            /** @var Match $match */
45
            foreach ($matches as $match) {
46
                $seasonInfo = Season::getSeason($match->getTimestamp());
47
48
                // Clear the model cache every season since Elos are cached internally
49
                if ($seasonInfo != $lastSeason) {
50
                    $lastSeason = $seasonInfo;
51
                    Service::getModelCache()->clear();
52
                }
53
54
                $teamA = $match->getTeamAPlayers();
55
                $teamB = $match->getTeamBPlayers();
56
57
                if (empty($teamA) || empty($teamB)) {
58
                    continue;
59
                }
60
61
                $getElo = function($n) use ($seasonInfo) {
62
                    /** @var Player $n */
63
                    return $n->getElo($seasonInfo['season'], $seasonInfo['year']);
64
                };
65
66
                $teamA_Avg = array_sum(array_map($getElo, $teamA)) / count($teamA);
67
                $teamB_Avg = array_sum(array_map($getElo, $teamB)) / count($teamB);
68
69
                $diff = Match::calculateEloDiff(
70
                    $teamA_Avg, $teamB_Avg, $match->getTeamAPoints(), $match->getTeamBPoints(), $match->getDuration()
71
                );
72
73
                // We need to disable transactions so our Player::adjustElo() fxn won't hold up execution
74
                $this->getAdapter()->commitTransaction();
75
76
                $this->query("UPDATE matches SET player_elo_diff = {$diff} WHERE id = {$match->getId()} LIMIT 1;");
77
78
                $walkFxn = function ($v, $k, $positive) use ($diff, $match, &$batch, $seasonInfo) {
79
                    /** @var Player $v */
80
81
                    $eloDiff = ($positive) ? $diff : -$diff;
82
83
                    if ($v->isValid()) {
84
                        $v->adjustElo($eloDiff, $match);
85
                    }
86
                };
87
88
                array_walk($teamA, $walkFxn, true);
89
                array_walk($teamB, $walkFxn, false);
90
91
                $this->getAdapter()->beginTransaction();
92
            }
93
        }
94 1
    }
95
96
    public function down()
97
    {
98
        $seasonElos = $this->table('player_elo');
99
        $seasonElos->truncate();
100
    }
101
}
102