Sinds 2012 is ez-roosterbord in gebruik op het Oostvaarders College in Almere. Met ingang van schooljaar 2017/2018 is het roosterbord alleen nog toegankelijk voor personeel.
Het klopt niet helemaal wat de leerlingen op Twitter/OVCMemes hebben geschreven. Ondanks dat het roosterbord voor meer dan 99% procent van de school het enige zichtbare gedeelte is van het roostersysteem, is het maar een klein deel van het hele roostersysteem. De roostermakers gebruiken Zermelo als roosterprogramma.
apache2
als webserver.git clone
https://github.com/rsnel/ez-roosterbord/
, pas de voorbeeldconfiguratie
aan en plaats deze in config.php
.
Belangrijke configuratie items:
'UPLOAD_SECRET' => 'w43XxxeZlunMcQdHE7Bf3J2Z1ACdx85f'
upload.php?secret=w43XxxeZlunMcQdHE7Bf3J2Z1ACdx85f
, zonder de juiste waarde van de secret
parameter kom je er niet in (genereer zelf een random string, de string uit het voorbeeld is algemeen bekend en daarom geen slimme keuze...)'DSN' => 'mysql://rooster:Fdbji3eNh0Tc7KKXhvY2OoRJcgsdTtD8@unix+localhost/rooster1314?charset=utf8'
'DATADIR' => '/var/cache/roosterphp/ovc/'
'LOGFILE' => 'log.txt'
'TIMEZONE' => 'Europe/Amsterdam'
'INTERNAL_IPS' => array('127.0.0.1/0' , '172.16.0.0/12')
'SCHOOL_VOLUIT' => 'Oostvaarders College'
'SCHOOL_AFKORTING' => 'OVC'
'ZERMELO_CATEGORY_IGNORE' => array('OVERIG', '#uit', 'Algemeen')
'ZERMELO_GROUP_IGNORE' => array('#allen')
'ZERMELO_ENCODING' => 'ISO-8859-1'
rooster.sql
en installeer het overzicht met lesweken
weken1415-noord.sql
. Pas dit overzicht naar smaak aan.
DocumentRoot /usr/local/share/ez-roosterbord/
config.php
gezet). Upload de wijzigingen (txt).config.php
,
een ander deel staat in de database in tabel config
. Alle
configuratie items in de database kunnen in principe worden angepast vanuit
upload.php
. De configuratie in config.php
overrulet
de configuratie in de database.
Omdat ik mij ongans veel ergerde aan infoweb en omdat ik de kleurtjes van roosternet bij ons oude Untis rooster miste.
EZ staat voor easy, prettig en gemakkelijk in de omgang. En ook voor de initialen van Ernst Zermelo; de beroemde Duitse wiskundige, naar wie het roosterprogramma Zermelo is vernoemd.
Dat is de beroemde Duitse wiskundige Ernst Zermelo. De foto, die hiernaast ook te zien is, is in 1953 gemaakt door Konrad Jacobs en wordt door verspreid onder de CC-BY-SA-2.0-de licentie (bron).
Het idee is, dat de database het zware werk doet. Het systeem is als volgt
opgebouwd. Om te beginnen hebben we de tabellen lessen
en
entities
. In lessen
zitten alle lessen
(dag/uur/docent(en)/groep(en)/loka(a)l(en)/vak(ken)/opmerking) en in
entities
zitten alle dingen die (indirect) bij een les kunnen
horen. Tabel entities2lessen
bevat alle links tussen beide
tabellen.
In zermelo heeft elke les een 'zermelo id'; zijn er in twee roosters lessen met dezelfde 'zermelo_id', dat is het 'dezelfde les'. Als deze lessen verschillen in enig opzicht (docent/lokaal/uur...) dan is er dus sprake van een leswijziging.
Een 'zermelo id' bestaat uit cijfers en (meestal) een letter. Het is dus
lastig om ze letterlijk te gebruiken als key in een database, daarom hebben we
een aparte tabel voor deze dingen; zermelo_ids
. In de tabel
files2lessen
gebruiken niet de 'zermelo id's zelf, maar links naar
zermelo_ids
Bij het inlezen van het basisrooster en de wijzigingen wordt de file waar de
lessen staan, toegevoegd aan de tabel files
en alle lessen in de
betreffende file worden zonodig toegevoegd aan lessen
en, onder
vermelding van hun 'zermelo id', gelinkt aan de file in tabel
files2lessen
.
Om een basisrooster te laten zien, hoef je alleen maar de
file_id
van het betreffende basisrooster te weten (dit zoek je op
in tabel roosters
) en dan trek je alle lessen uit de database die
verbonden zijn met de entity waarvan je het rooster wilt zien. Voorbeeld: het basisrooster van SNEL
in week 15 met debug output.
Een weekrooster (basisrooster + wijzigingen) is veel interessanter. Je hebt al gezien dat, bij een lesverplaatsing, de betreffende les tweemaal wordt weergegeven. Namelijk op de oude locatie als verplaatst naar en op de nieuwe locatie als verplaatst van. Als het een wijziging betreft waarbij de les op dezelfde uur blijft EN in beide roosters zichtbaar is (kolom 'vis'), dan komt er gewijzigd te staan.
Om dit te doen maak je een LEFT JOIN op 'zermelo_id' van het basisrooster met de wijzigingen en dan UNION met een LEFT JOIN op 'zermelo_id' van de wijzigingen met het basisrooster. Voorbeeld: Het weekrooster van SNEL in week 25 met debug output vergelijk met het rooster van de lokalen 155 en 253 in dezelfde week.
Oefening voor de lezer: wat gebeurt er als je de LEFT's weglaat in de bovenstaande paragraaf?
Dan is er nog een koppeling tussen leerlingen en groepen ppl2grp
,
koppelingen tussen groepen die minstens één leerling
gemeenschappelijk hebben grp2grp
, een lijst met lesweken;
weken
en een lijst met namen; names
.
Voor het berichtensysteem is er ook nog de tabellen berichten
en
entities2berichten
.
Dan is er nog een tabel locking
om ervoor te zorgen dat er
maar één update tegelijkertijd kan draaien en dat er informatieoverdracht
plaatsvindt naar de progressbar in het uploadscherm.
Tenslotte hebben we nog een tabel config
met wat configuratiedingetjes erin.
SELECT basis.week_id, basis.basis_id, basis.file_id
FROM roosters AS basis
LEFT JOIN roosters AS next
ON next.week_id = basis.week_id AND next.wijz_id = 0 AND next.basis_id > basis.basis_id
WHERE basis.wijz_id = 0 AND next.week_id IS NULL
geeft een tabel met van elke week het meest recente basisrooster.
SELECT basis.week_id, basis.basis_id, basis.file_id file_id_basis, wijz.wijz_id, wijz.file_id file_id_wijz FROM (
SELECT basis.week_id, basis.basis_id, basis.file_id
FROM roosters AS basis
LEFT JOIN roosters AS next
ON next.week_id = basis.week_id
AND next.wijz_id = 0
AND next.basis_id > basis.basis_id
WHERE basis.wijz_id = 0 AND next.rooster_id IS NULL
) AS basis
JOIN roosters AS wijz USING (basis_id)
LEFT JOIN roosters AS next
ON next.basis_id = wijz.basis_id
AND next.wijz_id = wijz.wijz_id + 1
WHERE next.rooster_id IS NULL
geeft een tabel met van elke week waar een rooster in staat het meest recente basisrooster (inclusief de versie van het basisrooster; het file_id van het basisrooster en de versie van de wijzigingen en het file_id van de wijzigingen). De file_id's zijn nodig om het daadwerkelijke rooster op te halen. Merk op dat de basis_id
op weekbasis niet noodzakelijk met stapjes van 1 oplopen. Beter zou het zijn roosters
een veld rooster_id_prev
te geven, wat verwijst naar de vorige.
SET @prev := 0;
SELECT weken.*, @prev := IF(file_id_basis IS NOT NULL, file_id_basis, @prev) file_id_basis, IF(file_id_basis IS NOT NULL AND file_id_wijz != file_id_basis, file_id_wijz, 0) file_id_wijz FROM weken
LEFT JOIN (
SELECT basis.week_id, basis.basis_id, basis.file_id file_id_basis, wijz.wijz_id, wijz.file_id file_id_wijz FROM (
SELECT basis.week_id, basis.basis_id, basis.file_id
FROM roosters AS basis
LEFT JOIN roosters AS next
ON next.week_id = basis.week_id
AND next.wijz_id = 0
AND next.basis_id > basis.basis_id
WHERE basis.wijz_id = 0 AND next.rooster_id IS NULL
) AS basis
JOIN roosters AS wijz USING (basis_id)
LEFT JOIN roosters AS next
ON next.basis_id = wijz.basis_id
AND next.wijz_id = wijz.wijz_id + 1
WHERE next.rooster_id IS NULL
) AS roosters USING (week_id)
ORDER BY year, week
geeft een tabel met van elke week het meest recente basisrooster.