Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 91 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
| OlzZielsprint | |
0.00% |
0 / 91 |
|
0.00% |
0 / 2 |
110 | |
0.00% |
0 / 1 |
| getHtml | |
0.00% |
0 / 38 |
|
0.00% |
0 / 1 |
30 | |||
| getRanking | |
0.00% |
0 / 53 |
|
0.00% |
0 / 1 |
30 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace Olz\Components\OlzZielsprint; |
| 4 | |
| 5 | use Olz\Components\Common\OlzComponent; |
| 6 | |
| 7 | /** @extends OlzComponent<array<string, mixed>> */ |
| 8 | class 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 </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("{$calculation}")'>"; |
| 44 | $out .= "<td style='text-align: right;'>{$actual_rank}. </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 | } |