Completed
Push — master ( ff6361...375f0f )
by Matthew
04:31
created

AlertCountsEndpointController::getDailyMetrics()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 13
rs 9.4285
cc 1
eloc 8
nc 1
nop 2
1
<?php
2
3
namespace Ps2alerts\Api\Controller\Endpoint\Alerts;
4
5
use League\Fractal\Manager;
6
use Ps2alerts\Api\Controller\Endpoint\AbstractEndpointController;
7
use Ps2alerts\Api\Repository\AlertRepository;
8
use Ps2alerts\Api\Transformer\AlertTotalTransformer;
9
use Ps2alerts\Api\Transformer\AlertTransformer;
10
use Ps2alerts\Api\Exception\InvalidArgumentException;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpFoundation\Response;
13
14
class AlertCountsEndpointController extends AbstractEndpointController
15
{
16
    /**
17
     * Construct
18
     *
19
     * @param Ps2alerts\Api\Repository\AlertRepository   $repository
20
     * @param Ps2alerts\Api\Transformer\AlertTransformer $transformer
21
     * @param League\Fractal\Manager                     $fractal
22
     */
23
    public function __construct(
24
        AlertRepository  $repository,
25
        AlertTransformer $transformer,
26
        Manager          $fractal
27
    ) {
28
        $this->repository  = $repository;
29
        $this->transformer = $transformer;
30
        $this->fractal     = $fractal;
31
    }
32
33
    /**
34
     * Returns the victories of each faction and the totals
35
     *
36
     * @param  Symfony\Component\HttpFoundation\Request  $request
37
     * @param  Symfony\Component\HttpFoundation\Response $response
38
     *
39
     * @return array
40
     */
41
    public function getVictories(Request $request, Response $response)
42
    {
43
        return $this->getCountData($request, $response, 'victories');
44
    }
45
46
    /**
47
     * Returns the dominations of each faction and the totals
48
     *
49
     * @param  \Symfony\Component\HttpFoundation\Request  $request
50
     * @param  \Symfony\Component\HttpFoundation\Response $response
51
     *
52
     * @return array
53
     */
54
    public function getDominations(Request $request, Response $response)
55
    {
56
        return $this->getCountData($request, $response, 'dominations');
57
    }
58
59
    /**
60
     * Gets the required count data and returns
61
     *
62
     * @param  \Symfony\Component\HttpFoundation\Request  $request
63
     * @param  \Symfony\Component\HttpFoundation\Response $response
64
     * @param  string                                     $mode     The type of data we're getting (victory / domination)
65
     *
66
     * @return \Symfony\Component\HttpFoundation\Response
67
     */
68
    public function getCountData(Request $request, Response $response, $mode)
69
    {
70
        try {
71
            $servers = $this->getFiltersFromQueryString($request->get('servers'), 'servers', $response);
72
            $zones   = $this->getFiltersFromQueryString($request->get('zones'), 'zones', $response);
73
        } catch (InvalidArgumentException $e) {
74
            return $this->errorWrongArgs($response, $e->getMessage());
75
        }
76
77
        $counts = [];
78
        $serversExploded = explode(',', $servers);
79
80
        foreach ($serversExploded as $server) {
81
            $query = $this->repository->newQuery();
82
83
            $sql = $this->generateFactionCaseSql($server, $zones, $mode);
84
85
            $query->cols([$sql]);
86
87
            $data = $this->repository->readRaw($query->getStatement(), true);
88
            $data['total'] = array_sum($data);
89
90
            if ($mode === 'domination') {
91
                $data['draw'] = null; // Since domination draws are not possible, set it to null
92
            }
93
94
            // Build each section of the final response using the transformer
95
            $counts['data'][$server] = $this->createItem($data, new AlertTotalTransformer);
96
        }
97
98
        // Return the now formatted array to the response
99
        return $this->respondWithArray($response, $counts);
100
    }
101
102
    /**
103
     * Get Daily totals over a range of dates
104
     *
105
     * @param  \Symfony\Component\HttpFoundation\Request  $request
106
     * @param  \Symfony\Component\HttpFoundation\Response $response
107
     *
108
     * @return \Symfony\Component\HttpFoundation\Response
109
     */
110
    public function getDailyTotals(Request $request, Response $response)
111
    {
112
        try {
113
            $servers = $this->getFiltersFromQueryString($request->get('servers'), 'servers', $response);
114
            $zones   = $this->getFiltersFromQueryString($request->get('zones'), 'zones', $response);
115
        } catch (InvalidArgumentException $e) {
116
            return $this->errorWrongArgs($response, $e->getMessage());
117
        }
118
119
        $data = [];
120
121
        $metrics = $this->getDailyMetrics($servers, $zones);
122
123 View Code Duplication
        foreach ($metrics as $row) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
124
            $date = $row['dateIndex'];
125
            unset($row['dateIndex']);
126
            $row['total'] = array_sum($row);
127
128
            // Build each section of the final response using the transformer
129
            $data['data'][$date] = $this->createItem($row, new AlertTotalTransformer);
130
        }
131
132
        // Return the now formatted array to the response
133
        return $this->respondWithArray($response, $data);
134
    }
135
136
    /**
137
     * Get Daily totals over a range of dates broken down by server
138
     *
139
     * @param  \Symfony\Component\HttpFoundation\Request  $request
140
     * @param  \Symfony\Component\HttpFoundation\Response $response
141
     *
142
     * @return \Symfony\Component\HttpFoundation\Response
143
     */
144
    public function getDailyTotalsByServer(Request $request, Response $response)
145
    {
146
        try {
147
            $servers = $this->getFiltersFromQueryString($request->get('servers'), 'servers', $response);
148
            $zones   = $this->getFiltersFromQueryString($request->get('zones'), 'zones', $response);
149
        } catch (InvalidArgumentException $e) {
150
            return $this->errorWrongArgs($response, $e->getMessage());
151
        }
152
153
        $data = [];
154
        $serversExploded = explode(',', $servers);
155
156
        foreach ($serversExploded as $server) {
157
            $metrics = $this->getDailyMetrics($server, $zones);
158
159 View Code Duplication
            foreach ($metrics as $row) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
160
                $date = $row['dateIndex'];
161
                unset($row['dateIndex']);
162
                $row['total'] = array_sum($row);
163
164
                // Build each section of the final response using the transformer
165
                $data['data'][$server][$date] = $this->createItem($row, new AlertTotalTransformer);
166
            }
167
        }
168
169
        // Return the now formatted array to the response
170
        return $this->respondWithArray($response, $data);
171
    }
172
173
    /**
174
     * Gets raw daily metrics which can be further processed
175
     *
176
     * @param  string $server
177
     * @param  string $zones
178
     *
179
     * @return array
180
     */
181
    public function getDailyMetrics($server, $zones)
182
    {
183
        $query = $this->repository->newQuery();
184
185
        $sql = $this->generateFactionCaseSql($server, $zones);
186
        $sql .= ', DATE(ResultDateTime) AS dateIndex';
187
        $query->cols([$sql]);
188
189
        $query->where('ResultDateTime IS NOT NULL');
190
        $query->groupBy(['dateIndex']);
191
192
        return $metrics = $this->repository->readRaw($query->getStatement());
0 ignored issues
show
Unused Code introduced by
$metrics is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
193
    }
194
195
    /**
196
     * Generates the SELECT CASE statements required to filter down by Faction and Server
197
     *
198
     * @param  string $server
199
     * @param  string $zones
200
     * @param  string $mode
201
     *
202
     * @return string
203
     */
204
    public function generateFactionCaseSql($server = null, $zones = null, $mode = null)
205
    {
206
        $sql = '';
207
208
        foreach ($this->getConfigItem('factions') as $faction) {
0 ignored issues
show
Bug introduced by
The expression $this->getConfigItem('factions') of type string is not traversable.
Loading history...
209
            $factionAbv = strtoupper($faction);
210
            $sql .= "SUM(CASE WHEN `ResultWinner`='{$factionAbv}' ";
211
            if (! empty($server)) {
212
                $sql .= "AND `ResultServer` IN ({$server}) ";
213
            }
214
215
            if (! empty($zones)) {
216
                $sql .= "AND `ResultAlertCont` IN ({$zones}) ";
217
            }
218
219
            if ($mode === 'dominations') {
220
                $sql .= "AND `ResultDomination` = 1 ";
221
            }
222
223
            $sql .= "THEN 1 ELSE 0 END) {$faction}";
224
225
            if ($factionAbv !== 'DRAW') {
226
                $sql .= ", ";
227
            }
228
        }
229
230
        return $sql;
231
    }
232
}
233