Skip to content
Snippets Groups Projects
Commit 212c82c6 authored by Thomas Hackl's avatar Thomas Hackl
Browse files

Updated AdmissionRule documentation for Stud.IP 6.0

parent 67ea7c21
Branches
Tags
No related merge requests found
Checking pipeline status
...@@ -12,17 +12,22 @@ Ein Anmeldeset stellt einen Rahmen für Veranstaltungen dar, die gemeinsame Rege ...@@ -12,17 +12,22 @@ Ein Anmeldeset stellt einen Rahmen für Veranstaltungen dar, die gemeinsame Rege
### Aufbau einer Anmelderegel ### Aufbau einer Anmelderegel
Alle Anmelderegeln liegen im Ordner `lib/admissionrules`. Pro Regeltyp gibt es dort einen Ordner, in dem typischerweise die Klassendefinition der Regel liegt (`Regeltyp.class.php`, SQL-Anweisungen, die bei (De-)Installation der Regel ausgeführt werden müssen und templates zur Konfiguration und zur Kurzanzeige der Regel. Anmelderegeln liegen in zwei Ordnern:
- der PHP-Teil liegt in `lib/admissionrules`.
- die zugehörige Vue-Komponente liegt in `resources/vue/components/admission`.
In `lib/admissionrules/<unterordner>` liegen typischerweise die Klassendefinition der Regel (`Regeltyp.php`, SQL-Anweisungen, die bei (De-)Installation der Regel ausgeführt werden müssen und ein Template zur Kurzanzeige der Regel.
Im Folgenden soll das Beispiel `NightAdmission` entwickelt werden, eine Regel, die eine Anmeldung nur zwischen 22 und 6 Uhr zulässt. Im Folgenden soll das Beispiel `AdditionalDataAdmission` entwickelt werden, eine Regel, die die Eingabe zusätzlicher Daten (Telefonnummer und Semesteradresse) vor der Anmeldung erfordert.
#### Speichern und Laden der Daten #### Speichern und Laden der Daten
Die Regel vom Typ `NightAdmission` sollen alle in einer eigenen Tabelle `nightadmissions` in der Datenbank gespeichert werden. Da dieser Regeltyp neben dem standardmäßig vorhandenen Infotext keine weiteren Attribute besitzt, sieht diese Tabelle so aus: Die Regel vom Typ `AdditionalDataAdmission` sollen alle in einer eigenen Tabelle `additionaldataadmissions` in der Datenbank gespeichert werden. Diese kann so aussehen:
```sql ```sql
CREATE TABLE `nightadmissions` ( CREATE TABLE `additionaldataadmissions` (
`rule_id` VARCHAR(32) NOT NULL, `rule_id` CHAR(32) NOT NULL COLLATE latin1_bin,
`message` TEXT NOT NULL, `message` TEXT NOT NULL,
`phone` VARCHAR(255) NOT NULL,
`address` VARCHAR(1024) NOT NULL,
`mkdate` INT NOT NULL, `mkdate` INT NOT NULL,
`chdate` INT NOT NULL, `chdate` INT NOT NULL,
PRIMARY KEY (`rule_id`); PRIMARY KEY (`rule_id`);
...@@ -31,127 +36,58 @@ CREATE TABLE `nightadmissions` ( ...@@ -31,127 +36,58 @@ CREATE TABLE `nightadmissions` (
Wird dieser Regeltyp komplett aus dem System entfernt, so reicht folgende SQL-Anweisung zum Aufräumen: Wird dieser Regeltyp komplett aus dem System entfernt, so reicht folgende SQL-Anweisung zum Aufräumen:
```sql ```sql
DROP TABLE `nightadmissions`; DROP TABLE `additionaldataadmissions`;
DELETE FROM `courseset_rule` WHERE `type`='NightAdmission'; DELETE FROM `courseset_rule` WHERE `type`='AdditionalDataAdmission';
``` ```
#### Regeldefinition #### Regeldefinition (PHP)
Wir legen eine Datei `NightAdmission.class.php` an, die von der bereits vorhandenen Klasse `AdmissionRule` erbt. Da wir nur die aktuelle Uhrzeit berücksichtigen müssen, braucht diese Klasse keine eigenen, weiteren Attribute. Wir definieren nur, mit welchen anderen Anmelderegeltypen diese Regel kombinierbar ist (nämlich alle Standardregeln außer zeitgesteuerter und komplett gesperrter Anmeldung). Die PHP-Klasse für die Regel wird von `AdmissionRule` abgeleitet. Damit das Zusammenspiel mit der zugehörigen Vue-Komponente funktionieren kann, müssen mindestens diese beiden Methoden implementiert sein:
- `getPayload()` liefert ein Array mit den Attributen (und deren Werten), die für diesen Regeltyp spezifisch sind. In unserem Fall wären das also `phone` und `address` für die Telefonnummer und Semesteradresse.
Einige Standardmethoden müssen wir ebenfalls implementieren, um das Laden und Speichern in eigene Tabellen zu realisieren. - `setAllData($data)` empfängt ein Array mit den Werten, die für diese Regel spezifisch sind. Hier also wieder `phone` und `address`.
```php - Weiter ist die Methode `ruleApplies($user_id, $course_id)` wichtig, die ermittelt, ob die angegebene Person in die angegebene Veranstaltung eingetragen werden darf.
<?php
class NightAdmission extends AdmissionRule { #### Regeldefinition (Vue)
Die Vue-Komponente `AdditionalDataAdmission` implementiert sowohl die Oberfläche zur Regelkonfiguration als auch die Logik, die Daten an das PHP-Backend zu übergeben.
/** Die Komponente sollte das Mixin `AdmissionRuleMixin` verwenden und bekommt damit bereits die gesamte Kommunikations- und Wertetransferlogik eingebaut. Darüber hinaus braucht die Komponente neben ihrem Template nur folgende Attribute und Methoden:
* Standardkonstruktor - `data()` legt fest, welche eigenen Attribute es in dieser Komponente gibt. Das wären hier `phone` und `address` für Telefonnummer und Semesteradresse
*/ - ```javascript
public function __construct($ruleId=*, $courseSetId = *) payload() {
{ return {
parent::__construct($ruleId, $courseSetId); type: 'AdditionalDataAdmission',
$this->default_message = _("Sie können sich nur nachts zwischen 22 und 6 Uhr anmelden."); payload: {
if ($ruleId) { phone: this.phone,
// Regel bereits vorhanden, lade Daten. address: this.address,
$this->load();
} else {
// Erzeuge neue ID.
$this->id = $this->generateId('nightadmissions');
} }
return $this;
} }
/**
* Lösche aktuelle Regel aus der Datenbank.
*/
public function delete() {
parent::delete();
$stmt = DBManager::get()->prepare("DELETE FROM `nightadmissions` WHERE `rule_id`=?");
$stmt->execute(array($this->id));
}
/**
* Beschreibungstext für diesen Regeltyp, wird angezeigt, wenn eine neue
* Regel zu einem Anmeldeset hinzugefügt werden soll.
*/
public static function getDescription() {
return _("Diese Regel erlaubt die Anmeldung nur nachts zwischen 22 und 6 Uhr.");
}
/**
* Name für diesen Regeltyp, wird angezeigt, wenn eine neue Regel zu einem
* Anmeldeset hinzugefügt werden soll.
*/
public static function getName() {
return _("Nächtliche Anmeldung");
}
/**
* Holt das Template zur Anzeige der Konfiuration dieser Regel
* (configuration.php, hinterlegt im Unterordner templates). Für unser
* Beispiel brauchen wir nur das Standardtemplate, da es nichts eigenes*
* für diesen Regeltyp zu konfigurieren gibt.
*/
public function getTemplate() {
$tpl = $GLOBALS['template_factory']->open('admission/rules/configure');
$tpl->set_attribute('rule', $this);
return $tpl->render();
}
/**
* Lädt die Regel aus der Datenbank.
*/
public function load() {
$rule = DBManager::get()->fetch("SELECT * FROM `nightadmissions` WHERE `rule_id`=? LIMIT 1", array($this->id));
$this->message = $rule['message'];
return $this;
}
/**
* Diese Funktion überprüft, ob sich der gegebene Benutzer zur gegebenen
* Veranstaltung anmelden darf, ob die Regel also greift.
* Zurückgegeben wird eine Fehlermeldung, falls die Anmeldung nicht
* möglich ist.
*/
public function ruleApplies($userId, $courseId) {
$failed = array();
$now = mktime();
// Zeit zwischen 6 und 22 Uhr => keine Anmeldung erlaubt.
if (date('H', $now) < 22 && date('H', $now) >= 6) {
$failed[] = $this->default_message;
} }
return $failed; ```
Diese Methode ist `computed` und liefert die regelspezifischen Attribute zur Übertragung an die JSON-API-Route zur Speicherung
- Weiter werden noch zwei Methoden benötigt, um die eingebenen Daten von außen setzen und beim Speichern validieren zu können:
```javascript
setRuleData(data) {
this.phone = data.attributes.payload.phone;
this.address = data.attributes.payload.address;
},
validate() {
this.invalidData = [];
if (this.phone === '') {
this.invalidData.push(this.$gettext('Es ist keine Telefonnummer angegeben.'));
} }
/** if (this.address === '') {
* Speichert die aktuelle Regel in der Datenbank. this.invalidData.push(this.$gettext('Es ist keine Semesteradresse angegeben.'));
*/
public function store() {
$stmt = DBManager::get()->prepare("INSERT INTO `nightadmissions`
(`rule_id`, `message`, `mkdate`, `chdate`)
VALUES
(:id, :message, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())
ON DUPLICATE KEY
UPDATE `message`=VALUES(`message`), `chdate`=VALUES(`chdate`)");
$stmt->execute(array('id' => $this->id, 'message' => $this->message));
return $this;
} }
return this.invalidData.length === 0;
} }
``` ```
#### Verknüpfung Vue-Komponente mit Regeltyp
Am wichtigsten sind die beiden Methoden `ruleApplies` und `getTemplate`. Damit Stud.IP weiß, welche Vue-Komponente zu diesem Regeltyp gehört, muss diese Verknüpfung in `STUDIP.Admission.availableRules` hergestellt werden:
```javascript
Erstere Methode spezifiert das Verhalten der Regel, also wann und unter welchen Voraussetzungen überhaupt eine Anmeldung erfolgreich sein kann. Hier können im Prinzip beliebige Datenbankabfragen oder sonstige anderen Funktionen aufgerufen werden. STUDIP.Admission.availableRules.AdditionalDataAdmission = 'AdditionalDataAdmission.vue'
```
Das Template definiert die GUI zur Konfiguration der jeweiligen Regel. Standardmäßig wird nur ein Textfeld angeboten, das einen Text aufnehmen kann, der vor der Anmeldung auf der Veranstaltungsseite erscheint. Will man hier weitere Werte, Checkboxen oder anderes einstellbar machen, muss man selbst ein [Flexi-Template](FlexiTemplates) dafür schreiben. Hier muss der Pfad der Komponente relativ zu `resources/vue/components/admission` angegeben werden.
Daneben kann es noch ein Info-Template geben, das nur zur Anzeige der Regel in normalem Prosatext dient.
### Zusammenfassung
Um diese Beispielregel in Stud.IP zu installieren, reicht es, in `lib/admissionrules` einen Ordner `nightadmissions` zu erstellen, dort die obige Klasse `Nightadmission.class.php` hineinzukopieren und die nötigen SQL-Anweisungen auszuführen. Da kein eigenes Template benötigt wird, ist hier auch kein Unterordner `templates` von Nöten. In der **globalen Konfiguration** unter **Anmelderegeln ** kann die Regel dann aktiviert werden. An gleicher Stelle muss dann unter **Regelkompatibilität** eingestellt werden, mit welchen vorhandenen Regelndie neue Regel kombinierbar ist.
## Verteilungsalgorithmus ## Verteilungsalgorithmus
Der Algorithmus, der die Plätze der Veranstaltungen eines Anmeldesets verteilt, kann ebenfalls frei selbst implementiert werden. Standardmäßig wird bereits ein Algorithmus mitgeliefert. Der Algorithmus, der die Plätze der Veranstaltungen eines Anmeldesets verteilt, kann ebenfalls frei selbst implementiert werden. Standardmäßig wird bereits ein Algorithmus mitgeliefert.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment