Completed
Pull Request — master (#160)
by Vladimir
05:27 queued 02:42
created

SeasonController   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 10

Importance

Changes 0
Metric Value
wmc 11
lcom 0
cbo 10
dl 0
loc 167
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
B showAction() 0 113 1
A parseSeason() 0 21 3
C validSeason() 0 28 7
1
<?php
2
3
use Symfony\Component\HttpFoundation\Request;
4
5
class SeasonController extends HTMLController
6
{
7
    public function showAction($season, Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
8
    {
9
        $term = $year = '';
10
        $this->parseSeason($season, $term, $year);
11
12
        // Because this query can't be created efficiently using our QueryBuilder, let's do things manually
13
        $db = Database::getInstance();
14
        $seasonQuery = sprintf("
15
            SELECT %s, e.elo_new AS elo FROM players p 
16
              INNER JOIN player_elo e ON e.user_id = p.id 
17
              INNER JOIN (
18
                SELECT
19
                  user_id, 
20
                  MAX(match_id) AS last_match 
21
                FROM
22
                  player_elo 
23
                WHERE
24
                  season_period = ? AND season_year = ?
25
                GROUP BY
26
                  user_id
27
              ) i ON i.user_id = p.id AND i.last_match = e.match_id
28
            WHERE p.status = 'active'
29
            ORDER BY elo DESC, p.username ASC LIMIT 10;
30
        ", Player::getEagerColumns('p'));
31
        $results = $db->query($seasonQuery, [$term, $year]);
32
        $players_w_elos = Player::createFromDatabaseResults($results);
33
34
        $seasonRange = Season::getCurrentSeasonRange($term);
35
        $matchQuery = Match::getQueryBuilder();
36
        $matchQuery
37
            ->active()
38
            ->where('time')->isAfter($seasonRange->getStartOfRange($year), true)
39
            ->where('time')->isBefore($seasonRange->getEndOfRange($year), true)
40
        ;
41
42
        $fmQuery   = clone $matchQuery;
43
        $offiQuery = clone $matchQuery;
44
45
        $fmCount   = $fmQuery->where('type')->equals(Match::FUN)->count();
46
        $offiCount = $offiQuery->where('type')->equals(Match::OFFICIAL)->count();
47
48
        Map::getQueryBuilder()->addToCache();
49
        $mapQuery = '
50
            SELECT
51
              map AS map_id,
52
              COUNT(*) AS match_count
53
            FROM
54
              matches
55
            WHERE
56
              timestamp >= ? AND timestamp <= ? AND map IS NOT NULL
57
            GROUP BY
58
              map
59
            HAVING
60
              match_count > 0
61
            ORDER BY
62
              match_count DESC
63
        ';
64
        $results = $db->query($mapQuery, [
65
            $seasonRange->getStartOfRange($year),
66
            $seasonRange->getEndOfRange($year),
67
        ]);
68
69
        $mapIDs = array_column($results, 'map_id');
70
        $maps = Map::arrayIdToModel($mapIDs);
71
        $mapCount = array_combine($mapIDs, $results);
72
73
        $matchCount = "
74
            SELECT
75
              p.user_id,
76
              SUM(m.match_type = ?) AS match_count
77
            FROM
78
              match_participation p
79
            INNER JOIN
80
              matches m ON m.id = p.match_id
81
            WHERE
82
              m.timestamp >= ? AND m.timestamp < ?
83
            GROUP BY
84
              p.user_id
85
            ORDER BY
86
              match_count DESC
87
            LIMIT 10
88
        ";
89
        $fmResults = $db->query($matchCount, [
90
            'fm',
91
            $seasonRange->getStartOfRange($year),
92
            $seasonRange->getEndOfRange($year),
93
        ]);
94
        $offiResults = $db->query($matchCount, [
95
            'official',
96
            $seasonRange->getStartOfRange($year),
97
            $seasonRange->getEndOfRange($year),
98
        ]);
99
100
        return [
101
            'season'  => ucfirst($term),
102
            'year'    => $year,
103
            'players' => $players_w_elos,
104
            'fmCount' => $fmCount,
105
            'offiCount' => $offiCount,
106
            'maps'    => $maps,
107
            'mapCount' => $mapCount,
108
            'player_matches' => [
109
                'fm' => [
110
                    'players' => Player::arrayIdToModel(array_column($fmResults, 'user_id')),
111
                    'count' => array_column($fmResults, 'match_count'),
112
                ],
113
                'official' => [
114
                    'players' => Player::arrayIdToModel(array_column($offiResults, 'user_id')),
115
                    'count' => array_column($offiResults, 'match_count'),
116
                ],
117
            ],
118
        ];
119
    }
120
121
    private function parseSeason($string, &$term, &$year)
122
    {
123
        $string = strtolower($string);
124
        $currentSeason = ($string === 'current');
125
126
        if (!$currentSeason) {
127
            $seasonTerm = explode('-', $string);
128
129
            if ($this->validSeason($seasonTerm)) {
130
                $term = $seasonTerm[0];
131
                $year = (int)$seasonTerm[1];
132
133
                return;
134
            }
135
        }
136
137
        $term = Season::getCurrentSeason();
138
        $year = TimeDate::now()->year;
139
140
        return;
0 ignored issues
show
Coding Style introduced by
Empty return statement not required here
Loading history...
141
    }
142
143
    private function validSeason($seasonSplit)
144
    {
145
        if (empty($seasonSplit) || count($seasonSplit) != 2) {
146
            return false;
147
        }
148
149
        if (in_array($seasonSplit[0], [Season::WINTER, Season::SPRING, Season::SUMMER, Season::FALL])) {
150
            $currentYear = TimeDate::now()->year;
151
            $seasonYear = (int)$seasonSplit[1];
152
153
            // The season's in the future
154
            if ($seasonYear > $currentYear) {
155
                return false;
156
            }
157
158
            // If the year's the same, we need to make sure the season's not in the future; e.g. Fall 2017 shouldn't be
159
            // valid when it's only July 2017
160
            if ($seasonYear == $currentYear &&
161
                Season::toInt($seasonSplit[0]) > Season::toInt(Season::getCurrentSeason())
162
            ) {
163
                return false;
164
            }
165
166
            return true;
167
        }
168
169
        return false;
170
    }
171
}
172