From d0fce093ef2f16fc2897baf7ddf93b6f969890bf Mon Sep 17 00:00:00 2001 From: Friedrich Beckmann Date: Fri, 30 Jan 2026 17:59:23 +0100 Subject: initial commit The first prototype where you can upload student data from moodle and change the marks. In student view the results for the logged in person can be viewed. --- ReadMe.md | 28 +++++++ admin-addusers.php | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++++ admin-show.php | 154 ++++++++++++++++++++++++++++++++++++ admin-update.php | 39 +++++++++ database.php | 138 ++++++++++++++++++++++++++++++++ index.php | 46 +++++++++++ login.php | 47 +++++++++++ logout.php | 18 +++++ setup.php | 93 ++++++++++++++++++++++ show-user.php | 133 +++++++++++++++++++++++++++++++ 10 files changed, 922 insertions(+) create mode 100644 ReadMe.md create mode 100644 admin-addusers.php create mode 100644 admin-show.php create mode 100644 admin-update.php create mode 100644 database.php create mode 100644 index.php create mode 100644 login.php create mode 100644 logout.php create mode 100644 setup.php create mode 100644 show-user.php diff --git a/ReadMe.md b/ReadMe.md new file mode 100644 index 0000000..5bb50d2 --- /dev/null +++ b/ReadMe.md @@ -0,0 +1,28 @@ +# praktrack - Verwaltung von Portfolioprüfungen + +Mit diesem Webtool können die Teilleistungen von den +Portfolioprüfungen Digitaltechnik und Technische Informatik +verwaltet werden. Portfolioprüfungen bestehen aus + + * Laborteil der bestanden/nicht bestanden sein kann + * Klausur mit einer Note + +Erst wenn beide Prüfungsteile erfolgreich absolviert sind, +wird die Note ans Prüfungsamt gemeldet. + +## Ansicht der Studenten + +Die Studenten authentifizieren sich über ldap und können dann die eigenen Daten einsehen. + +## Adminansicht + +Als Admin kann man Studenten für ein Semester und eine Prüfung (ti/dt) anlegen und dann die Prüfungsergebnisse ändern. + +## Anlegen der Studentendaten + +Die Prüfungsteilnehmer werden über die Daten aus dem Moodlekurs +in das Tool importiert. Dazu werden die Teilnehmerdaten des Moodlekurses als .csv exportiert und dann in praktrack importiert. + +## Eingabe der Prüfungsergebnisse + +Die Prüfungsergebnisse werden in der Listenansicht eingegeben und mit dem Knopf "update" in die Datenbank gespeichert. diff --git a/admin-addusers.php b/admin-addusers.php new file mode 100644 index 0000000..880a535 --- /dev/null +++ b/admin-addusers.php @@ -0,0 +1,226 @@ + + + + +

Add Users

+ + + + + + +
+ Add students + + Show students + + Logout +
+ +

Die Teilnehmer werden aus dem Moodlekurs der Veranstaltung übernommen. + Dazu die Teilnehmer als csv exportieren. Die csv Datei + dann mit den Angaben zum Kurs und zum Semester hier hochladen. Die + csv Datei enthält die Namen, Matrikelnummer und die Gruppen. +

+ + $teilnehmerliste) { + if (in_array($matrikelnummer, $teilnehmerliste)) { + return $gname; + } + } +} + +function parseuserfile($fname) { + global $pfach,$psemester,$newstudents,$newgroups,$students,$groups; + if (($fh = fopen($fname, "r")) !== FALSE) { + while (($line = fgetcsv($fh, 1000, ",", "\"", ""))) { + $vorname = $line[0]; + $nachname = $line[1]; + $matrikelnummer = is_numeric($line[2]) ? $line[2] : ""; + $student = array ( + "vorname" => $vorname, + "nachname" => $nachname, + "noten" => array ( + $pfach => [] + ) + ); + $newgruppe = ""; + if (!empty($line[4])) { + $gruppen = str_getcsv($line[4],",","\"",""); + foreach ($gruppen as $gruppe) { + if (preg_match("/.*-G[0-9].*/u", $gruppe) or + preg_match("/G[0-9].*/u", $gruppe) ) { + $newgruppe = trim($gruppe); + } + } + } + + if (empty($newgruppe) or empty($matrikelnummer)) { + echo "

WARNING: $vorname $nachname has no group or no matrikelnummer.

"; + } elseif (!empty($groups[$psemester][$pfach]) and + $gname = is_student_in_any_group($matrikelnummer, $groups[$psemester][$pfach])) { + echo "

WARNING: $matrikelnummer is already in $gname in database.

"; + } elseif ($gname = is_student_in_any_group($matrikelnummer, $newgroups)) { + echo "

WARNING: $matrikelnummer is already in $gname in this file

"; + } else { + if (empty($students[$matrikelnummer])) { + //db_student_new($matrikelnummer,$student); + echo "

Adding student $matrikelnummer

"; + $newstudents[$matrikelnummer] = $student; + } elseif (!array_key_exists($pfach,$students[$matrikelnummer]["noten"])) { + echo "

Adding $pfach to student $matrikelnummer

"; + $newstudents[$matrikelnummer] = $student; + } else { + echo "

WARNING: student $matrikelnummer is already in database.

"; + } + if (empty($groups[$psemester][$pfach][$newgruppe])) { + if (empty($newgroups[$newgruppe])) { + $newgroups[$newgruppe] = [$matrikelnummer]; + } elseif (!in_array($matrikelnummer,$newgroups[$newgruppe])) { + $newgroups[$newgruppe][] = $matrikelnummer; + } else { + echo "

WARNING: student $matrikelnummer is already in group $newgruppe

"; + } + } elseif (!in_array($matrikelnummer,$groups[$psemester][$pfach][$newgruppe])) { + echo "

ERROR: TODO group $newgruppe without $matrikelnummer already in database but

"; + } else { + echo "

WARNING: group $newgruppe with $matrikelnummer already in database

"; + } + } + //echo "

",$vorname,$nachname,$matrikelnummer,$newgruppe,"

"; + } + ksort($newgroups); + $_SESSION["newstudents"] = $newstudents; + $_SESSION["newgroups"] = $newgroups; + $_SESSION["fach"] = $pfach; + $_SESSION["semester"] = $psemester; + } else { + echo "

Error: Could not open file

"; + return FALSE; + } + return; +} + +echo "
"; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; + +if (!empty($_POST["save"]) and $_POST["save"] === "save") { + foreach ($newstudents as $matrikelnummer => $student) { + if (empty($students[$matrikelnummer])) { + db_student_new($matrikelnummer,$student); + } elseif (empty($students[$matrikelnummer]["noten"][$pfach])) { + db_student_add_fach($matrikelnummer,$pfach); + } else { + echo "

ERROR: $matrikelnummer with $pfach already in database.

"; + } + } + foreach ($newgroups as $gname => $teilnehmerarray) { + db_group_new($psemester,$pfach,$gname,$teilnehmerarray); + } + $newstudents = []; + $newgroups = []; + echo "

Saved.

"; +} elseif (!empty($_POST["cancel"]) and $_POST["cancel"] === "cancel") { + $newstudents = []; + $newgroups = []; + echo "

Canceled.

"; +} elseif (!empty($_POST["upload"]) and $_POST["upload"] === "upload") { + $fname = $_FILES["csvfile"]["tmp_name"]; + $ftype = $_FILES["csvfile"]["type"]; + + if (!empty($fname)) { + if ($ftype !== "text/csv") { + echo "

ERROR: Filetype must be csv

"; + } else { + parseuserfile($fname); + } + } +} +if (!empty($newstudents) or !empty($newgroups)) { + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + foreach ($newgroups as $gname => $teilnehmera) { + foreach ($teilnehmera as $matrikelnummer) { + if (!empty($newstudents[$matrikelnummer])) { + $vorname = $newstudents[$matrikelnummer]["vorname"]; + $nachname = $newstudents[$matrikelnummer]["nachname"]; + } else { + $vorname = $students[$matrikelnummer]["vorname"]; + $nachname = $students[$matrikelnummer]["nachname"]; + } + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + } + echo "
SemesterPrüfungGruppeNachnameVorname
",$psemester,"",$pfach,"",$gname,"",$nachname,"",$vorname,"
"; + + echo ""; + echo ""; +} + +echo "
"; + +?> + + + \ No newline at end of file diff --git a/admin-show.php b/admin-show.php new file mode 100644 index 0000000..10394d8 --- /dev/null +++ b/admin-show.php @@ -0,0 +1,154 @@ + + + + + +

Listenansicht

+ + + + + + + +
+ Add students + + Show students + + Logout +
+ +"; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +//echo ""; +echo ""; +//echo "
SemesterPrüfungGruppeNachnameVornameLaborKlausur
"; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo "
"; + +//echo "
"; +//echo ""; +foreach ($groups as $semester => $pruefungen) { + if ($selectedsemester === "alle" or $selectedsemester === $semester) { + foreach ($pruefungen as $pruefung => $groupsperpruefung) { + if ($selectedpruefung === "alle" or $selectedpruefung === $pruefung) { + foreach ($groupsperpruefung as $groupname => $teilnehmerarray) { + foreach ($teilnehmerarray as $matrikelnummer) { + echo ""; + echo ""; + echo ""; + echo ""; + $student = $students[$matrikelnummer]; + $nachname = $student["nachname"]; + $vorname = $student["vorname"]; + if (!empty($student["noten"][$pruefung]["klausur"])) { + $klausurnote = $student["noten"][$pruefung]["klausur"]; + } else { + $klausurnote = ""; + } + if (!empty($student["noten"][$pruefung]["labor"])) { + $labornote = $student["noten"][$pruefung]["labor"]; + } else { + $labornote = ""; + } + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + } + } + } + } +} +echo "
$semester $pruefung $groupname $nachname $vorname
"; +echo ""; +echo "
"; +?> + + + \ No newline at end of file diff --git a/admin-update.php b/admin-update.php new file mode 100644 index 0000000..f0d3896 --- /dev/null +++ b/admin-update.php @@ -0,0 +1,39 @@ + $pruefungen) { + foreach ($pruefungen as $fach => $teilpruefungen) { + foreach ($teilpruefungen as $teilpruefung => $semesterliste) { + foreach ($semesterliste as $semestername => $note) { + if (!array_key_exists($fach,$students[$matrikelnummer]["noten"])) { + var_dump($students[$matrikelnummer]); + echo "

ERROR: Fach $fach bei $matrikelnummer existiert nicht

"; + } else { + if (!empty($note) and ( + empty($students[$matrikelnummer]["noten"][$fach][$teilpruefung]) or + $students[$matrikelnummer]["noten"][$fach][$teilpruefung] !== $note)) { + if (($teilpruefung === "klausur" and in_array($note,$notenklausur) or + $teilpruefung === "labor" and in_array($note,$notenlabor))) { + $students[$matrikelnummer]["noten"][$fach][$teilpruefung] = $note; + db_student_update_note($matrikelnummer,$fach,$teilpruefung,$note); + break; + } else { + var_dump($students[$matrikelnummer]); + echo "

ERROR: Note $note ungueltig fuer $matrikelnummer,$fach,$teilpruefung

"; + } + } + } + } + } + + } +} + +?> \ No newline at end of file diff --git a/database.php b/database.php new file mode 100644 index 0000000..9c14920 --- /dev/null +++ b/database.php @@ -0,0 +1,138 @@ + date('Y-m-d H:i:s', time()), + "cmd" => "student_new", + "matrikelnummer" => $matrikelnummer, + "vorname" => $student["vorname"], + "nachname" => $student["nachname"], + "noten" => $student["noten"] + ); + $json_string = json_encode($json_student_add, JSON_UNESCAPED_UNICODE)."\n"; + $fh = fopen("database.json", "a"); + fwrite($fh,$json_string); + fclose($fh); + + //echo $json_string; +} + +function db_student_add_fach($matrikelnummer,$fach) { + date_default_timezone_set("UTC"); + $cmd = array ( + "time" => date('Y-m-d H:i:s', time()), + "cmd" => "student_add_fach", + "matrikelnummer" => $matrikelnummer, + "fach" => $fach + ); + $json_string = json_encode($cmd, JSON_UNESCAPED_UNICODE)."\n"; + $fh = fopen("database.json", "a"); + fwrite($fh,$json_string); + fclose($fh); +} + +function db_student_update_note($matrikelnummer,$fach,$teilpruefung,$note) { + date_default_timezone_set("UTC"); + $cmd = array ( + "time" => date('Y-m-d H:i:s', time()), + "cmd" => "note_upd", + "fach" => $fach, + "teilpruefung" => $teilpruefung, + "note" => $note, + "matrikelnummer" => $matrikelnummer + ); + $json_string = json_encode($cmd, JSON_UNESCAPED_UNICODE)."\n"; + $fh = fopen("database.json", "a"); + fwrite($fh,$json_string); + fclose($fh); +} + +function db_group_new($semester,$fach,$gname,$teilnehmerarray) { + date_default_timezone_set("UTC"); + $cmd = array ( + "time" => date('Y-m-d H:i:s', time()), + "cmd" => "group_new", + "semester" => $semester, + "fach" => $fach, + "name" => $gname, + "teilnehmer" => $teilnehmerarray + ); + $json_string = json_encode($cmd, JSON_UNESCAPED_UNICODE)."\n"; + $fh = fopen("database.json", "a"); + fwrite($fh,$json_string); + fclose($fh); + //echo $json_string; +} + +function db_read () { + global $students,$groups,$pfp; + $fh = fopen("database.json", "r"); + if ($fh === FALSE) { + echo "

Cannot open database.json

"; + return FALSE; + } + while ($line = fgets($fh)) { + $cmd = json_decode($line,JSON_UNESCAPED_UNICODE); + switch ($cmd["cmd"]) { + case "student_new" : + $matrikelnummer = $cmd["matrikelnummer"]; + if (empty($students[$matrikelnummer])) { + $students[$matrikelnummer]["vorname"] = $cmd["vorname"]; + $students[$matrikelnummer]["nachname"] = $cmd["nachname"]; + $students[$matrikelnummer]["noten"] = $cmd["noten"]; + $fach = array_key_first($cmd["noten"]); + $students[$matrikelnummer]["history"][] = $cmd["time"]." student new with ".$fach; + } else { + echo "

ERROR: Student ",$matrikelnummer," is already in database.

"; + } + break; + case "student_add_fach" : + $matrikelnummer = $cmd["matrikelnummer"]; + $fach = $cmd["fach"]; + if (empty($students[$matrikelnummer])) { + echo "

ERROR: Cannot add $fach to $matrikelnummer as student is not in database.

"; + } elseif (array_key_exists($fach,$students[$matrikelnummer]["noten"])) { + echo "

ERROR: $fach already exists for $matrikelnummer in database.

"; + } else { + $students[$matrikelnummer]["noten"][$fach] = []; + $students[$matrikelnummer]["history"][] = $cmd["time"]." add ".$fach; + } + break; + case "group_new" : + $semester = $cmd["semester"]; + $fach = $cmd["fach"]; + $gname = $cmd["name"]; + if (empty($groups[$semester][$fach][$gname])) { + $groups[$semester][$fach][$gname] = $cmd["teilnehmer"]; + } else { + echo "

ERROR: Group $gname for $fach in $semester is already in database.

"; + } + break; + case "note_upd": + $fach = $cmd["fach"]; + $teilpruefung = $cmd["teilpruefung"]; + $matrikelnummer = $cmd["matrikelnummer"]; + $note = $cmd["note"]; + $students[$matrikelnummer]["noten"][$fach][$teilpruefung] = $note; + $students[$matrikelnummer]["history"][] = $cmd["time"]." ".$fach."/".$teilpruefung.": ".$note; + break; + default : + echo "

ERROR: database cmd ", $cmd["cmd"],"is unknown.

"; + } + } + fclose($fh); +} + +// Search user with name and return matrikelnummer if found +function db_find_user($vorname,$nachname) { + global $students; + foreach ($students as $matrikelnummer => $student) { + if ($student["vorname"] === $vorname and $student["nachname"] === $nachname) { + return $matrikelnummer; + break; + } + } + return FALSE; +} +?> \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..3997484 --- /dev/null +++ b/index.php @@ -0,0 +1,46 @@ + + + + +

Ergebnisse der Portfolioprüfungen

+

Hier können sie die Teilleistungen der Portfolioprüfungen für + die Veranstaltungen „Technische Informatik für EIT/ME“ und + „Digitaltechnik für TI“ einsehen. Sie müssen für den Login im Netz + der Hochschule oder über VPN mit dem Hochschulnetz verbunden sein. +

+ +
+ +
+ +
+ +
+Login hat funktioniert. Leider habe ich sie nicht in der + Datenbank gefunden.

"; + } elseif ($login === "failed") { + echo "

Login failed

"; + } + echo ""; + echo ""; +} +?> \ No newline at end of file diff --git a/login.php b/login.php new file mode 100644 index 0000000..a767266 --- /dev/null +++ b/login.php @@ -0,0 +1,47 @@ + + 100) { + return "failed"; + } + if (strlen($password) < 8 or strlen($password) > 1000) { + return "failed"; + } + $ldapserver = "ldap://ldap.hs-augsburg.de"; + $ldapusertree = 'ou=People, dc=fh-augsburg, dc=de'; + + $ldapconn = ldap_connect($ldapserver) + or die ("Cannot connect to ldap server ".$ldapserver); + ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); + ldap_set_option($ldapconn, LDAP_OPT_NETWORK_TIMEOUT, 3); + + $ldapbind = ldap_bind($ldapconn,"uid=$username, ".$ldapusertree,$password); + if ($ldapbind) { + // Login was successfull + session_regenerate_id(TRUE); + $sr=ldap_search($ldapconn,$ldapusertree,"uid=$username",["sn","givenname"]); + $info = ldap_get_entries($ldapconn,$sr); + ldap_unbind($ldapconn); + $vorname = $info[0]["givenname"][0]; + $nachname = $info[0]["sn"][0]; + $matrikelnummer = db_find_user($vorname,$nachname); + if (in_array($username,$admins)) { + $_SESSION["login"] = "admin"; + return "admin"; + } elseif ($matrikelnummer) { + $_SESSION["login"] = "user"; + $_SESSION["myusername"] = $username; + $_SESSION["mymatrikelnummer"] = $matrikelnummer; + return "user"; + } else { + $_SESSION["login"] = "nodb"; + return "nodb"; + } + } else { + $_SESSION["login"] = "failed"; + return "failed"; + } +} +?> \ No newline at end of file diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..5fec951 --- /dev/null +++ b/logout.php @@ -0,0 +1,18 @@ + \ No newline at end of file diff --git a/setup.php b/setup.php new file mode 100644 index 0000000..640ee56 --- /dev/null +++ b/setup.php @@ -0,0 +1,93 @@ + 1, + 'cookie_httponly' => 1, + 'cookie_secure' => $secure, // Only if using HTTPS + 'cookie_samesite' => 'Strict', // or 'Lax' + 'use_only_cookies' => 1 + ]); + // Set session timeout + if (isset($_SESSION['LAST_ACTIVITY']) && + (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) { // 30 minutes + session_unset(); + session_destroy(); + } + $_SESSION['LAST_ACTIVITY'] = time(); +} + +$pfp = array ( + "ti" => array ( + "name" => "Technische Informatik", + "pnr" => ["1710080", "3707100"], + "studiengang" => ["EI", "ME"] + ), + "dt" => array ( + "name" => "Digitaltechnik", + "pnr" => ["3976090"], + "studiengang" => ["TI"] + ) +); + +$notenlabor = ["BE", "NB", "AB", "NM", "NA"]; +$notenklausur = ["100","130","170","200","230","270","300","330","370","400","500"]; + +$students = array ( + "12345" => array ( + "vorname" => "Karl", + "nachname" => "Meier", + "studiengang" => "EI", + "noten" => array ( + "ti" => array ( + "klausur" => "500", + "labor" => "BE" + ), + "dt" => [] + ) + ), + "11111" => array ( + "vorname" => "Claudia", + "nachname" => "Darbo", + "studiengang" => "ME", + "noten" => array("ti" => [],"dt" => []) + ), + "22222" => array ( + "vorname" => "Günther", + "nachname" => "Kohl", + "studiengang" => "TI", + "noten" => array("ti" => [],"dt" => []) + ) +); + +$groups = array ( + "WiSe 2025/26" => array ( + "ti" => array ( + "G99-AA" => ["12345", "11111"], + "G99-ZZ" => ["22222", "11111"] + ) + ), + "SoSe 2025" => array ( + "ti" => array ( + "G99-AA" => ["11111"], + "G98-ZZ" => ["22222"] + ), + "dt" => array ( + "G99-KK" => ["11111"], + "G37-ZZ" => ["22222","12345"] + ) + ) +); + +db_read(); + +} //setupdone +?> diff --git a/show-user.php b/show-user.php new file mode 100644 index 0000000..f0441c7 --- /dev/null +++ b/show-user.php @@ -0,0 +1,133 @@ + + + + + + + + + +
+ Logout +
+ +$nachname, $vorname ($matrikelnummer)"; + echo "

Status

"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + foreach ($students[$matrikelnummer]["noten"] as $fach => $notenliste) { + $fachname = $pfp[$fach]["name"]; + if (!empty($notenliste["klausur"])) { + $klausurnote = $notenliste["klausur"]; + } else { + $klausurnote = "-"; + } + if (!empty($notenliste["labor"])) { + $labornote = $notenliste["labor"]; + } else { + $labornote = "-"; + } + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + echo "
FachLaborKlausur
$fachname$labornote$klausurnote
"; + + echo "

Gruppen

"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + foreach ($groups as $semestername => $fachliste) { + foreach ($fachliste as $fachname => $gruppenliste) { + foreach ($gruppenliste as $gname => $teilnehmerliste) { + if (in_array($matrikelnummer, $teilnehmerliste)) { + $tnnamensliste = ""; + foreach ($teilnehmerliste as $tnmat) { + if (empty($tnnamensliste)) { + $tnnamensliste = $students[$tnmat]["nachname"]; + } else { + $tnnamensliste = $tnnamensliste.", ".$students[$tnmat]["nachname"]; + } + } + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + } + } + } + echo "
SemesterFachGruppennameTeilnehmer
$semestername$fachname$gname$tnnamensliste
"; + + echo "

Geschichte

"; + echo ""; + echo ""; + echo ""; + echo ""; + foreach ($students[$matrikelnummer]["history"] as $ereignis) { + echo ""; + echo ""; + echo ""; + } + echo "
Ereignisliste
$ereignis
"; +} else { + echo "

Error

"; +} +?> + + + \ No newline at end of file -- cgit v1.2.3