Version: 2.2.0
Für ILIAS: 9.0 – 9.24
Das ExtendedTestSettings Plugin erweitert ILIAS-Tests um Funktionen für Online-Prüfungen. Es basiert auf einem modularen System: Funktionalität wird in eigenständigen Modulen gebündelt, die über die Plugin-Administration als ZIP hochgeladen, aktiviert und deaktiviert werden können – ohne den Plugin-Kern zu ändern.
- Modulare Architektur – Module als eigenständige ZIP-Pakete installier-, aktivier- und aktualisierbar, ohne den Plugin-Kern zu ändern
- Modul-Updates aus einem Repository – automatische Update-Prüfung gegen ein konfigurierbares GitHub-Repository
- Pro-Test-Konfiguration – eigener Sub-Tab „Erweiterte Test-Einstellungen“ in jedem Test
- Steuerbare Sichtbarkeit – System-Administratoren, Kurs-Administratoren oder eine Benutzer-Whitelist
- Zentrales Geräte-Inventar – IP → Koffer/Gerät-Zuordnung per CSV-Import, nutzbar für Module
- Mehrsprachigkeit – Deutsch/Englisch für Kern und Module
- Eigene Module – über ein schlankes Interface beliebig erweiterbar
Ein Auszug der verfügbaren Module findet sich unter Module.
# 1. Plugin klonen
cd <pathtoplugin>
git clone https://github.com/andreschweigert/ExtendedTestSettings ExtendedTestSettings
# 2. ACL setzen: modules/-Verzeichnis für den Web-User beschreibbar machen
setfacl -R -m u:www-data:rwx <pathtoplugin>/ExtendedTestSettings/modules
setfacl -dm u:www-data:rwx <pathtoplugin>/ExtendedTestSettings/modules
# 3. In ILIAS installieren und aktivieren
# Administration → Plugins → ExtendedTestSettings → Installieren → Aktivieren
# 4. Einmalig Classmap + ilCtrl-Artefakte regenerieren
cd /pfad/zu/ilias
composer dump-autoload
<pathtoplugin>=.../Customizing/global/plugins/Services/UIComponent/UserInterfaceHook/
Nach der Aktivierung erscheint in jedem ILIAS-Test ein neuer Sub-Tab "Erweiterte Test-Einstellungen", in dem die Module einzeln konfiguriert werden können.
cd <pathtoplugin>
git clone https://github.com/andreschweigert/ExtendedTestSettings ExtendedTestSettingsDas modules/-Verzeichnis muss vom Web-Server beschreibbar sein, damit Admins Module über die Oberfläche hochladen können:
setfacl -R -m u:www-data:rwx <pathtoplugin>/ExtendedTestSettings/modules
setfacl -dm u:www-data:rwx <pathtoplugin>/ExtendedTestSettings/modulesDie Default-ACL (
-dm) sorgt dafür, dass auch zukünftig angelegte Dateien und Ordner innerhalb vonmodules/automatisch die richtigen Rechte erhalten.
- Als Administrator einloggen
- Administration → Plugins → ExtendedTestSettings → Installieren → Aktivieren
Damit ILIAS die Plugin-Klassen und deren Controller-Sicherheitsregeln erkennt, müssen die Composer-Classmap und ilCtrl-Artefakte regeneriert werden:
cd /pfad/zu/ilias
composer dump-autoload
composer dump-autoloaderzeugt in ILIAS 9 über den Composer-Hook auch die ilCtrl-Artefakte. Den Befehl nach der Erstinstallation und nach Änderungen an Plugin-Klassen ausführen. Bei späteren Modul-Installationen über ZIP ist er nicht erforderlich.
- Einen beliebigen Test öffnen → Einstellungen
- Sub-Tab "Erweiterte Test-Einstellungen" muss sichtbar sein
- Administration → Plugins → ExtendedTestSettings → Module – die Modulliste sollte erscheinen
Alle Module (ExamCalc, ExamSymbols, ExamGuard, ExamAlert, ExamChecker, ExamConnGuard) sind extern und müssen separat installiert werden:
Administration → Plugins → ExtendedTestSettings → Module → ZIP hochladen
Die ZIPs sind im Module-Repository verfügbar.
- Plugin-Dateien auf Version 2.2.0 aktualisieren.
- Im ILIAS-Hauptverzeichnis
composer dump-autoloadausführen, damit Classmap und ilCtrl-Artefakte aktualisiert werden. - Unter Administration → Plugins → ExtendedTestSettings das Plugin aktualisieren.
- Das Speichern der erweiterten Testeinstellungen und den Zugriff auf Hilfsmittelblätter mit einem laufenden Testdurchlauf prüfen.
Installierte Module werden weiterhin separat verwaltet. Die Änderungen dieser Version betreffen den Plugin-Kern.
Jedes Modul ist ein eigenständiges Paket, das folgendes liefert:
- PHP-Handler der das
ilExamModuleInterfaceimplementiert - Assets (CSS, JS, HTML-Templates) für den Testplayer
- Datenbanktabellen die beim Install angelegt und beim Deinstall entfernt werden
- Optional: eine eigene GUI-Seite (z.B. für Verwaltungsoberflächen)
Der Plugin-Kern lädt den Code eines Moduls nur wenn es aktiv ist. Deaktivierte oder nicht installierte Module sind für PHP vollständig unsichtbar.
Externe Module (modules/<id>/) werden vom Admin hochgeladen:
- Standardmäßig inaktiv nach Installation
- Können installiert, deinstalliert, aktiviert und deaktiviert werden
- Update durch erneutes Hochladen eines neuen ZIP
- Verfügbar im Module-Repository
Administration → Plugins → ExtendedTestSettings → Module → ZIP hochladen
Nach dem Upload das Modul in der Liste aktivieren.
MeinModul_v1.0.0.zip
├── module.json ← Pflicht: Metadaten + Handler-Referenz
├── class.ilMeinModulHandler.php
├── sql/
│ ├── install.php ← DB-Tabellen anlegen
│ └── uninstall.php ← DB-Tabellen löschen
├── css/ ← Optional
├── js/ ← Optional
└── templates/ ← Optional
Das ZIP darf einen Wrapper-Ordner enthalten (wie beim GitHub-Download) – der Installer erkennt und überspringt ihn automatisch.
Das Paket muss genau eine module.json an der Paketwurzel enthalten; bei einem Wrapper liegt sie direkt darunter. Weitere Dateien namens module.json, doppelte Dateipfade und Pfad-Aliase werden abgelehnt. Vor der Installation wird das entpackte Manifest mit dem zuvor geprüften Manifest verglichen.
{
"id": "meinmodul",
"label": "Mein Modul",
"description": "Kurze Beschreibung.",
"version": "1.0.0",
"ilias_min": "9",
"ilias_max": "12",
"handler_class": "ilMeinModulHandler",
"handler_file": "class.ilMeinModulHandler.php",
"gui_file": "class.ilMeinModulGUI.php",
"gui_class": "ilMeinModulGUI",
"require_files": [],
"tables": ["meinmodul_settings"]
}gui_file und gui_class sind nur nötig wenn das Modul eine eigene Verwaltungsseite hat.
Alle Module werden separat im Module-Repository gepflegt und versioniert. Dort finden sich jeweils die ZIP-Downloads, Dokumentation und Changelogs der einzelnen Module.
Auszug der verfügbaren Module:
- ExamCalc – Taschenrechner (einfach + wissenschaftlich mit 2nd-Ebene, Verlauf, Speicher)
- ExamSymbols – Sonderzeichen-Paletten (Mathematik, Sprachen, Naturwissenschaften)
- ExamGuard – Prüfungsschutz (Blockiert Rechtsklick, Copy/Paste, DevTools)
- ExamAlert – Zeitwarnung vor Prüfungsende (konfigurierbare Warnzeit + Nachricht)
- ExamChecker – Einstellungsprüfung gegen konfigurierbare Soll-Werte (Präsenz-/Fernprüfung)
- ExamConnGuard – Verbindungs-Schutz bei WLAN-Ausfällen (On-Demand-Probe, Overlay, Auto-Replay)
Administration → Plugins → ExtendedTestSettings → Konfigurieren:
- Tab-Sichtbarkeit: Wer sieht den "Erweiterte Test-Einstellungen"-Sub-Tab?
- System-Administratoren
- Kurs-Administratoren (Standard)
- Spezifische Benutzer (Whitelist)
- ExamAlert Auto-Aktivierung: ExamAlert für neue Tests automatisch einschalten
- ExamChecker (eigener Reiter): je Prüfungstyp festlegen, welche Test-Einstellungen geprüft werden und welchen Soll-Wert sie haben sollen (ab ExamChecker 2.0.0)
Für die automatische Update-Prüfung eine Repository-URL im Format https://github.com/OWNER/REPO und den gewünschten Branch konfigurieren. ZIP-Downloads müssen über HTTPS von github.com oder raw.githubusercontent.com aus genau diesem Repository kommen. Diese Regeln gelten auch für Weiterleitungen; URLs mit Query-Parametern oder Fragmenten werden abgelehnt. Alternativ lassen sich Modul-ZIPs über die Oberfläche hochladen.
Test → Einstellungen → Erweiterte Test-Einstellungen:
Jedes aktive Modul zeigt hier seine eigenen Einstellungsfelder. Änderungen gelten nur für den jeweiligen Test.
Das zugehörige Modul muss global aktiviert sein. Teilnehmende benötigen aktuelle Leserechte am Test und einen gestarteten, noch offenen Durchlauf. Der Test muss online sein; Prüfungsbeginn, Prüfungsende und Bearbeitungszeit werden geprüft, einschließlich individueller Zeitverlängerungen. Die Dateien werden ohne Browser-Cache ausgeliefert. Prüfende mit Schreibrecht können die Dateien auch außerhalb eines laufenden Durchlaufs abrufen, sofern das Modul aktiv ist.
ExtendedTestSettings/
├── classes/
│ ├── Contracts/
│ │ └── ilExamModuleInterface.php ← Interface für alle Handler
│ ├── Module/
│ │ ├── ilModuleRegistry.php ← Discovery + Active-State
│ │ └── ilModuleInstaller.php ← ZIP-Upload, DB-Setup
│ ├── class.ilExtendedTestSettingsPlugin.php
│ ├── class.ilExtendedTestSettingsUIHookGUI.php
│ ├── class.ilExtendedTestSettingsAdvancedGUI.php ← Test-Settings GUI
│ ├── class.ilExtendedTestSettingsConfigGUI.php ← Admin-Konfiguration
│ └── class.ilExtendedTestSettingsModuleProxyGUI.php ← Proxy-Router für externe GUIs
├── modules/ ← Externe installierte Module (nicht versioniert)
├── sql/
│ └── dbupdate.php ← ILIAS DB-Migrationen
└── plugin.php ← Plugin-Metadaten
Das Plugin ist als Plattform konzipiert. Eigene Module können als ZIP-Pakete entwickelt und über die Admin-Oberfläche installiert werden.
Ein Modul besteht mindestens aus:
class ilMeinModulHandler implements ilExamModuleInterface
{
public function isEnabled(int $ref_id): bool { ... }
public function injectAssets(ilGlobalTemplateInterface $tpl, int $ref_id): void { ... }
public function saveSettings(int $ref_id, array $post_data): bool { ... }
public function getFormItems(int $ref_id): array { ... }
}Die Entwicklerdokumentation unter .dev/ModuleEntwicklung.md und die Tests unter .tests/ werden lokal gepflegt und sind nicht Bestandteil des Git-Repositories.
Entwickler:
- André Schweigert (Andre.Schweigert@fau.de)
- Cornel Musielak (Cornel.Musielak@fau.de)
Institution: Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
Repository: https://github.com/andreschweigert/ExtendedTestSettings
Der Plugin-Kern ist unter der GNU Affero General Public License, Version 3 ausschließlich (AGPL-3.0-only) veröffentlicht. Der vollständige Lizenztext liegt in LICENSE. Die ursprünglichen Autoren sind in AUTHORS.md aufgeführt.
Für die ursprünglichen Bestandteile dieses Projekts gilt zusätzlich die in NOTICE formulierte Bedingung nach AGPLv3, Abschnitt 7(b): Die Autorenangabe „Ursprüngliche Entwicklung: André Schweigert und Cornel Musielak“ muss im betreffenden Material und in den angezeigten rechtlichen Hinweisen erhalten bleiben. In der Oberfläche kann sie auf einer zugänglichen Informations- oder Rechtshinweisseite stehen; sie muss nicht auf jeder Seite erscheinen. Weitere Beteiligte dürfen ihre eigenen Beiträge zusätzlich nennen.
Nutzung, Änderungen, Weitergabe und kommerzielle Nutzung sind unter den Lizenzbedingungen erlaubt. Wer eine geänderte Version über ein Netzwerk betreibt, muss den damit interagierenden Nutzern den entsprechenden Quellcode dieser Version kostenlos anbieten (Abschnitt 13). Der Download muss zur tatsächlich eingesetzten Version passen; ein Link auf ein unverändertes Upstream-Repository genügt für eigene Änderungen nicht. Eine Rückgabe der Änderungen an dieses Projekt ist nicht vorgeschrieben.
Die Lizenzierung des Plugin-Kerns ändert nicht automatisch die Lizenzen von ILIAS oder separat installierten Modulen. Bei einer Kombination mit ILIAS unter GPLv3 ist Abschnitt 13 der AGPLv3 zu beachten, insbesondere der Umfang des bereitzustellenden Quellcodes. Module und weitere Fremdkomponenten müssen unter mit der jeweiligen Kombination vereinbaren Bedingungen verwendet werden.
Das Plugin wird ohne Gewährleistung im Rahmen der Abschnitte 15 und 16 der AGPLv3 bereitgestellt. Vor dem Einsatz in Produktiv-Prüfungen in einer Testumgebung prüfen.
- Plugin-Kern unter AGPLv3 (AGPL-3.0-only) mit zusätzlicher Autorenangabe nach
Abschnitt 7(b) veröffentlicht. Lizenztext, Autorenliste und Attribution sind
in
LICENSE,AUTHORS.mdundNOTICEenthalten; die Plugin-Administration zeigt die ursprünglichen Autoren und Lizenzhinweise auf Deutsch und Englisch. - Modul-Downloads prüfen Repository, HTTPS und Pfad vor jedem Abruf, einschließlich
aller Redirects. Traversal, encodierte Pfadtrenner, fremde Hosts/Repositories,
andere Ports sowie URLs mit Query oder Fragment werden abgelehnt. Unterstützt
werden direkte ZIP-Links aus dem konfigurierten GitHub-Repository auf
github.comundraw.githubusercontent.com. - Das Speichern von Testeinstellungen verlangt serverseitig POST und den gültigen ILIAS-Session-Token. Die Prüfung greift auch ohne neu erzeugtes ilCtrl-Artefakt.
- Modulmetadaten in der Administration und alle Einträge im Update-Protokoll werden als Text escaped, einschließlich Bestätigungs- und Upload-Meldungen.
- Der Hilfsmittel-Endpunkt prüft den globalen Aktivstatus des über die Registry ermittelten Tabellenbesitzers. Auch Prüfende erhalten bei deaktiviertem Modul keine Datei; fehlende oder uneindeutige Zuordnungen werden abgewiesen.
- Für Teilnehmende sind aktuelle Leserechte und ein gestarteter, offener
Durchlauf nötig. Online-Status, Prüfungsbeginn/-ende und Bearbeitungszeit werden
berücksichtigt, einschließlich individueller Zeitverlängerungen und Timer-Reset.
Dateien werden mit
Cache-Control: private, no-store, max-age=0ausgeliefert. - Modul-ZIPs müssen genau ein Paketmanifest an der Wurzel oder unter einem gemeinsamen Wrapper enthalten. Doppelte Dateipfade und Pfad-Aliase werden abgewiesen; vor dem Umschalten und der DB-Migration wird das entpackte Manifest vollständig mit dem geprüften Manifest verglichen.
ExamChecker-Konfiguration mit Soll-Werten:
- Der ExamChecker-Reiter legt jetzt nicht mehr nur fest, welche Einstellungen geprüft werden, sondern auch welchen Wert sie haben sollen — als Ja/Nein, Zahl, Auswahl oder Text
- Das Formular wird vollständig aus dem Check-Katalog des Moduls erzeugt
(
getCheckCatalogue()/getRules()/saveRules()); der Plugin-Kern kennt weder die geprüften Datenbankspalten noch die Sprachschlüssel des Moduls - Ältere ExamChecker-Versionen: der Reiter zeigt einen Hinweis statt eines halb funktionierenden Formulars
- Check-Definitionen und die zugehörigen
check_*-Sprachschlüssel sind aus dem Plugin-Kern ins Modul gewandert — die Liste stand bisher an drei Stellen und lief auseinander - Setzt ExamChecker 2.0.0 voraus (eigene Tabelle
examchecker_rules, ZIP-Upload nötig)
Sicherheits-Nacharbeit (Kern).
- Modul-Proxy löst Module nur noch über die Registry auf und prüft den Objekttyp:
deaktivierte Module sind über keinen Aufruf mehr erreichbar,
ref_idmuss auf einen Test zeigen (C-01, C-08). Gleiches gilt für die Modul-Tabs der Plugin-Konfiguration (Z-01). - CSRF: alle zustandsändernden Aktionen der Konfiguration laufen über
getFormAction()und erzwingen serverseitig POST; keine$_GET-Fallbacks mehr. Die Bereinigung verwaister Einträge verlangt jetzt eine Bestätigung (C-02). - Hilfsmittelblätter: HTML wird nicht mehr im ILIAS-Kontext gerendert (Auslieferung als Download, eigene restriktive CSP statt entfernter Header). Die Anzeige im Testplayer bleibt unverändert (C-03).
- Zugriff auf Hilfsmittelblätter setzt einen laufenden, nicht abgegebenen Testdurchlauf voraus. Behebt zugleich einen Fehler, durch den die Prüfung wegen einer verwechselten Test-ID nie zutraf (C-07).
- Benutzer-Whitelist steuert nur noch die Sichtbarkeit; der Zugriff auf einen konkreten Test verlangt zusätzlich ein Recht daran (C-04).
- Modulinstallation ist atomar: Staging-Verzeichnis, Prüfung auf Vollständigkeit,
Umschalten per
rename(), Rollback auf den alten Stand bei Fehlern. Alle Dateisystem-Rückgabewerte werden ausgewertet (C-05). - Deinstallation eines Moduls bricht ab, wenn die Datenbereinigung scheitert — das Modul bleibt für einen erneuten Versuch erhalten (C-06).
- Modulupdate wird an die bestätigte Modul-ID und Version gebunden und vor der Installation gegen das heruntergeladene Paket geprüft (C-09).
- ZIP-/Download-Grenzen gegen Dekompressions-DoS: Einträge, entpackte Größe, Einzeldateigröße und Kompressionsverhältnis werden vor dem Entpacken geprüft, Downloads laufen gestreamt statt komplett im Speicher (C-10).
- Manifest-Validierung ist für Installer, Registry und Proxy vereinheitlicht; alle
Dateipfade werden per
realpath()in den Modulordner gezwungen (C-11). - Plugin-Deinstallation entfernt alle vom Kern angelegten Tabellen (u. a.
etest_hosts) und protokolliert das Ergebnis je Tabelle (C-12). - Modulfehler werden an den Modulgrenzen als
Throwableabgefangen — ein fehlerhaftes Modul kann den Testplayer nicht mehr lahmlegen (C-13). - Versionsangabe kommt nur noch aus
plugin.php; das permanente Debug-Panel im Update-Pfad ist entfernt (C-14, C-15).
- Sub-Tab „Erweiterte Test-Einstellungen" erscheint nur noch im Haupt-Tab „Einstellungen" von Test-Objekten (Prüfung auf aktiven Haupt-Tab statt auf CmdClass) — danke an @rfcmaXi für Meldung und Lösungsvorschlag (#8)
- Modulliste zeigt den Entwicklungsstand jedes Moduls (
maturityaus module.json) als Farbpunkt mit Label — Stufen: Konzept ⚪, Experimentell 🟠, Entwicklung 🟡, Test 🔵, Pilot 🟣, Erprobt 🟢, Eingestellt 🔴 (Definition:modules-zip/docs/entwicklungsstand.md)
Zentrales Geräte-Inventar:
- Neue Tabelle
etest_hosts(dbupdate Step 7): zentrale IP → Koffer/Gerät-Zuordnung als Plugin-Infrastruktur - Geräte-Tab mit CSV-Import nativ in der ConfigGUI (immer sichtbar)
- Module greifen nur lesend zu (LEFT JOIN über IP, mit
tableExists()-Guard) — keine Code-Abhängigkeit - Update-Reihenfolge beachten: erst Plugin aktualisieren (legt Tabelle an), dann Modul-ZIPs (z.B. ExamLogger ≥ 1.4.0, ExamBattery ≥ 1.1.0)
Mehrsprachigkeit (DE/EN):
- Hauptplugin auf ILIAS-Plugin-Sprachdateien umgestellt (
lang/ilias_de|en.lang) - Modul-i18n-Infrastruktur: Module bringen eigene
lang/-Dateien mit (ilModuleLanguage, Fallback-Kette Sprache → EN → Default)
Admin-GUI:
- Umstellung auf ILIAS-KitchenSink-Komponenten (Panels, MessageBox, Accordions)
- Modul-spezifische Tabs erscheinen nur bei aktivem Modul; neue Tabs für ExamNetQos und ExamKeymap
- Statistik-Tab dynamisch an installierte Module gekoppelt
Fixes & Aufräumarbeiten:
- ModuleProxyGUI: Debug-Logging entfernt (Header-/Session-Cookie-Leak in
serveResourceFile()) allow_student_accessausmodule.jsonrespektiert RBAC-Leserecht (ExamMessage)- Ungenutzten Legacy-Endpoint
ResourceFileGUIentfernt - dbupdate: Step-Marker
<#7>korrekt am Zeilenanfang (Step wurde sonst nicht erkannt)
Security Audit & Hardening:
- Auth + RBAC-Check im ModuleProxyGUI (F-002)
- SQL-Injection-Schutz durch Tabellennamen-Validierung in Installer + Registry (F-003)
- Scope-Isolation für install.php/uninstall.php + Audit-Logging (F-004)
- SSRF-Fix: Download-URL-Validierung prüft Host + Path-Prefix (F-005)
- Objekttyp-Prüfung in saveSettings() (F-008)
- Auto-Insert in getFallbackExamAlertStatus() entfernt (F-009)
- Allowlist-Validierung für ExamChecker POST-Daten (F-010)
- toggleModule/uninstallModule von GET auf POST umgestellt (F-011)
- Dead Code entfernt: searchUsersAjax(), addUser() (F-012)
- Path-Traversal-Schutz für require_files (F-013)
Breaking Changes:
- Module werden nicht mehr als Built-in mitgeliefert, sondern ausschließlich über das Module-Repository installiert
modules/-Verzeichnis benötigt ACL-Rechte (siehe Installation)
ExamCalc – 2nd-Funktionsebene & EE-Notation:
2nd-Taste schaltet10^xaufEE(wissenschaftliche Notation) um:2 EE 3= 2000- Visuelles Feedback:
2nd-Badge in der Status-Leiste, Button-Label wechselt - Shift-Modus setzt sich nach jedem Klick automatisch zurück
- Bugfix:
eist jetzt strikt die Eulersche Konstante — für wissenschaftliche Notation mussEEverwendet werden
Modulares System:
ilExamModuleInterfaceals gemeinsames Interface für alle HandlerilModuleRegistry: Auto-Discovery + Lazy-Loading (Code nur bei aktivem Modul)ilModuleInstaller: ZIP-Upload mit Validierung, Entpacken, DB-SetupilExtendedTestSettingsModuleProxyGUI: Proxy-Router für externe Modul-GUIs- Admin-UI: neuer "Module"-Tab mit Aktivieren/Deaktivieren + ZIP-Upload
modules/-Verzeichnis für externe Module
GUI-Refactoring:
- ConfigGUI und AdvancedGUI auf ILIAS KitchenSink UI-Komponenten umgestellt
- Statistik-Seite: Panel/Report-Layout mit Modul-Details
- ExamAlert Auto-Aktivierung für neue Tests
- ExamChecker: Konfigurierbare Standards
- Tab-Sichtbarkeit: Modus "Spezifische Benutzer"
- ExamSymbols: 8 Templates (neu: Physik, Chemie)
- Initial Release: ExamCalc, ExamSymbols, ExamGuard, ExamAlert, ExamChecker