1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
<?php
/* Copyright 2025 Florian Fischer
* punktestand is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* punktestand is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* punktestand. If not, see <https://www.gnu.org/licenses/>.
*/
// PHP Klasse, die alle Daten einer Schulklasse enthält.
class Klasse {
public string $bezeichner;
public int $punkte;
public string $farbe;
public function __construct(string $bezeichner, ?string $farbe) {
$this->bezeichner = $bezeichner;
$this->punkte = 0;
if (is_null($farbe)) {
// Die Standardfarbe ist ein leichtes Blau
$this->farbe = 'rgb(54, 162, 235)';
} else {
$this->farbe = $farbe;
}
}
}
// Die Funktion lade_daten liefert die Klassen und ihren Punktestand, sowie alle
// aufgetretenen Ereignisse in einem array zurück.
function lade_daten($config, $schuljahr, $jahrgang): array {
// Zusätzliche Parameter neben der Datenbankbeschreibung für den PDO Konstruktor.
$pdo_parameter = array();
// Behandle unterschiedliche Arten von Datenbanken
if ($config['dbtype'] == 'sqlite') {
$db_beschreibung = sprintf("sqlite:%s", $config['dbname']);
} else {
$db_beschreibung = sprintf('%s:host=%s;dbname=%s', $config['dbtype'], $config['dbhost'], $config['dbname']);
// MySql bspw. benötigt einen Nutzernamen und ein Passwort für die Verbindung
array_push($pdo_parameter, $config['dbuser']);
array_push($pdo_parameter, $config['dbpassword']);
}
// Versuche die Verbindung zur Datenbank aufzubauen. Benötigte Parameter
// müssen in der richtigen Reihenfolge in dem $pdo_parameter array enthalten sein.
try {
$verbindung = new PDO($db_beschreibung, ...$pdo_parameter);
} catch(PDOException $e) {
// Die Verbindung ist fehlgeschlagen
error_log($e->getMessage());
return "null; alert('Es konnte keine Verbindung zur Datenbank hergestellt werden, bitte gib deiner Lehrkraft Bescheid. Fehler: " . $e->getMessage() . "')";
}
// Die Verbindung war erfolgreich
// Bereite unsere Klassenabfrage vor.
// Dies verhindert SQL-Injection Angriffe, da die Parameter Schuljahr und
// Jahrgang über die URL kontrollierbar sind.
$klassen_abfrage = $verbindung->prepare('SELECT * FROM Klasse WHERE Schuljahr = ? AND Jahrgang = ?');
$klassen_abfrage->bindValue(1, $schuljahr, PDO::PARAM_STR);
$klassen_abfrage->bindValue(2, $jahrgang, PDO::PARAM_INT);
$klassen_abfrage->execute();
// Die Klassen im passenden Jahrgang und Schuljahr
$klassen = array();
foreach ($klassen_abfrage->fetchAll() as $zeile) {
$bezeichner = sprintf('%d%s', $zeile['Jahrgang'], $zeile['Bezeichner']);
$klasse = new Klasse($bezeichner, $zeile['Farbe']);
// Indiziere die Klassen mit dem jeweiligen Bezeichner
$klassen[$bezeichner] = $klasse;
}
// Bereite die Ereignisabfrage vor. Sicherheitshinweis siehe: Klassenabfrage.
// Nur Ereignisse mit einem Delta != 0, also solche die wirklich den Punktestand
// verändern, werden ausgewählt.
$ereignis_abfrage = $verbindung->prepare('SELECT * FROM Ereignis WHERE Schuljahr = ? AND Jahrgang = ? AND Delta != 0');
$ereignis_abfrage->bindValue(1, $schuljahr, PDO::PARAM_STR);
$ereignis_abfrage->bindValue(2, $jahrgang, PDO::PARAM_INT);
$ereignis_abfrage->execute();
// Alle Ereignisse der ausgewählten Klassen
$ereignisse = $ereignis_abfrage->fetchAll();
// Deklaration der streak_ereignisse Variable, die nur unter bestimmten
// Umständen mit einem Wert gefüllt wird. Die Forward-Deklaration ermöglicht es
// die Variable danach zu benutzen unabhängig, davon ob sie mit einem sinnvollen
// Wert gefüllt wurde.
$streak_ereignisse = null;
$streak_ereignis_beschreibung = $config['streak_ereignis'];
if ($streak_ereignis_beschreibung != '') {
// Bereite die Streak-Ereignisabfrage vor. Sicherheitshinweis siehe: Klassenabfrage.
// Nur Ereignisse mit dem konfigurierten Namen werden ausgewählt.
// Zusätzlich werden nur Ereignisse mit einem Datum betrachtet, da zur Streak
// Berechnung die Ereignisse in eine zeitliche Reihenfolge gebracht werden
// müssen.
$streak_ereignis_abfrage = $verbindung->prepare('SELECT * FROM Ereignis WHERE Schuljahr = ? AND Jahrgang = ? AND Beschreibung = ? ORDER BY Datum ASC');
$streak_ereignis_abfrage->bindValue(1, $schuljahr, PDO::PARAM_STR);
$streak_ereignis_abfrage->bindValue(2, $jahrgang, PDO::PARAM_INT);
$streak_ereignis_abfrage->bindValue(3, $streak_ereignis_beschreibung, PDO::PARAM_STR);
$streak_ereignis_abfrage->execute();
// Alle Streak-Ereignisse der ausgewählten Klassen
$streak_ereignisse = $streak_ereignis_abfrage->fetchAll();
}
// Schließe die Datenbank Verbindung
$verbindung = null;
foreach ($ereignisse as $ereignis) {
$bezeichner = sprintf('%d%s', $ereignis['Jahrgang'], $ereignis['Bezeichner']);
// Aktualisiere den Punktestand nach dem Ereignis.
$klassen[$bezeichner]->punkte += $ereignis['Delta'];
}
$daten = array();
$daten['klassen'] = array_values($klassen);
$daten['ereignisse'] = $ereignisse;
if ($streak_ereignisse != null) {
$daten['streakEreignisse'] = $streak_ereignisse;
}
return $daten;
}
?>
|