Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 91
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
OlzZielsprint
0.00% covered (danger)
0.00%
0 / 91
0.00% covered (danger)
0.00%
0 / 2
110
0.00% covered (danger)
0.00%
0 / 1
 getHtml
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
30
 getRanking
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3namespace Olz\Components\OlzZielsprint;
4
5use Olz\Components\Common\OlzComponent;
6
7/** @extends OlzComponent<array<string, mixed>> */
8class OlzZielsprint extends OlzComponent {
9    public function getHtml(mixed $args): string {
10        $out = '';
11
12        $ranking = $this->getRanking();
13
14        $out .= "<table>";
15        $out .= "<tr>";
16        $out .= "<th style='border-bottom: 1px solid black; text-align: right;'>Rang&nbsp;</th>";
17        $out .= "<th style='border-bottom: 1px solid black;'>Name</th>";
18        $out .= "<th style='border-bottom: 1px solid black; text-align: right;'>Punkte</th>";
19        $out .= "</tr>";
20        $last_points = null;
21        $last_actual_rank = 1;
22        for ($index = 0; $index < count($ranking); $index++) {
23            $rank = $index + 1;
24            $ranking_entry = $ranking[$index];
25            $person_name = $ranking_entry['person_name'];
26            $points = intval($ranking_entry['points']);
27            $actual_rank = ($last_points === $points)
28                ? $last_actual_rank
29                : $rank;
30
31            $calculation = "{$person_name}\\n---\\n";
32            foreach ($ranking_entry['calculation'] as $event_calculation) {
33                $event_name = $event_calculation['event_name'];
34                $event_points = $event_calculation['points'];
35                $event_max_points = $event_calculation['max_points'];
36                $finish_split = $event_calculation['finish_split'];
37                $finish_minutes = floor(intval($finish_split) / 60);
38                $finish_seconds = str_pad(strval(intval($finish_split) % 60), 2, '0');
39                $pretty_finish_split = "{$finish_minutes}:{$finish_seconds}";
40                $calculation .= "{$event_name}{$event_points} / {$event_max_points} ({$pretty_finish_split})\\n";
41            }
42            $bgcolor = ($index % 2 === 0) ? 'rgba(0,0,0,0.1)' : 'rgba(0,0,0,0)';
43            $out .= "<tr style='background-color:{$bgcolor}; cursor:pointer;' onclick='alert(&quot;{$calculation}&quot;)'>";
44            $out .= "<td style='text-align: right;'>{$actual_rank}.&nbsp;</td>";
45            $out .= "<td>{$person_name}</td>";
46            $out .= "<td style='text-align: right;'>{$points}</td>";
47            $out .= "</tr>";
48            $last_points = $points;
49            $last_actual_rank = $actual_rank;
50        }
51        $out .= "</table>";
52
53        return $out;
54    }
55
56    /**
57     * @return array<array{
58     *   person_id: int,
59     *   person_name: string,
60     *   points: int,
61     *   calculation: array<array{
62     *     event_name: string,
63     *     points: int,
64     *     finish_split: int,
65     *     max_points: int,
66     *   }>
67     * }>
68     */
69    public function getRanking(): array {
70        $year = $this->dateUtils()->getCurrentDateInFormat('Y');
71        $db = $this->dbUtils()->getDb();
72
73        $sql = "
74            SELECT solv_uid, name, date
75            FROM solv_events
76            WHERE
77                date>='{$year}-01-01'
78                AND date<='{$year}-12-31'
79                AND kind='foot'
80            ORDER BY date ASC";
81        $res_events = $db->query($sql);
82        $this->generalUtils()->checkNotBool($res_events, "Query error: {$sql}");
83        $points_by_person = [];
84        while ($row_event = $res_events->fetch_assoc()) {
85            // $out .= "<h3>".json_encode($row_event)."</h3>";
86            $event_id = intval($row_event['solv_uid']);
87            $sql = "
88                SELECT person, finish_split
89                FROM solv_results
90                WHERE
91                    event='{$event_id}'
92                    AND finish_split > '0'
93                ORDER BY finish_split ASC";
94            $res_results = $db->query($sql);
95            $this->generalUtils()->checkNotBool($res_results, "Query error: {$sql}");
96            $num_participants = intval($res_results->num_rows);
97            $last_finish_split = null;
98            $last_actual_points = null;
99            for ($points = $num_participants; $points > 0; $points--) {
100                $row_results = $res_results->fetch_assoc();
101                $person_id = intval($row_results['person'] ?? 0);
102                $finish_split = intval($row_results['finish_split'] ?? PHP_INT_MAX);
103                $actual_points = ($last_finish_split === $finish_split)
104                    ? $last_actual_points
105                    : $points;
106                $person_points = $points_by_person[$person_id]
107                    ?? ['points' => 0, 'calculation' => []];
108                $points_by_person[$person_id]['points'] = $person_points['points'] + $actual_points;
109                $points_by_person[$person_id]['calculation'][] = [
110                    'event_name' => "{$row_event['name']}",
111                    'points' => $actual_points,
112                    'finish_split' => $finish_split,
113                    'max_points' => $num_participants,
114                ];
115                $last_finish_split = $finish_split;
116                $last_actual_points = $actual_points;
117                // $out .= "<div>".json_encode($row_results)."</div>";
118            }
119        }
120        $ranking = [];
121        foreach ($points_by_person as $person_id => $points) {
122            $sql = "
123                SELECT name
124                FROM solv_people
125                WHERE id='{$person_id}'";
126            $res_person = $db->query($sql);
127            $this->generalUtils()->checkNotBool($res_person, "Query error: {$sql}");
128            $row_person = $res_person->fetch_assoc();
129            $person_name = strval($row_person['name'] ?? '?');
130            $ranking[] = [
131                'person_id' => $person_id,
132                'person_name' => $person_name,
133                'points' => $points['points'],
134                'calculation' => $points['calculation'],
135            ];
136        }
137
138        usort($ranking, fn ($a, $b) => $b['points'] - $a['points']);
139
140        return $ranking;
141    }
142}