Webgestuurde deelnemersadministratie voor een sociaal...
Transcript of Webgestuurde deelnemersadministratie voor een sociaal...
Griet Schelstraete, Gijs Jacobs
sociaal-toeristische jeugdvereniging
Webgestuurde deelnemersadministratie voor een
Academiejaar 2009-2010
Faculteit Ingenieurswetenschappen
Voorzitter: prof. dr. Guido Vanden Berghe
Vakgroep Vakgroep Toegepaste wiskunde en informatica
Voorzitter: prof. dr. ir. Herwig Bruneel
Vakgroep Telecommunicatie en informatieverwerking
Master in de toegepaste informatica
Masterproef ingediend tot het behalen van de academische graad van
Begeleider: dr. Ewout Vansteenkiste
Promotoren: prof. dr. ir. Wilfried Philips, prof. dr. David Vyncke
PERMISSION
"De auteurs geven de toelating deze masterproef voor consultatie beschikbaar te stellen en
delen van de masterproef te kopiëren voor persoonlijk gebruik.
Elk ander gebruik valt onder de beperkingen van het auteursrecht, in het bijzonder met
betrekking tot de verplichting de bron uitdrukkelijk te vermelden bij het aanhalen van
resultaten uit deze masterproef."
"The authors give permission to make this master dissertation available for consultation and
to copy parts of this master dissertation for personal use.
In the case of any other use, the limitations of the copyright have to be respected, in
particular with regard to the obligation to state expressly the source when quoting results
from this master dissertation."
30 mei 2010
Jacobs Gijs Prof.dr.ir.W.Philips
Schelstraete Griet Prof. dr. David Vyncke
p. I
Woord vooraf
Aan het begin van deze thesis zijn er een aantal personen die wij graag zouden willen
bedanken. Zonder deze personen zou ons werk niet geweest zijn wat het uiteindelijk
geworden is.
In de eerste plaats willen wij onze promotor prof. dr. David Vyncke en onze begeleider dr.
Ewout Vansteenkiste bedanken voor de tijd die zij gestoken hebben in de vele
vergaderingen om ons bij te sturen waar nodig en voor de informatieve en technische
ondersteuning wat betreft het ontwikkelen van de website. Daarnaast een woord van dank voor onze andere promotor, prof. dr. ir. Wilfried Philips, om
steeds snel antwoord te geven op onze vragen. Ook een dikke dank-je-wel aan de twee IT-managers, Philippe Serbruyns en Davy Moreels,
waar wij altijd terecht konden voor een helpende hand bij het oplossen van een aantal
technische probleempjes. Verder wouden wij graag ook alle mensen bedanken die de tijd hebben genomen om deze
thesis na te lezen. Tot slot willen wij ook de medewerkers van Bizon vzw bedanken om ons de mogelijkheid te
geven deze site te ontwikkelen, en voor de positieve feedback die we van hen reeds
mochten ontvangen.
Wij wensen u allen Bizonder veel leesplezier
Gijs en Griet
p. II
Webgestuurde deelnemersadministratie voor een sociaal-toeristische
jeugdvereniging
Door
Jacobs Gijs
Schelstraete Griet
Promotoren: prof. dr. ir. Wilfried Philips, prof. dr. David Vyncke
Begeleider: dr. Ewout Vansteenkiste
Masterproef ingediend tot het behalen van de academische graad van
Master in de toegepaste informatica
Vakgroep Telecommunicatie en informatieverwerking
Voorzitter: prof. dr. ir. Herwig Bruneel
Vakgroep Toegepaste wiskunde en informatica
Voorzitter: prof. dr. Guido Vanden Berghe
Faculteit Ingenieurswetenschappen
Academiejaar 2009-2010
Trefwoorden: website, PHP, Bizon vzw
p. III
Inhoud
Woord vooraf .............................................................................................................................. I
Inhoud ........................................................................................................................................ III
Gebruikte afkortingen ................................................................................................................ V
Lijst van figuren ......................................................................................................................... VI
1 Inleiding ................................................................................................................................... 1
2 De database ............................................................................................................................. 3
2.1 Informatieverzameling ..................................................................................................... 3
2.1.1 Domeinanalyse .......................................................................................................... 3
2.1.2 Functionele analyse ................................................................................................... 5
2.1.3 Behoefteanalyse ........................................................................................................ 7
2.2 Conceptueel ontwerp ....................................................................................................... 8
2.3 Logisch ontwerp ............................................................................................................. 12
2.4 Fysiek ontwerp ............................................................................................................... 15
3 De website ............................................................................................................................. 17
3.1 Algemeen ........................................................................................................................ 18
3.1.1 De browser .............................................................................................................. 18
3.1.2 De gebruikte taal ..................................................................................................... 18
3.1.3 De lay-out ................................................................................................................ 19
3.1.4 De header ................................................................................................................ 20
3.1.5 Databaseconnectie .................................................................................................. 22
3.1.6 Functies .................................................................................................................... 22
3.1.7 De input ................................................................................................................... 25
3.1.8 De inlogpagina ......................................................................................................... 26
3.2 De gebruikers .................................................................................................................. 28
3.2.1 Toevoegen gebruiker ............................................................................................... 28
p. IV
3.2.2 Gegevens wijzigen ................................................................................................... 29
3.2.3 Wachtwoord wijzigen .............................................................................................. 31
3.2.4 Nieuw wachtwoord aanvragen ............................................................................... 32
3.2.5 Gebruiker verwijderen............................................................................................. 32
3.3 De gegevensbank ............................................................................................................ 33
3.3.1 Algemene structuur ................................................................................................. 36
3.3.2 Voorzieningen .......................................................................................................... 51
3.3.3 Activiteiten .............................................................................................................. 54
3.3.4 Jongeren .................................................................................................................. 58
3.3.5 Transportinformatie ................................................................................................ 61
3.3.6 Inschrijvingen ........................................................................................................... 62
3.3.7 Algemene gegevens ................................................................................................. 65
3.4 Beveiliging ....................................................................................................................... 66
3.4.1 Toegang ................................................................................................................... 66
3.4.2 Opvangen van fouten .............................................................................................. 70
4 Besluit .................................................................................................................................... 72
5 Bibliografie ............................................................................................................................. 74
5.1 Boeken ............................................................................................................................ 74
5.2 Rapporten ....................................................................................................................... 74
5.3 Websites ......................................................................................................................... 74
p. V
Gebruikte afkortingen
ADK annulatiedag kamp
AdmOpm administratieve opmerking
Aid activiteiten ID
Ajax Asynchronous JavaScript and XML
CSS cascading style sheets
DBMS database management systeem
EER enhanced entity-relationship
HTML HyperText Markup Language
Iid inschrijvingsID
Jid jongeren ID
Oid onkosten ID
PHP Hypertext Preprocessor
PIF persoonlijk inlichtingen formulier
ProcMedAnn percentage bij medische annulatie
Reknr rekening nummer
SHA1 Secure Hash Algorithm 1
Tid tijdelijke ID
Trid transport ID
Vid voorzieningsID
p. VI
Lijst van figuren
Figuur 1: EER Diagram ................................................................................................................... 10
Figuur 2: EER Diagram - Algemene gegevens ................................................................................ 11
Figuur 3: EER Diagram - Login gegevens........................................................................................ 11
Figuur 4: Fysiek ontwerp ............................................................................................................... 16
Figuur 5: De header ....................................................................................................................... 21
Figuur 6: Toevoegen header .......................................................................................................... 21
Figuur 7: De inlogpagina ................................................................................................................ 27
Figuur 8: Een voorbeeld van waardetoekenning aan een variabele ............................................. 36
Figuur 9: Het algemene overzicht van voorzieningen ................................................................... 39
Figuur 10: Het detailoverzicht van een activiteit .......................................................................... 42
Figuur 11: De webpagina om een jongere toe te voegen ............................................................. 46
Figuur 12: Het wijzigen van een transportinfo .............................................................................. 48
Figuur 13: De webpagina om activiteiten te verwijderen ........................................................... 50
Figuur 14: Een voorbeeld van het ontwikkelen van een selecteermenu om te rangschikken ..... 58
Figuur 15: Beveiliging tegen SQL-injection .................................................................................... 67
Figuur 16: Algemene toegangscontrole ........................................................................................ 70
Figuur 17: Toegangscontrole van administrator ........................................................................... 70
Figuur 18: Voorbeeld van foutopvanging ...................................................................................... 71
1 Inleiding
Bizon vzw is een organisatie die activiteiten organiseert voor maatschappelijk kwetsbare
kinderen en jongeren. Deze activiteiten zijn activiteiten voor één enkele dag, een weekend
of een kamp van meerdere dagen.
Opdat de administratieve kant van de zaak op een overzichtelijke manier georganiseerd kan
worden, is er nood aan een degelijke database en een programma dat ervoor zorgt dat men
op een gebruiksvriendelijke manier met deze database kan interageren. Het systeem dat op
dit moment gebruikt wordt, is echter verouderd en niet echt handig. De doelstelling van
deze thesis is hiervoor een oplossing te creëren door enerzijds een nieuwe database aan te
maken waarin alle noodzakelijke informatie kan worden opgeslagen en anderzijds een
website te ontwikkelen door middel waarvan gegevens in en uit deze database kunnen
worden gehaald. Het totale pakket werd verdeeld over twee groepen. De ene groep werd
verantwoordelijk gesteld voor de input van de data, de andere voor de output van de
informatie. De database zou samen worden ontwikkeld. Door omstandigheden echter was
de tweede groep niet in staat hun deel tijdig af te werken, waardoor in deze thesis niet
alleen de input van de data wordt behandeld, maar ook het grootste deel van de opbouw
van de database zelf.
Om tegemoet te kunnen komen aan de noden van Bizon vzw werden een aantal
noodzakelijke functionaliteiten meegegeven. Graag hadden zij een functionele website
gehad, louter voor administratieve doeleinden. Hierbij moet het mogelijk zijn om informatie
in de geven, te wijzigen en op te vragen van de verschillende activiteiten die worden
georganiseerd, de voorzieningen die jongeren meesturen op deze activiteiten, de jongeren
zelf, over hoe deze jongeren van en naar de activiteiten geraken en de inschrijvingen voor
elk van deze activiteiten. Aangezien het om een website gaat, kan in principe iedereen
hiernaartoe surfen. Om dit te vermijden, moet ook enige vorm van toegangscontrole
worden geïmplementeerd. Ten slotte hadden ze, indien mogelijk, graag gehad dat
voorzieningen zelf via de website jongeren konden inschrijven.
In wat volgt zal worden uiteengezet hoe geprobeerd werd aan elk van deze doelstellingen
tegemoet te komen. In hoofdstuk 2 wordt ingegaan op de manier waarop de database is
p. 2
opgebouwd. Hierna wordt in hoofdstuk 3 uitgelegd hoe de website in elkaar steekt. Er
wordt eerst en vooral een algemeen overzicht gegeven. Daarna wordt ingegaan op het
afscherming van de website voor het grote publiek, gevolgd door een overzicht van de
functionaliteiten die de website biedt. Tot slot wordt het aspect van de veiligheid
besproken.
p. 3
2 De database
Om de doelstellingen van Bizon vzw te realiseren, is het niet voldoende om een website te
bouwen langs waar men enkel en alleen nieuwe informatie kan ingeven. Deze informatie
moet ook op een overzichtelijke en efficiënte manier kunnen worden opgeslagen zodat die
ook later beschikbaar is. Aan de basis van deze website, ligt dus in de eerste plaats een goed
functionerende database1. Opdat de database op een goede en consistente manier zou
kunnen worden opgebouwd, werden een aantal stappen gevolgd zoals beschreven in
Principes van databases2 (De Tré, 2007).
2.1 Informatieverzameling
De doelstelling van deze eerste fase is om zich een zo goed mogelijk beeld te vormen van
welke informatie door de database moet worden bijgehouden, wat de betekenis ervan is en
hoe de verschillende gegevens met elkaar zijn verbonden.
Dit werd gedaan aan de hand van twee uitgangspunten, namelijk de database die tot
hiertoe werd gebruikt door Bizon vzw en de informatie die verkregen werd via één van de
administratieve medewerkers.
2.1.1 Domeinanalyse
Op basis van de informatie die werd vergaard, kon geconcludeerd worden dat er behoefte
is om verschillende gegevens te centraliseren rond een aantal kernconcepten:
- Activiteit
- Inschrijving
- Jongeren
- Onkosten
- Transport
- Voorzieningen
1 Aangezien de totale thesis werd verdeeld over twee groepen, is een deel van de database voor rekening van de
andere groep. In deze thesis wordt dan ook enkel ingegaan op het deel dat wijzelf hebben gemaakt. 2 De aanpak om een database op een gestructureerde manier te ontwerpen wordt meer specifiek beschreven in
hoofdstuk 3 van het vermelde boek.
p. 4
Elk van deze kernconcepten vormt de verzameling van een aantal specifieke eigenschappen.
Gegevens worden slechts als element van zo’n kernconcept beschouwd, wanneer zij voor al
deze eigenschappen een geldige waarde hebben.
Voor een Activiteit is het noodzakelijk dat men niet alleen de naam ervan weet, maar ook
de begin- en einddatum, de annulatiedatum, het soort activiteit, waar deze doorgaat, wat
de prijs ervan is en welk percentage men eventueel terug betaald krijgt wanneer men
annuleert omwille van medische redenen.
Bij Inschrijving moet niet alleen de inschrijving zelf worden geregistreerd. Het is ook
noodzakelijk dat een eventuele annulatie ervan kan worden bijgehouden, of deze annulatie
al dan niet vóór de gestelde datum was, of deze al dan niet is omwille van medische
redenen en of er eventueel iemand anders meegaat in de plaats. Daarnaast moet ook de
datum worden bijgehouden, de totaalprijs die moet worden betaald, of de medische fiche
al dan niet werd afgegeven en of de jongere in kwestie al dan niet toestemming heeft om
naar het buitenland te gaan. Ten slotte moet het voor de medewerkers van Bizon vzw
mogelijk zijn om eventueel nog een bijkomende opmerking bij te houden.
Voordat een Jongere ook effectief kan meegaan op kamp, moet enige informatie van hem
of haar gekend zijn, zoals de naam, het geslacht, de geboortedatum en bij welke
voorziening die staat geregistreerd. Daarnaast zou het ook mogelijk moeten zijn om een
persoonlijk telefoonnummer op te slaan, indien dit gekend is.
Om de Onkosten op een efficiënte manier te kunnen opslaan, werd gevraagd om voor elke
inschrijving bij te houden welk bedrag nog extra moet betaald worden, samen met een
korte uitleg waar dit verschuldigde bedrag vandaag komt.
Wat betreft het Transport wil Bizon vzw per activiteit en per voorziening bijhouden hoe de
jongeren van en naar de activiteit zullen komen en wie hen daarbij begeleidt.
p. 5
Voor elke Voorziening moet de naam en het adres worden bijgehouden, samen met het
telefoonnummer van de verantwoordelijke. Daarnaast moet ook de mogelijkheid worden
voorzien om de naam en het e-mailadres van deze verantwoordelijke bij te houden en aan
te geven om welke soort voorziening het gaat. Tot slot moet kunnen worden aangegeven of
aan de voorziening al dan niet een korting wordt toegekend3, of er jongeren zijn
geregistreerd die ouder zijn dan 18 jaar, of de voorziening al dan niet verborgen is binnen
de database en moet men bijkomende informatie kunnen opslaan.
2.1.2 Functionele analyse
In deze fase wordt geprobeerd om inzicht te krijgen in de herkomst van de data en hoe deze
wordt verwerkt.
Gegevens die behoren tot Activiteit, Jongeren, Onkosten, Transport of Voorzieningen
worden rechtstreeks toegevoegd aan de database door de medewerkers van Bizon vzw. Er
zijn een aantal activiteiten die elk jaar terug komen. Eens deze zijn ingegeven worden ze
meestal niet meer veranderd, alhoewel dat dit niet uitgesloten is. Activiteiten die reeds
plaatsgevonden hebben, blijven gewoon in de database aanwezig.
De gegevens van de jongeren moeten normaal gezien niet meer veranderd worden, met
uitzondering wanneer hun telefoonnummer zou wijzigen. Uit de informatie van Bizon vzw
kwam wel naar voor dat het verloop van jongeren van de ene voorziening naar de andere
wel groot is. Er moet dus ten alle tijden kunnen worden bijgehouden bij welke voorziening
de jongere op dit ogenblik staat ingeschreven.
De onkosten moeten kunnen worden toegekend per inschrijving, hoewel aan eenzelfde
inschrijving meerdere onkostennota’s kunnen worden toegekend4.
De informatie betreffende het transport moet per voorziening worden bijgehouden. Voor
alle jongeren van eenzelfde voorziening, die naar eenzelfde activiteit gaan, geldt dus
eenzelfde regeling.
3 In eerste instantie had Bizon vzw gezegd dat voor elke voorziening het rekeningnummer moest worden
bijgehouden en moest kunnen aangegeven worden of de voorziening al dan niet een dagcentrum was. Tijdens de
demonstratie die wij hen gaven van het resultaat vroegen zij ons echter of het eventueel nog mogelijk zou zijn om
het rekeningnummer te veranderen in een veld waarin zij konden invullen om welke soort voorziening het ging en
om aan te kunnen duiden of de voorziening al dan niet een korting kreeg, in plaats van de optie ‘dagcentrum’.
Deze wijziging werd alsnog uitgevoerd. 4 Hoewel de implementatie van Onkosten in de database door ons werd gedaan, hoorde ook dit tot de taken van
de andere groep. De implementatie ervan in de website nemen zij wel voor hun rekening.
p. 6
De gegevens van de voorzieningen kunnen in de loop van de tijd veranderen, zeker wat
betreft de naam, telefoonnummer en e-mailadres van de verantwoordelijke.
Wat betreft de Inschrijvingen moet een onderscheid gemaakt worden tussen een
inschrijving ingegeven door de voorziening zelf, en een inschrijving ingegeven door één van
de medewerkers van Bizon vzw. In het eerste geval gaat het eerder om een voorstel tot
inschrijving. De gegevens moeten worden opgeslagen in een tijdelijke tabel totdat ze door
één van de medewerkers van Bizon vzw definitief zijn goedgekeurd. Medewerkers geven
ofwel rechtstreeks definitieve inschrijvingen in, of halen de voorstellen tot inschrijving uit
de tijdelijke tabel en kijken of de inschrijving al dan niet aanvaard kan worden, waarna deze
al dan niet wordt overgebracht naar een definitieve tabel. Verder kunnen medewerkers
aangeven of een inschrijving werd geannuleerd en of de jongere in kwestie werd vervangen.
De gegevens van Bizon vzw zelf moeten ook in de database worden opgenomen, maar
mogen niet zomaar worden gewijzigd. Enkel iemand met de juiste bevoegdheid mag in staat
zijn om deze informatie aan te passen. Hetzelfde geldt voor de inlog gegevens. Gebruikers
mogen in principe enkel hun eigen gegevens aanpassen. Wanneer een gebruiker zijn/haar
wachtwoord vergeten is, moet een nieuw wachtwoord worden gegenereerd en opgestuurd
naar de gebruiker in kwestie.
p. 7
2.1.3 Behoefteanalyse
Naast de zes kernconcepten die expliciet vanuit Bizon vzw zelf werden meegegeven en die
reeds eerder werden besproken5, blijkt uit het voorgaande dat ook een aantal andere
elementen in rekening moeten worden gebracht, zoals de behoefte om een deel van de
website te beveiligen en het opslaan van de gegevens van de Bizon vzw zelf. Hoewel
voorzieningen zelf nog steeds jongeren zouden moeten kunnen inschrijven voor één of
meerdere activiteiten, blijft de verantwoordelijkheid voor het aanvaarden van die
inschrijvingen bij de medewerkers van Bizon vzw. Hiertoe werden drie andere
kernconcepten gedefinieerd:
- Algemene gegevens
- Login gegevens
- Aanvraag6
Ook hier geldt dat gegevens slechts als element van zo’n kernconcept worden beschouwd,
wanneer zij voor al de kenmerkende eigenschappen een geldige waarde hebben.
Aangezien de gegevens van Bizon vzw op elke factuur moeten worden weergegeven,
moeten ook deze in de database worden opgeslagen, onder Algemene gegevens7. Deze
bevatten de naam van de verantwoordelijke, het adres, telefoonnummer en
rekeningnummer van Bizon vzw.
Vanuit Bizon vzw werden niet echt specifieke richtlijnen gegeven over hoe het
administratief gedeelte van de website moest worden afgeschermd van het publieke
gedeelte. Aangezien tot hiertoe een systeem werd gebruikt dat niet verbonden was met het
internet, was de administratie hoe dan ook niet toegankelijk van buitenaf en was er dus niet
echt nood aan een inlogsysteem. Voor de Login gegevens moet dan ook vooral gekeken
worden naar wat er noodzakelijk is om een rechtmatige gebruiker op unieke wijze te
kunnen identificeren, voordat die toegang krijgt tot het afgeschermde gedeelte. Dit gebeurt
aan de hand van een unieke gebruikersnaam waaraan een paswoord wordt gelinkt.
5 Zie 2.1.1 Domeinanalyse.
6 Op vraag van Bizon vzw wordt op de website de term ‘Aanvraag’ gebruikt. In de database zelf echter werd
oorspronkelijk de term ‘Tijdelijk jongere’ gebruikt in plaats van ‘Aanvraag’. Aangezien deze naamswijziging pas laat
werd doorgegeven, was het niet meer mogelijk dit in de code zelf te veranderen. 7 Hoewel dit strikt genomen voor de andere groep was, leek het ons eenvoudiger om toch zelf dit stukje te
implementeren, aangezien de andere groep pas later aan hun deel zal werken en dit nu meteen kan worden
opgenomen op de juiste plaats in de website.
p. 8
Daarnaast wordt ook de volledige naam van de persoon in kwestie bijgehouden, samen met
zijn/haar e-mailadres. Verder wordt er ook bijgehouden of een gebruiker al dan niet
administratorrechten heeft.
Tot slot was het de wens van Bizon vzw dat een voorziening, die bij hen reeds eerder werd
geregistreerd, in staat is om via de website jongeren in te schrijven. Via deze inschrijving
moeten voldoende gegevens worden meegegeven, zodanig dat wanneer een jongere wordt
ingeschreven waarvan de gegevens nog niet in de database aanwezig zijn, deze jongere
eerst kan worden geregistreerd. In Aanvraag wordt dus enerzijds dezelfde informatie
opgeslagen als bij Jongeren. Bijkomende informatie is de naam van de activiteit waarvoor
deze jongere zich wil inschrijven, en de naam van de voorziening die verantwoordelijk is
voor deze jongere.
2.2 Conceptueel ontwerp
Eens over de context waarin de database moet functioneren voldoende gekend is, kan op
basis van deze informatie een schema worden gemaakt. Belangrijk is dat dit schema los
staat van om het even welk databasemodel. Hier werd de keuze gemaakt om te werken met
een ‘Enhanced Entity-Relationship’ diagram, zoals gesuggereerd in (De Tré, 2007). In dit
soort schema worden de kernconcepten met hun eigenschappen visueel voorgesteld,
alsook hun relatie tot elkaar.
Eerst en vooral kunnen acht entiteittypes8 worden geïdentificeerd, namelijk Activiteiten,
Inschrijvingen, Jongeren, Onkosten, Voorzieningen, Aanvraag, Login gegevens en Algemene
gegevens. Deze laatste twee staan los van elk ander entiteittype. De anderen daarentegen
zijn via verschillende relatietypes met elkaar verbonden.
Er is één speciaal relatietype9: Transport.
Zowel de acht entiteittypes als het speciale relatietype worden gekenmerkt door een aantal
attributen. Alle attributen zijn enkelwaardig, wat betekent dat het attribuut ‘binnen de
context waarin wordt gewerkt, op elk tijdstip, slechts één waarde mag aannemen’ (De Tré,
8 Een entiteittype is ‘een collectie van entiteiten en wordt gekenmerkt door een naam en een verzameling
attributen’. Een entiteit is ‘een ding dat een zelfstandig bestaan leidt in de reële wereld’ (De Tré, 2007, p62). 9 Een relatietype is ‘een verwachtschap tussen twee of meer al dan niet verschillende entiteittypes’ (De Tré, 2007,
p63). In totaal zijn er zeven relatietypes, maar enkel aan Transport worden een aantal attributen toegekend.
p. 9
2007, p65). Zowel bij Activiteiten, Transport als Voorzieningen komen wel enkele
samengestelde attributen voor.
Alle entiteittypes hebben ook een primaire sleutel aan de hand waarvan de entiteiten op
een unieke wijze kunnen worden geïdentificeerd. Deze wordt door middel van onderlijning
aangegeven.
Elk van de relatietypes wordt gekenmerkt door een kardinaliteits- en een
participatierestrictie. De eerste geeft weer hoeveel entiteiten van het beschouwde
entiteittype er maximaal, op een welbepaald moment, in een relatie van het relatietype
kunnen deelnemen. Dit wordt weergegeven aan de hand van de cijfers of letters aan de
basis van de relatie10
. De participatierestrictie bepaalt of élke entiteit van het entiteittype
moet voorkomen in een relatie van het relatietype, op een welbepaald moment. Wanneer
dit het geval is spreekt men van totale participatie. Dit wordt weergegeven aan de hand van
een dubbele verbindingslijn. In het andere geval, de partiële participatie, wordt een enkele
verbindingslijn gebruikt.
Wanneer alle elementen worden samengebracht, bekomt men onderstaande schema’s.
10 Een letter n of m betekent dat er geen maximum staat op het aantal entiteiten dat in de relatie betrokken is.
p. 10
Figuur 1: EER Diagram
AdmOpm
n
n
Aanvraag
Naam
voorziening Voornaam
jongere
Familienaam
jongere
Geboorte
datum
Geslacht
Telefoon
Datum
Trid
Tid
Voornaam Geboorte
datum
Terug
Begeleider
Vervoer
1
1
n
Oid Bedrag
Beschrijving
Prijs
n
n Inschrijving
Iid
Actie
AdmOpm
Datum
PIF
1
Toestemming
buitenland
Onkosten
n
1
Jid
Geslacht
Familienaam
Telefoon
Jongeren
Opmerkingen
m
Naam Email
Telefoon
Voorzieningen
Soort
Korting
Vid
Naam
Info
Verborgen
Oudere
Jongeren
1
Verantwoordelijke
Land
Adres
Straat + nr Postcode
Gemeente
Provincie
Heen Vervoer
Begeleider
Tran-
sport
n
Aid Naam
Prijs
1
ProcMedAnn
Activiteit
Type
Locatie
Data
Aankomst
Vertrek
ADK
p. 11
Login
gegevens
Loginnaam
Voornaam
Paswoord
Admin
Familienaam
Figuur 2: EER Diagram - Algemene gegevens
Figuur 3: EER Diagram - Login gegevens
Algemene
gegevens
Uniekeident
ificatie
Verantwoordelijke
Adres
Gemeente
Telefoon
Reknr
p. 12
2.3 Logisch ontwerp
Dit is de fase waarin een databasemodel wordt gekozen en het database schema wordt
opgebouwd op basis van het conceptueel ontwerp. Hier werd gekozen voor een relationeel
databasemodel, welke in de realiteit het meest gebruikt wordt11
.
Om het EER-diagram om te zetten naar een degelijk databaseschema moet gebruik worden
gemaakt van een omzettingsalgoritme. Hoewel dit algoritme uit negen stappen bestaat,
zoals beschreven in (De Tré, 2007), worden hier enkel de stappen behandeld die in dit geval
van toepassing zijn.
• Stap 1: omzetten van de reguliere entiteittypen
Hier wordt voor elk regulier entiteittype een basisrelatie aangemaakt.
(1.0) AANVRAAG (Tid: integer, NaamVoorziening: text, VoornaamJongere: text,
FamilienaamJongere: text, Telefoonnr: text, Geboortedatum: date, Geslacht:
enum('v','m'), Datum: date)
Primaire sleutel: {Tid}
(2.0) ACTIVITEIT (Aid: integer, Naam: text, ADK: date, Aankomst: date, Vertrek: date,
Locatie: text, Type: enum('Kamp','Eendagsactiviteit','Weekend'), Dagprijs:
decimal(10,2), ProcMedAnn: decimal(5,2))
Primaire sleutel: {Aid}
(3.0) ALGEMENE GEGEVENS (Unieke identificatie: integer, Verantwoordelijke: text,
Adres: text, Gemeente: text, Telefoon: text, Reknr: text)
Primaire sleutel: {Unieke identificatie}
(4.0) INSCHRIJVING (Iid: integer, Datum: date, Actie: enum('Inschrijving','Tijdige
annulatie','Laattijdige annulatie','Vervanging','Medische annulatie'), Prijs:
decimal(10,2), PIF: enum('Ja','Neen'), ToestemmingBuitenland:
enum('Ja','Neen'), AdmOpm: text)
Primaire sleutel: {Iid}
11 De keuze voor een relationele database was niet alleen omdat dit het meeste voorkomt, maar ook omdat
gevraagd werd om met phpMyAdmin te werken (zie 2.4 Fysiek ontwerp).
p. 13
(5.0) JONGEREN (Jid: integer, Voornaam: text, Familienaam: text, Geslacht:
enum('v','m'), Geboortedatum: date, TelefoonNr: text)
Primaire sleutel: {jid}
(6.0) LOGINGEGEVENS (Loginnaam: varchar(25), Paswoord: text, Voornaam: text,
Familienaam: text, Email: text, Admin: enum('ja','nee'))
Primaire sleutel: {Loginnaam}
(7.0) ONKOSTEN (Oid: integer, Bedrag: integer, Beschrijving: text)
Primaire sleutel: {Oid}
(8.0) VOORZIENINGEN (Vid: integer, NaamVoorziening: text, StraatEnNummer: text,
Postcode: text, Gemeente: text, Provincie: text, Land: text,
NaamVerantwoordelijke: text, EmailVerantwoordelijke: text,
TelVerantwoordelijke: text, Soort: text, Korting: enum('Ja','Neen'),
OudereJongere: enum('Ja','Neen'), Verborgen: enum('Ja','Neen'), Info: text)
Primaire sleutel: {Vid}
• Stap 6: Omzetting van binaire ‘één-op-meerdere’ relatietypes
Hier wordt de primaire sleutel van het entiteittype met kardinaliteit ‘één’
opgenomen als vreemde sleutel in het andere entiteittype.
(1.1) AANVRAAG (Tid: integer, Vid: integer, NaamVoorziening: text, Aid: integer,
VoornaamJongere: text, FamilienaamJongere: text, Telefoonnr: text,
Geboortedatum: date, Geslacht: enum('v','m'), Datum: date)
Primaire sleutel: {Tid}
Vreemde sleutel: {Vid} verwijst naar Voorzieningen
Vreemde sleutel: {Aid} verwijst naar Activiteit
p. 14
(4.1) INSCHRIJVING (Iid: integer, Aid: integer, Jid: integer,
Datum: date, Actie: enum('Inschrijving','Tijdige annulatie','Laattijdige
annulatie','Vervanging','Medische annulatie'), Prijs: decimal(10,2), PIF:
enum('Ja','Neen'), ToestemmingBuitenland: enum('Ja','Neen'), AdmOpm:
text)
Primaire sleutel: {Iid}
Vreemde sleutel: {Aid} verwijst naar Activiteit
Vreemde sleutel: {Jid} verwijst naar Jongeren
(5.1) JONGEREN (Jid: integer, Vid: integer, Voornaam: text, Familienaam: text,
Geslacht: enum('v','m'), Geboortedatum: date, TelefoonNr: text)
Primaire sleutel: {jid}
Vreemde sleutel: {Vid} verwijst naar Voorzieningen
(7.1) ONKOSTEN (Oid: integer, Iid: interger, Bedrag: integer, Beschrijving: text)
Primaire sleutel: {Oid}
Vreemde sleutel: {Iid} verwijst naar Inschrijving
• Stap 7: Omzetting van binaire ‘meerdere-op-meerdere‘ relatietypes
In deze fase wordt voor elk ‘meerdere-op-meerdere’ relatietype een nieuwe
basisrelatie aangemaakt, met als primaire sleutel de attributen van beide vreemde
sleutels. Deze vreemde sleutels zijn de primaire sleutels van de betrokken
entiteittypes. Daarnaast worden ook alle attributen van het relatietype zelf
toegevoegd.
(9.0) TRANSPORT (Trid: integer, Aid: integer, Vid: integer, BegeleiderHeen: text,
VervoerHeen: text, BegeleiderTerug: text, VervoerTerug: text, AdmOpm:
text)
Primaire sleutel: {Trid}12
Vreemde sleutel: {Aid} verwijst naar Activiteit
Vreemde sleutel: {Vid} verwijst naar Voorzieningen
Het definitieve databasemodel dat via deze stappen wordt verkregen bestaat uit (1.1), (2.0),
(3.0), (4.1), (5.1), (6.0), (7.1), (8.0) en (9.0)
12 Hier werd gekozen om een nieuwe primaire sleutel in te voeren ter vervanging van de samenvoeging van de
attributen van de vreemde sleutels, aangezien dit compacter en makkelijker is om mee te werken.
p. 15
2.4 Fysiek ontwerp
Vanuit de technische afdeling werd op voorhand voor ons de mogelijkheid voorzien om een
MySQL-database aan te maken via het database management systeem phpMyAdmin. Beide
zijn open source systemen die zeer vaak worden gebruikt. PhpMyAdmin is een PHP
programma dat het mogelijk maakt om de MySQL- database via het internet te beheren,
wat op zich het voordeel geeft dat de database van overal kan worden gewijzigd
(phpMyAdmin). MySQL is een relationele database, die kan gebruikt worden op meer dan
20 platforms en is zeer flexibel in gebruik (My SQL).
Het grote nadeel van heel wat open source software, namelijk dat er geen professionele
technische ondersteuning is, is zowel voor phpMyAdmin als voor MySQL niet van
toepassing. Door het feit dat beiden zeer veel gebruikt worden, kan men op heel wat fora
terecht, en ook via de website zelf kan men steeds hulp vragen.
Wanneer de database is opgebouwd, wordt volgend schema bekomen
p. 16
Figuur 4: Fysiek ontwerp
p. 17
3 De website
In het volgende hoofdstuk is het de bedoeling om een kort overzicht te geven van hoe de
website precies werd geïmplementeerd en op welke manier tegemoet gekomen werd
aan de vereisten die gesteld werden door Bizon vzw. Verder zal ook aandacht besteed
worden aan een aantal zaken die niet specifiek gevraagd werden, maar toch nuttig leken
om in te bouwen. Om dit op een zo overzichtelijk mogelijke manier te doen, wordt eerst
ingegaan op een aantal zaken die op regelmatige basis terugkomen op verschillende
webpagina’s. Tevens wordt ook even stilgestaan bij de inlogpagina. Vervolgens wordt
ingegaan op de functionaliteiten waarmee men kan bepalen wie al dan niet toegang
heeft tot het afgeschermde gedeelte van de website. Daarna wordt voor alle
entiteittypen die in het stuk over Informatieverzameling op p.3 werden besproken een
overzicht gegeven hoe nieuwe entiteiten kunnen worden toegevoegd en oude kunnen
worden gewijzigd, opgevraagd en verwijderd13
. Tot slot wordt ook een woordje uitleg
gegeven over de veiligheidsmaatregelen die werden genomen opdat de website zo goed
mogelijk zou kunnen functioneren.
De uiteindelijke code van elk van de webpagina’s kan gevonden worden op de CD-ROM
die bij dit werkstuk werd toegevoegd.
13 Uitzondering hierop vormt het entiteittype Onkosten, dat in de thesis van de andere groep zal worden
besproken, en het entiteittype Login gegevens, die in het stuk De gebruikers op p.28 wordt besproken.
p. 18
3.1 Algemeen
3.1.1 De browser
Vandaag de dag zijn er verschillende browsers beschikbaar op de markt. Sommigen, zoals
Firefox, Safari en Google Chrome, zijn gratis te downloaden. Internet Explorer
daarentegen is betalend. De functionaliteit die elk van deze browsers aanbiedt is
gelijkaardig. Toch verschillen zij van elkaar onder andere in de manier waarop een pagina
wordt getoond. Hoewel ervoor gezorgd werd dat de website met elk van de populaire
browsers kan worden gebruikt, werd deze geoptimaliseerd voor Firefox. Deze browser is
gratis, betrouwbaar en gemakkelijk in gebruik. Bovendien biedt deze browser een aantal
functionaliteiten aan die niet worden aangeboden door de anderen.
3.1.2 De gebruikte taal
Voor het opbouwen van de webpagina’s werd voornamelijk gebruik gemaakt van een
combinatie van HTML code – voor het weergeven van de lay-out – en PHP code – om de
pagina’s dynamisch te maken. Daarnaast werden ook een aantal Javascripts en een
Ajaxscript gebruikt.
Om zeker te zijn dat de HTML code correct is en de verschillende webpagina’s dus
worden ondersteund door de belangrijkste browsers van het moment, werden de
pagina’s gecontroleerd met de validator die ter beschikking wordt gesteld door
W3Schools14
. Hierdoor was het mogelijk om webpagina’s te verkrijgen die voldoen aan
de officiële standaard.
De voornaamste reden waarom gekozen werd voor het gebruik van de PHP scripttaal is
het feit dat dit uitdrukkelijk gevraagd werd door Bizon vzw zelf. Anderzijds biedt het
gebruik van PHP ook een aantal belangrijke voordelen.
Eerst en vooral is PHP platformonafhankelijk, wat betekent dat dit zowel op een
Windows- als op een Linux-platform kan worden gedraaid. Als gevolg daarvan is het geen
noodzaak dat het platform waarop de website ontwikkeld werd, dezelfde is als het
platform waar de website uiteindelijk zal staan. Verder is PHP een open-source software,
14 De website waarop deze validator ter beschikking wordt gesteld kan in de bronnenlijst terug gevonden
worden (W3Schools, 2010).
p. 19
dus moet er geen geld uitgegeven worden aan het aanschaffen van dure pakketten.
Bovendien is er een zeer uitgebreide website en zijn er heel wat fora beschikbaar waarop
men terecht kan voor ondersteuning (PHP.NET, 2010). Verder is PHP actief aan de server
zijde, waardoor de browser waarmee de website wordt bekeken geen speciale plug-ins
nodig heeft. Andere belangrijke voordelen zijn dat PHP snel, betrouwbaar, stabiel en
gemakkelijk is in gebruik (Stewart, 2006). Informatie omtrent het gebruik van PHP –
code werd voornamelijk gehaald uit (Naramore et al., 2005), (Valade, Ballad, & Ballad,
2008) en vanop de officiële website (PHP.NET, 2010).
Daarnaast werden ook een aantal Javascripts geïmplementeerd. Deze hebben als
voordeel dat zij voor interactiviteit zorgen en snel worden uitgevoerd door de browser.
Belangrijk is ook dat zij herkend worden door de verschillende browsers, hoewel er toch
een aantal verschillen zijn. Het nadeel echter is dat de mogelijkheid bestaat dat de
gebruiker de ondersteuning van Javascript heeft uitgeschakeld in de instellingen van zijn
browser en hierdoor een foutmelding zal krijgen. Door deze optie echter terug aan te
schakelen kan het probleem opgelost gemakkelijk worden opgelost (Mortimer, 2007).
Tot slot werd er ook een Ajaxscript gebruikt. Het voordeel hiervan is dat slechts een deel
van de pagina kan worden vernieuwd op basis van de meegegeven waarden, zonder dat
het noodzakelijk is de volledige pagina te herladen. Dit zorgt ervoor dat het niet alleen
sneller is, het beperkt ook het verkeer van en naar de server (W3Schools, 2010).
3.1.3 De lay-out
De algemene opmaak van de elementen van de website ligt vervat in een speciaal
daarvoor gemaakte css-file. Deze wordt aan elke webpagina toegevoegd via de code
“<link rel="stylesheet" type="text/css" href="../bizon.css" />”, zodat een uniform geheel
wordt bekomen. Het grote voordeel van het werken met een stylesheet is dat indien
men de lay-out wil wijzigen, dit slechts op één enkele plaats moet worden gedaan.
Daarnaast zorgt het er ook voor dat de broncode van de verschillende pagina’s sterk
vermindert.
Aangezien de website voor administratieve doeleinden zal worden gebruikt, werd
geopteerd voor een sobere, praktische en overzichtelijke lay-out. De file op zich is
opgebouwd uit drie delen.
p. 20
Een eerste deel, de pagina lay-out, bevat een opmaakstijl voor de body. Deze zorgt
ervoor dat alle tekst die getoond wordt eenzelfde basis lay-out heeft. Daarnaast bevat
die ook een aantal opmaakstijlen voor tabellen in het algemeen, en voor rijen en
kolommen elk afzonderlijk. Zij zorgen ervoor dat kan worden afgeweken van de
algemene stijl die gedefinieerd werd voor de body. Vervolgens werden drie stijlen
gedefinieerd voor het weergeven van paragrafen. Zij worden gebruikt enerzijds om
foutmeldingen weer te geven, anderzijds om aan te geven dat een bepaalde actie
geslaagd is ofwel om bepaalde tekst kleiner te zetten dat de puntgrootte die gebruikt
werd in de basis lay-out. Tot slot werden vier IDs gecreëerd die gebruikt worden bij het
creëren van de header15
.
Het tweede deel definieert een aantal stijlen voor de verschillende elementen die
voorkomen in de formulieren op de verschillende pagina’s. Deze werden gedeeltelijk
overgenomen uit (De Coninck & Verhamme, 2009).
Het derde deel tenslotte wordt gebruikt om de header op te maken. Aangezien het script
dat hiervoor gebruikt werd, geleend werd van (De Coninck & Verhamme, 2009) (zie
verder), werden ook de bijhorende stijlen overgenomen. De opmaak van de stijlen werd
hier en daar wel aangepast aan de specifieke omstandigheden.
3.1.4 De header
De header is een element dat aan elke webpagina, die niet toegankelijk is voor het
publiek, is toegevoegd. Deze wordt bovenaan elke pagina getoond en bevat verwijzingen
naar de verschillende onderdelen van de website. Op die manier kunnen gebruikers
makkelijk overschakelen van het ene onderdeel naar het andere en hebben ze ook een
overzicht van wat men op de website kan doen. Daarnaast bevat de header ook het logo
van Bizon vzw en wordt er ook vermeld wie ingelogde gebruiker is.
15 Het header, logo en menu ID werden grotendeels overgenomen uit (De Coninck & Verhamme, 2009).
p. 21
Figuur 5: De header
Om de header te implementeren werden twee documenten aangemaakt. Het eerste
document werd gebaseerd op de code van (De Coninck & Verhamme, 2009). In
tegenstelling tot deze code werd hier eerst een tabel gecreëerd. Hierin werden het logo
en de eerder vermelde login gegevens van de gebruiker geplaatst. Deze tabel wordt
gevolgd door een overzicht —in lijstvorm— van de verschillende webpagina’s waar een
gebruiker naartoe kan gaan. Het overzicht is zodanig opgebouwd dat sommige van deze
opties enkel zichtbaar zijn wanneer de ingelogde gebruiker administratorrechten heeft16
.
Het tweede document werd integraal overgenomen van (De Coninck & Verhamme,
2009). Deze code is een Javascript dat ervoor zorgt dat de header wordt weergegeven als
een horizontale titelbalk en dat de verschillende dropdown menu’s verborgen blijven tot
op het moment dat er met een muisaanwijzer wordt overgegaan.
Beide documenten worden aan elke afgeschermde pagina toegevoegd met behulp van
onderstaande code.
16 Het gaat hier in het bijzonder om de opties om de contactgegevens van Bizon vzw te veranderen en de opties
voor het aanmaken en verwijderen van gebruikers.
<script type="text/javascript" src="../Headerscript.js"></script>
require_once "../header.php";
Figuur 6: Toevoegen header
p. 22
3.1.5 Databaseconnectie
De connectie tot de database wordt gerealiseerd in een apart document dat indien nodig
kan worden opgeroepen. Dit kan gebeuren aan de hand van de PHP code ‘require_once’.
Het grote voordeel van deze manier van werken is enerzijds dat gevoelige informatie,
zoals het wachtwoord, niet in de eigenlijke documenten staat (Valade et al., 2008).
Anderzijds wordt op deze manier verhinderd dat webpagina’s elk afzonderlijk moeten
worden aangepast indien een of meerdere van de verbindingsparameters worden
veranderd17
, wat niet alleen tijdrovend is, maar ook een grotere kans op fouten
betekent.
3.1.6 Functies
Om te verhinderen dat de code voor veel gebruikte functionaliteiten elke keer opnieuw
moeten worden gemaakt, werd één centrale pagina gecreëerd waar deze functies
werden gegroepeerd. Wanneer één of meerdere van deze functies moeten worden
geïmplementeerd op een pagina, volstaat het om deze centrale pagina eerst op te
nemen met behulp van de PHP code ‘include’, waarna de functie op dezelfde manier kan
gebruikt worden alsof ze in de pagina zelf zou zijn gedefinieerd. Dit heeft als bijkomend
voordeel dat bij het wijzigen van deze functies deze wijzigingen automatisch worden
doorgevoerd waar de functies worden gebruikt. Hieronder wordt een kort overzicht
gegeven van de gedefinieerde functies.
3.1.6.2 SELECTIEVELD VOOR DE DATUM
Deze functie werd overgenomen van (De Coninck & Verhamme, 2009). Bij het oproepen
van de functie moet een minimum en een maximum worden meegegeven net als de
waarde die als geselecteerd moet worden aangeduid. De functie zorgt er dan voor dat
automatisch alle gehele getallen tussen dit minimum en maximum worden getoond in
een dropdown-menu.
17 Er wordt aangeraden om het wachtwoord regelmatig te veranderen omwille van de veiligheid van de
database (De Tré, 2007).
p. 23
3.1.6.3 ESCAPEN VAN INPUT
Een belangrijk probleem dat bestaat wanneer men wordt geconfronteerd met input die
in een database moet worden opgeslagen is dat deze input ‘vreemde’ tekens kan
bevatten18
. Hierdoor is het mogelijk dat het DBMS geen onderscheid kan maken tussen
de commando’s die gebruikt worden om de juiste acties aan te geven, en de data die
effectief moet worden opgeslagen. Als gevolg hiervan kan een foutmelding worden
weergegeven, maar de gevolgen kunnen ook erger zijn, zoals bijvoorbeeld het verlies van
data (De Tré, 2007).
Om deze problemen te vermijden werd een functie ontwikkeld die automatisch code
toevoegt vóór deze vreemde tekens — de zogenaamde escape-code — zodanig dat er
geen onduidelijkheden meer bestaan. Deze functie is gebaseerd op de code van (De
Coninck & Verhamme, 2009) en (PHP.NET, 2010).
Anderzijds, wanneer data uit te database wordt gehaald en wordt getoond in de
inputvelden op de webpagina, worden deze vreemde tekens automatisch voorafgegaan
door een escape-code en ook zo getoond aan de gebruiker. Dit is uiteraard niet
wenselijk. Om deze code te verwijderen bestaat echter reeds een standaardfunctie
‘stripslashes’ , dus is er geen nood om een speciale functie te ontwikkelen.
3.1.6.4 GENEREN VAN EEN WACHTWOORD
Opdat niemand, behalve de persoon voor wie het wachtwoord bestemd is, het
wachtwoord zou kennen, werd geopteerd om een functie te implementeren die
automatisch sterke wachtwoorden aanmaakt. Op de reden en de implicaties hiervan
wordt verder ingegaan in het stuk over Beveiliging op p.67. De code werd overgenomen
van (Jumba, 2008). Ze werd echter lichtjes aangepast, zodat het mogelijk zou zijn om
eventuele fouten op te kunnen vangen. De lengte van het paswoord werd ingesteld op
tien tekens en er werd steeds gekozen voor de categorie ‘any’, wat inhoudt dat een
willekeurig wachtwoord wordt gegenereerd die vreemde karakters kan bevatten.
18 Deze vreemde tekens zijn onder andere enkele aanhalingstekens (‘) en dubbele aanhalingstekens (“).
p. 24
3.1.6.5 CONTROLEREN VAN EEN WACHTWOORD
Een wachtwoord kan ten alle tijden veranderd worden. Omwille van veiligheidsredenen
wordt zelfs aangeraden om dit op regelmatige tijdstippen te doen (De Tré, 2007). Er
moet echter steeds voldaan zijn aan een aantal voorwaarden19
, zodanig dat men zeker is
dat ook het nieuwe wachtwoord voldoende sterk is. Dit moet ervoor zorgen dat het
wachtwoord niet zomaar kan worden gekraakt. De code voor het controleren van het
wachtwoord werd grotendeels gehaald van (De Coninck & Verhamme, 2009).
3.1.6.6 CONTROLE DECIMALE CIJFERS
Deze functie is geïmplementeerd om te controleren of een prijs of een percentage op de
juiste manier werd geschreven. Dit betekent in de eerste plaats dat er maximaal twee
cijfers na de komma zijn ingegeven. Doordat het decimaal getal in de databank wordt
opgeslagen met een punt in plaats van een komma, werd ook toegelaten dat het
decimaal getal met een punt wordt geschreven. Hoewel niet gebruikelijk binnen de
notatie van decimale getallen, heeft men de neiging om na een punt of een komma een
spatie te zetten. Om ook hier rekening mee te houden, werd dit ook toegelaten. Deze
spatie zal later verwijderd worden en de komma vervangen door een punt. Alle andere
input die aan deze test wordt onderworpen, zal de waarde ‘false’ geven. In de praktijk
betekent dit dat de waarde niet zal aanvaard worden door het database management
systeem en bijgevolg een foutmelding zal genereren.
Deze functie werd voornamelijk gehaald van een website (PHP development 5, 2010). De
egrep-uitdrukking werd aangepast, omdat de oorspronkelijk uitdrukking niet de gewilde
functionaliteit als gevolg had.
19 Een sterk wachtwoord vereist namelijk dat dit wachtwoord niet te kort is en minstens één gewone letter, één
hoofdletter, één cijfer en één speciaal teken bevat.
p. 25
3.1.6.7 VOLGORDE VAN DATA CONTROLEREN
Wanneer een nieuwe activiteit wordt toegevoegd of een activiteit die reeds in de
database aanwezig is wordt gewijzigd, moeten onder andere een aantal data worden
ingevuld. Omdat het niet de bedoeling kan zijn dat deze data in het verleden liggen, werd
een functie gemaakt die dit controleert.
Deze functie heeft twee data als input en geeft een boolean als resultaat weer. Het
resultaat is ‘waar’ wanneer de eerste datum wel degelijk voor de tweede datum komt.
3.1.6.8 BEREKENEN VAN DE PROVINCIE
Bizon vzw organiseert een aantal activiteiten in elk van de provincies. Om ervoor te
zorgen dat de deelnemers zoveel mogelijk verspreid kunnen worden over elk van deze
activiteiten is het belangrijk dat zij van iedere voorziening — en dus automatisch ook van
elke jongere— de juiste provincie kennen. Aangezien de provinciale spreiding cruciaal is
voor de erkenning als landelijk georganiseerd jeugdwerk, moet vermeden worden dat al
dan niet doelbewust de verkeerde provincie wordt ingevuld. Hiervoor beschikt Bizon vzw
reeds over een algoritme dat de provincie berekent op basis van de postcode. Dit
algoritme was echter geschreven in Visual Basic, en moest dus nog omgezet worden naar
PHP. De functionaliteit bleef echter behouden.
3.1.7 De input
Op heel wat van de webpagina’s zijn formulieren terug te vinden waar van de gebruiker
verwacht wordt dat die een aantal gegevens invult. Deze worden dan later toegevoegd,
gelezen of verwijderd uit de database. Omdat niet zomaar om het even welke gegevens
mogen worden ingelezen, worden telkens op voorhand een aantal controles uitgevoerd.
Vaak komt het voor dat een aantal van deze invulvelden verplicht in te vullen zijn. De
inputcontrole gaat in deze gevallen ook na of al deze velden daadwerkelijk werden
ingevuld.
Wanneer één of meerdere velden een foutieve input hebben meegekregen, verschijnt
een foutboodschap. Bovendien wordt ook aangegeven welk van de ingevulde gegevens
de foutboodschap heeft veroorzaakt, zodat de gebruiker de nodige aanpassingen kan
doen.
p. 26
Deze controle is een aanvulling van het feit dat de input wordt voorzien van escape-
codes. De eerste controle gaat na of de input aan bepaalde voorwaarden voldoet, terwijl
de laatste ervoor zorgt dat de data zonder problemen kan worden ingevoegd in de
database. Pas wanneer de inputcontrole succesvol is verlopen wordt toelating gegeven
om de bedoelde acties uit te voeren.
3.1.8 De inlogpagina
Aan de ene kant wil Bizon vzw een administratieve website die enkel toegankelijk is voor
medewerkers van de organisatie zelf. Aan de andere kant vinden zij het ook belangrijk
dat voorzieningen die reeds bij hen gekend zijn de mogelijkheid hebben om zelf
rechtstreeks, online jongeren in de schrijven voor de verschillende activiteiten. Een
antwoord hierop werd geformuleerd onder de vorm van een inlogpagina.
Op deze pagina kunnen medewerkers inloggen en zo toegang krijgen tot het
administratief gedeelte. Om te kunnen inloggen moet de gebruiker zijn of haar
gebruikersnaam met bijhorend paswoord invullen. Op het moment dat op ‘Inloggen’
wordt geklikt, wordt gecontroleerd of de ingevulde gebruikersnaam in de database
aanwezig is en zo ja, of het opgegeven paswoord overeen komt met het paswoord dat is
opgeslagen in de database. Wanneer dit niet het geval is, wordt een foutmelding
gegeven. Pas wanneer alles in orde is, krijgt men toegang tot de administratieve website.
Wanneer een gebruiker zijn/haar wachtwoord zou vergeten zijn, kan via ‘Wachtwoord
vergeten?’ een nieuw wachtwoord worden aangevraagd. Hierop wordt verder ingegaan
op p.32.
Voorzieningen daarentegen kunnen een keuze maken tussen de verschillende types van
activiteiten waarna ze de jongeren kunnen inschrijven. Hiervoor hebben zij enkel hun
klantennummer nodig dat door Bizon vzw aan hen is toegekend. Volgende figuur geeft
een beeld van hoe de inlogpagina er in de praktijk uitziet.
p. 27
Figuur 7: De inlogpagina
p. 28
3.2 De gebruikers
In tegenstelling tot de algemene definitie van de gebruikers van een database, namelijk
‘elke persoon die op één of andere manier interactie met het databasesysteem heeft’
(Tré, 2007, p14), zijn de gebruikers die hier in beschouwing worden genomen de
personen die niet alleen interageren met de website op zich, maar bovendien ook over
een gebruikersnaam en paswoord beschikken. Onder deze gebruikers werden twee
groepen gedefinieerd: de gewone gebruiker en de administrator. Aan deze laatste groep
zijn een aantal extra rechten toegekend. Hierop wordt later teruggekomen.
Om aan de vereiste te kunnen voldoen de website op een succesvolle manier af te
schermen van het grote publiek, kan dus aan elke medewerker een unieke
gebruikersnaam en paswoord worden toegekend. Hierdoor heeft men controle op wie
toegang heeft tot de website. Hoewel elke gebruiker in staat is zijn eigen gegevens en
paswoord te wijzigen, komt het beheer van de gebruikers als geheel toe aan de
administrators. Om dit beheer mogelijk te maken werden een aantal pagina’s
ontwikkeld, respectievelijk om gebruikers aan te maken, te verwijderen of de gegevens
te wijzigen. Administrators zijn niet in staat om de wachtwoorden van gebruikers te
wijzigen, met uitzondering van hun eigen wachtwoord. Dit om mogelijk misbruik tegen te
gaan. In wat volgt wordt kort ingegaan op een aantal belangrijke punten.
3.2.1 Toevoegen gebruiker
Omdat de identiteit en het aantal medewerkers geen vast en statisch gegeven is, moet
enerzijds de mogelijkheid worden voorzien om op zelfstandige basis gebruikers toe te
kunnen voegen. Anderzijds is het wenselijk dat er toch enige vorm van controle bestaat
op dit toevoegen, om misverstanden en mogelijks misbruik tegen te gaan. Daarom werd
er voor geopteerd om enkel aan de administrators de bevoegdheid te geven om
gebruikers toe te voegen. Voordat er een gebruiker kan worden toegevoegd moet de
administrator dan ook zijn/haar paswoord opgeven.
p. 29
Bij het toevoegen van een gebruiker moet er een gebruikersnaam worden gekozen. Deze
keuze is belangrijk, aangezien deze later niet meer kan worden aangepast. Ook belangrijk
is dat deze niet te kort of te lang is, enkel letters of cijfers bevat en vooral, dat deze uniek
is. Daarnaast moeten ook naam, voornaam en e-mailadres ingevuld worden en moet
worden aangegeven of de nieuwe gebruiker al dan niet een administrator is.
Hoewel het mogelijk is dat medewerkers eenzelfde naam hebben, is het wel noodzakelijk
dat elke gebruikersnaam uniek is, en dat maximaal één gebruikersnaam per e-mailadres
kan worden toegekend. Om dit te verzekeren, worden deze gegevens eerst vergeleken
met de gegevens die reeds in de database aanwezig zijn, voordat de ingevulde data
wordt goedgekeurd en doorgestuurd naar de databank.
Een ander probleem waar men mee werd geconfronteerd, is het feit dat hoewel de
gebruikersnaam kan worden gecreëerd door een administrator, het uit
veiligheidsoverwegingen niet wenselijk is dat deze ook het paswoord zelf kan kiezen. Dit
probleem werd opgelost door een functie te creëren die automatisch sterke
wachtwoorden kan genereren20. Dit wachtwoord wordt dan automatisch naar het
opgegeven e-mailadres verstuurd, samen met de aangemaakte gebruikersnaam, op
voorwaarde dat er geen problemen optreden bij het opslaan ervan in de database.
Wanneer om de één of andere reden een fout zou optreden bij het generen van het
wachtwoord, wordt een foutmelding gegeven en kan de administrator alsnog —
uitzonderlijk — zelf een wachtwoord meegeven.
3.2.2 Gegevens wijzigen
De gegevens die zijn opgegeven kunnen na verloop van tijd wijzigen. Om dit op te vangen
werd het mogelijk gemaakt om ook de opgeslagen gegevens te veranderen.
Het grote probleem dat hierbij ondervonden werd, is dat er een onderscheid moet
gemaakt worden tussen gewone gebruikers — die enkel hun eigen gegevens kunnen
wijzigen — en administrators — die de gegevens van iedereen kunnen wijzigen.
Aangezien de naam van een persoon normaal gezien niet verandert, werd ervoor
geopteerd om enkel aan administrators de mogelijkheid te geven om de naam te
veranderen. Ook mogen enkel zij de bevoegdheid hebben om administratorrechten te
20 Deze functie wordt in meer detail besproken op p. 23.
p. 30
geven of terug af te nemen. Bovendien moet vermeden worden dat ze zichzelf per
ongeluk de rechten afnemen21.
Deze problemen werden in eerste instantie opgelost door een boolean aan te maken die
aangeeft of de gebruiker al dan niet een administrator is. Op basis van de waarde van
deze boolean wordt ervoor gezorgd dat een bepaalde code wel of niet wordt uitgevoerd.
Het resultaat hiervan is dat een gewone gebruiker enkel zijn eigen gegevens te zien
krijgt, waarbij enkel het e-mail adres kan worden aangepast22. Een administrator
daarentegen krijgt een keuzemenu te zien waaruit hij/zij de gewenste gebruiker kan
selecteren. Op basis van deze keuze worden vervolgens de juiste gegevens uit de
database gehaald. Om dit te kunnen realiseren, wordt beroep gedaan op een eenvoudig
Javascript dat als doel heeft de pagina te vernieuwen en de gekozen gebruikersnaam
mee te geven.
In tweede instantie werd ervoor gezorgd dat, wanneer een administrator zijn eigen
gegevens wil aanpassen, de optie van ‘administrator’ niet kan worden aangepast. Op die
manier wordt ervoor gezorgd dat er altijd minstens één administrator is.
Een laatste probleem waar rekening mee werd gehouden, houdt in dat de rechten van
de administrator steeds moeten gecontroleerd worden vóórdat de wijzigingen mogen
worden doorgevoerd23. Wanneer deze rechten niet meer zouden bestaan, moet het toch
nog steeds mogelijk zijn om de eigen gegevens aan te passen. Dit werd opgelost door te
werken met een if-lus.
21 Dit moet vermijden dat er per ongeluk geen enkele administrator meer staat geregistreerd. Aangezien enkel
een administrator in staat is om gebruikers toe te voegen of te verwijderen zou dat betekenen dat er geen
aanpassingen meer zouden kunnen worden gedaan. 22
Net zoals bij het creëren van een nieuwe gebruiker wordt gecontroleerd dat er maximaal één
gebruikersnaam aan eenzelfde e-mailadres is gekoppeld. 23
Hierop wordt verder ingegaan in het stuk Aanpassingen administrator op p.69
p. 31
3.2.3 Wachtwoord wijzigen
Aangezien wordt aangeraden om op regelmatige tijdstippen het wachtwoord te wijzigen
(De Tré, 2007), is het dus noodzakelijk dit mogelijk te maken.
Het enige wachtwoord dat om het even welke gebruiker kan wijzigen, is zijn/haar eigen
wachtwoord. De gebruikersnaam wordt automatisch ingevuld en kan niet gewijzigd
worden. Op die manier wordt niet alleen verhinderd dat personen andermans
wachtwoord aanpassen, maar dit spaart ook tijd uit. De gebruiker in kwestie moet ook
zijn/haar wachtwoord opgeven, waarna gecontroleerd wordt of dit wel het correcte
paswoord is.
Voor het wijzigen zelf werden twee mogelijkheden voorzien. Enerzijds is er de
automatische methode, die een random wachtwoord genereert. Hierbij wordt gebruik
gemaakt van de functie besproken op p.23. Hoewel deze methode beter is, aangezien
het wachtwoord totaal ad random wordt gegenereerd en dus volledig los staat van de
persoon die het zal gebruiken in de toekomst, zijn deze wachtwoorden niet altijd even
makkelijk te onthouden. Daarom werd ervoor gekozen de gebruiker ook de mogelijkheid
te geven om zelf een nieuw wachtwoord te kiezen. Dit wachtwoord moet echter
voldoende sterk zijn. Dit wordt gecontroleerd aan de hand van de functie beschreven op
p.24. Om er zeker van te zijn dat het ingegeven paswoord het bedoelde paswoord is,
moet dit twee maal worden ingegeven.
In beide gevallen wordt het gewijzigde wachtwoord naar het e-mailadres van de
gebruiker gestuurd, als extra zekerheid.
p. 32
3.2.4 Nieuw wachtwoord aanvragen
Hoewel het niet de bedoeling is, kan het nooit worden uitgesloten dat iemand zijn/haar
wachtwoord vergeet. Om dit probleem op de vangen, werd een pagina gecreëerd
waarop de gebruiker een nieuw wachtwoord kan aanvragen door het opgeven van het e-
mailadres waarmee hij/zij is geregistreerd. Indien dit e-mailadres wordt teruggevonden
in de database, wordt een nieuw wachtwoord aangemaakt en samen met de
gebruikersnaam verstuurd naar het opgegeven e-mailadres.
Wanneer om de één of andere reden een fout zou optreden in het generen van het
nieuwe paswoord, wordt een standaard paswoord verstuurd. De ontvanger wordt
hiervan op de hoogte gebracht en aangeraden het paswoord zo snel mogelijk te
veranderen.
3.2.5 Gebruiker verwijderen
Wanneer een medewerker Bizon vzw verlaat, is het niet de bedoeling dat deze nog
langer toegang heeft tot de website. Het moet dus mogelijk zijn om een gebruiker te
verwijderen uit de database. Om hierover enige vorm van controle te hebben kan deze
actie enkel door een administrator worden uitgevoerd.
Het probleem dat hierbij kan optreden is dat —per ongeluk — de verkeerde gebruiker
wordt verwijderd. Er is dus nood aan een controlemechanisme om dat te vermijden. Dit
werd geïmplementeerd als volgt: op het moment dat de administrator de gebruiker die
hij/zij wenst te verwijderen uit het getoonde keuzemenu heeft geselecteerd en zijn/haar
eigen paswoord heeft ingevuld, wordt ter controle een extra bevestiging gevraagd. Pas
wanneer de verwijdering opnieuw wordt bevestigd, vindt deze ook effectief plaats.
Aangezien in dit proces de pagina wordt vernieuwd, is het noodzakelijk de gekozen
gebruiker mee te geven aan een session-key24.
Omdat aan een administrator bepaalde rechten werden toegekend, werd een
bijkomende veiligheidsmaatregel getroffen wanneer men deze zou willen verwijderen.
Hierop wordt verder ingegaan in het stuk over beveiliging op p.69.
24 Een session-key is een variabele die een waarde kan bevatten die over de pagina’s heen wordt doorgegeven.
De keuze zou daarentegen ook via een URL kunnen worden meegegeven, maar dit is minder veilig omdat dit
makkelijker te manipuleren is.
p. 33
3.3 De gegevensbank
Een ander deel van de opdracht is het onderhoud van de gegevensbank. Zoals
beschreven, bestaat de gegevensbank uit een aantal entiteittypes die gespecificeerd zijn
door verschillende attributen. Zo bestaat het entiteittype ‘Transportinfo’ uit
‘VervoerHeen’, ‘VervoerTerug’, ‘BegeleiderHeen’, ‘BegeleiderTerug’ en ‘AdmOpm’. Om
deze gegevensbank te kunnen onderhouden moet de administratie van Bizon een aantal
manipulaties op deze entiteittypes kunnen uitvoeren:
Het genereren van een overzicht.
Hoewel het genereren van een overzicht niet tot de oorspronkelijke opdracht behoorde,
is het toch belangrijk dat de administratie een goed overzicht krijgt wat er wel of niet in
de gegevensbank zit. Met andere woorden moet men per entiteittype een volledige lijst
kunnen oproepen van de entiteiten die reeds in de databank zitten.
Het is ook belangrijk dat de administratie één of meerdere gegevens op een vlotte en
snelle manier kan terugvinden.
Tenslotte dient zo’n overzicht ook als interface. Hierbij kan de administratie één of
meerdere entiteiten selecteren om vervolgens één van de onderstaande manipulaties uit
te voeren.
Het genereren van een meer gedetailleerd overzicht.
Hoewel deze pagina niet specifiek gevraagd werd, leek het ons toch belangrijk een
duidelijkere weergave te voorzien van één of meerdere entiteiten. Op die manier kunnen
minder fouten worden gemaakt in het interpreteren van de informatie. Een andere
reden voor dit overzicht ligt in het feit dat bepaalde entiteittypes veel attributen
bezitten. Zo bezit een Voorzieningsentiteit 15 attributen. Dit is te veel om een algemeen,
doch duidelijk beeld te scheppen van alle voorzieningen die reeds in de gegevensbank
zitten. Om wille hiervan werd besloten om bij een aantal entiteittypes slechts de
belangrijkste attributen weer te geven in het algemene overzicht. Opdat de administratie
ook hiervan alle informatie zou kunnen opvragen, worden in het gedetailleerd overzicht
alle attributen met inhoud weergegeven.
p. 34
Het toevoegen van een bepaalde entiteit.
De administratie moet de mogelijkheid hebben om een bepaalde entiteit toe te voegen.
Hierbij is het vooral belangrijk een onderscheid te maken tussen de belangrijkste
attributen en de meer secundaire informatie van een bepaald entiteittype. Met andere
woorden moet een onderscheid gemaakt worden tussen verplichte en niet-verplichte
velden. Het zou bijvoorbeeld niet goed zijn dat lege of nietszeggende entiteiten worden
toegevoegd. Op die manier kan nutteloze informatie worden opgeslagen die het
algemeen overzicht verstoort, tot misinterpretatie leidt en onnodige frustraties oproept
(De Tré, 2007).
Het is ook belangrijk om de structuur van de databank te respecteren in die zin dat
bepaalde entiteittypes met andere entiteittypes verbonden zijn. Het entiteittype
‘Transportinfo’ is bijvoorbeeld verbonden met het entiteittype ‘Voorzieningen’. Zo mag
men bij het toevoegen van transportinfo enkel kiezen tussen de voorzieningen die reeds
in de databank zijn opgenomen.
Zoals eerder gezegd, moet er ook een bepaalde inputcontrole zijn, enerzijds om te
vermijden dat de databank bepaalde informatie weigert op te slaan, anderzijds om te
vermijden dat dubbele informatie is opgeslagen. Er is dus een bepaalde controle nodig
die nagaat of de desbetreffende informatie reeds aanwezig is. Zo’n controle is echter niet
volledig waterdicht.
Het wijzigen van een bepaalde entiteit.
De administratie moet de mogelijkheid hebben om de primaire informatie te wijzigen en
de secundaire informatie aan te vullen, te wijzigen of te verwijderen. Er is ook opnieuw
een bepaalde inputcontrole nodig op deze gewijzigde velden.
Het verwijderen van een bepaalde entiteit.
Informatie die verouderd of irrelevant is geworden, moet kunnen worden verwijderd. Bij
het verwijderen bestaat echter steeds het gevaar dat per ongeluk entiteiten uit de
databank worden verwijderd door bijvoorbeeld op ‘Verwijderen’ te drukken in plaats van
op ‘Wijzigen’. Om dit te vermijden moet een bepaalde buffer worden ingebouwd opdat
het verwijderen een gewilde actie is.
p. 35
Ook hier moet rekening worden gehouden met de structuur van de databank. Zo mag
het pas mogelijk zijn voorzieningen te verwijderen als en slechts als ook alle verbonden
entiteiten verwijderd zijn (jongeren, transportinfo en publieke inschrijvingen).
Om het overzicht te bewaren is het misschien wenselijk om een herhaling te geven van
de verschillende entiteittypes25 waarvoor deze functionaliteiten moeten gerealiseerd
worden:
De activiteiten
De verschillende activiteiten waarvoor de jongeren zich kunnen inschrijven: kampen,
weekends en dagactiviteiten.
De Inschrijvingen
De eigenlijke inschrijving waarbij een jongere wordt ingeschreven voor een bepaalde
activiteit.
Ook zijn er de zogenaamde aanvragen: voorzieningen kunnen, eens opgenomen in de
databank, jongeren inschrijven via de website. Eenmaal de inschrijving wordt aanvaard,
moet zowel de jongere als de inschrijving opgenomen kunnen worden in de databank.
De jongeren
De jongere in kwestie die participeert in een bepaalde activiteit en die altijd gekoppeld is
aan een voorziening.
De transportinformatie
De manier waarop de jongeren naar een activiteit worden gebracht of worden
opgehaald. De transportinformatie is altijd gekoppeld aan een bepaalde voorziening en
een bepaalde activiteit.
De voorzieningen
De instellingen die verantwoordelijk zijn voor de inschrijving van de jongeren en die dus
ook zorgen voor het vervoer, de betaling, … van de jongeren.
25 De opgesomde entiteittypes zijn niet alle entiteittypes waarvoor deze functionaliteiten moeten gerealiseerd
worden. Het beheren van de resterende entiteittypes werd overgelaten aan het andere groepje.
p. 36
Om een duidelijk beeld te scheppen over de realisatie van de website wordt om te
beginnen uitgelegd hoe de verschillende manipulaties werden gerealiseerd. Daarna
wordt dieper ingaan op de specifieke eisen van de verschillende entiteittypes. De
verschillende manipulaties (overzicht, detail, toevoegen, wijzigen en verwijderen)
worden steeds herhaald, opdat het overzicht kan bewaard worden.
3.3.1 Algemene structuur
3.3.1.1 OVERZICHT
Eerst en vooral werd een algemeen overzicht gemaakt dat de hoofdpagina vormt van elk
entiteittype. Wanneer men in de hoofdbalk bovenaan de webpagina ‘gegevensbank’
selecteert, wordt een keuzemenu getoond. Elk van deze mogelijke keuzes leidt naar één
van deze overzichten. Het spreekt voor zich dat entiteiten slechts kunnen gewijzigd of
verwijderd worden wanneer deze kunnen worden geselecteerd.
Om zo’n overzicht te genereren, werd beroep gedaan op het boek Beginning: PHP5,
Apache, MySQL, Web Development (Naramore et al., 2005). Hierin werd de tip gegeven
om meerdere regels HTML in één variabele te stoppen in plaats van rechtstreeks HTML
af te printen of om aan elke HTML-regel een variabele toe te kennen. Op die manier kan
men het gemakkelijkst het overzicht bewaren binnen de code. Een concreet voorbeeld
hiervan — voor transportinfo — kan hieronder worden gevonden:
$tabel=<<<tabel
<table align = "center" class="overzicht" style="position:absolute;
left:200px;">
<tbody>
<tr>
<th align="center"></th>
<th width=”140px” align="center"> Voorziening </th>
<th width=”140px” align="center"> Activiteit <br/> (annulatiedatum) </th>
<th width=”140px” align="center"> Vervoer heen </th>
<th width=”140px” align="center"> Begeleider heen </th>
<th width=”140px” align="center"> Vervoer Terug </th>
<th width=”140px” align="center"> Begeleider terug </th>
</tr>
tabel;
Figuur 8: Een voorbeeld van waardetoekenning aan een variabele
p. 37
De variabele ‘$tabel’ wordt gedefinieerd door alles wat tussen ‘<<<tabel’ en ‘tabel’ staat.
Wanneer deze variabele wordt afgeprint met een ECHO zal alles tussen deze tekens
worden weergegeven op het scherm.
Zoals het voorbeeld aantoont, werden eerst de kolomtitels gedefinieerd en in de
variabele $tabel gestoken.
Vervolgens werd een SELECT-operatie uitgevoerd op de database die alle gegevens,
nodig om de tabel op te vullen, ophaalt. Meestal zullen er meerdere entiteiten — in
plaats van één entiteit — bewaard zijn. Het resultaat van de zoekactie levert met andere
woorden meestal een lijst van rijen op in plaats van één enkele rij. Om elk specifiek
resultaat op te vangen, wordt gebruik gemaakt van de functie mysqli_fetch_array(), die
vervolgens in een while-lus wordt gestoken (PHP.NET, 2010). Op die manier gaat het
programma, beginnend met de eerste rij, de rijen van het verkregen resultaat af tot er
geen rijen meer zijn. Elk resultaat binnen een rij wordt opgevangen door een specifieke
variabele. Deze variabelen worden vervolgens, net zoals bij de variabele $tabel, in de
grote variabele $gegevens gestoken. De waarden worden aan $gegevens toegekend
door middel van het teken ‘.=’ in plaats van ‘=’ zoals dit bij $tabel het geval is. Op die
manier worden aan de variabele $gegevens resultaten toegevoegd in plaats van
vervangen. $gegevens krijgt met andere woorden geen nieuwe waarde. Nadat de rij van
gegevens in $gegevens is gestoken, kunnen de variabelen opnieuw worden gebruikt om
de volgende rij van gegevens op te vangen. Bij het beëindigen van de while-lus zitten alle
rijen opgeslagen in de variabele $gegevens (Naramore et al., 2005).
Elke rij begint met ‘<input type="checkbox" value="$Xid" name="XXX[]">’. Dit dient om
een entiteit te selecteren via een checkbox waarbij de unieke ID van deze entiteit wordt
meegegeven wanneer men een POST uitvoert. Dit gebeurt wanneer men op één van de
knoppen naast de tabel drukt. Door deze unieke IDs kunnen de entiteiten op een
volgende webpagina gemakkelijk worden terug gevonden.
Nu moet enkel nog de tabel worden gesloten met een sluitingstag. Dit gebeurt met de
variabele $einde.
Op hun beurt worden de variabelen $tabel, $gegevens en $einde in de variabele
$overzicht gestoken, die dan wordt geëchood. Op die manier wordt per entiteittype een
overzicht verkregen van alle entiteiten die zich in de databank bevinden.
p. 38
Een eerste kanttekening die gemaakt moet worden bij deze beschrijving, is dat het
algemene overzicht wel alle entiteiten toont, maar daardoor nog niet alle informatie
bevat. Zoals eerder gezegd werd ervoor gekozen om voor entiteiten die een redelijk
aantal attributen bezitten enkel de meest essentiële attributen te tonen26.
Ook werd ervoor gekozen de tabellen een absolute positie te geven, namelijk 200 pixels
van het scherm af. Zo kan er plaats worden gemaakt voor de knoppen die de aanzet
zullen geven tot de verdere manipulaties van de geselecteerde gegevens. Er werden vier
standaardknoppen voorzien, die in elk van de overzichten terugkomen: ‘Detail’,
‘Toevoegen’, ‘Verwijderen’ en ‘Wijzigen’. Daarnaast staan er nog één of twee knoppen
om te rangschikken naargelang het overzicht dat gekozen wordt. Hierop wordt dieper
ingegaan in de specifieke hoofdstukken daar het rangschikken verschillend is per soort
entiteittype. Al deze knoppen hebben een vaste positie gekregen door te definiëren
hoeveel ruimte er moet gelaten worden ten opzichte van de linker- en bovenrand van
het scherm. Nemen we bijvoorbeeld de knop ‘Detail’ in het overzicht van de
voorzieningen, dan definieert ‘style="width: 120px; position:fixed; left: 2px; top: 310px"’
de vaste positie van de knop. Hierdoor blijven de knoppen staan wanneer men in het
overzicht naar beneden scrolt. Op die manier moet men niet telkens teruggaan naar het
begin van de pagina om een bepaalde actie te selecteren.
De volgende figuur geeft een voorbeeld van hoe een overzicht er in de praktijk uitziet.
26 Ons deel bestond er namelijk niet in om een webpagina te produceren op basis waarvan output, zoals
printen, kan worden gegenereerd. Dit behoort tot de taken van de andere groep.
p. 39
Figuur 9: Het algemene overzicht van voorzieningen
p. 40
3.3.1.2 DETAIL
Wanneer op de detailknop geklikt wordt, worden de IDs van alle geselecteerde entiteiten
in een lijst doorgestuurd naar de detailpagina. Hier wordt eerst en vooral gecontroleerd
of deze lijst al dan niet leeg is. Wanneer dit het geval is, wordt men onmiddelijk
teruggestuurd naar de overzichtspagina. Als geen entiteiten geselecteerd werden,
betekent dit met andere woorden dat de overzichtspagina in kwestie gewoon vernieuwd
wordt. Dit geldt ook voor de knop ‘Verwijderen’ en ‘Wijzigen’. Op die manier is het niet
nodig een aparte knop ‘Vernieuwen’ te voorzien. De administratie van Bizon vzw werd
hiervan uiteraard op de hoogte gebracht.
Wanneer er wel IDs aanwezig zijn in de lijst, wordt gebruik gemaakt van een for-lus in
PHP om de lijst af te gaan. Het aantal keren dat deze lus doorlopen wordt, werd op
voorhand berekend door middel van de functie count()(PHP.NET, 2010). Per ID wordt alle
informatie van de overeenkomstige entiteit opgehaald. Dit gebeurt via een SELECT-
operatie, waar door middel van de WHERE-clausule en de ID, de zoekactie kan worden
vernauwd tot de gewenste entiteit. Deze informatie wordt tijdelijk opgeslagen in een
aantal variabelen.
Om een goed overzicht te krijgen, werd een tabel gemaakt waarin in de eerste kolom het
soort informatie wordt vermeld. In de overeenkomstige cel van de tweede kolom wordt
de specifieke waarde uit de database weergegeven. Naargelang het type, worden de
waarden in inputvelden, checkboxen, textarea’s geplaatst. Op die manier worden de
waarden extra geaccentueerd. Aangezien deze velden niet dienen om informatie te
verzenden en om verwarring te voorkomen, werd de optie ‘readonly’ binnen de input- en
textareatag geactiveerd. Als gevolg hiervan kan de informatie binnen de velden niet
worden gewijzigd of verwijderd. Dit betekent niet dat niet meer kan geïnterageerd
worden met het veld. Wanneer bijvoorbeeld het inputveld te klein is om alle informatie
weer te geven, kan men nog steeds door de informatie scrollen. Daar ‘readonly’ nog
steeds interactie met checkboxen en radiobuttons toelaat, moet bij deze velden een
andere optie worden geactiveerd, namelijk ‘disabled’. Deze optie schakelt de interactie
van de gebruiker met checkboxen en radiobuttons uit.
p. 41
Na elke informatieblok werd een knop ‘Terug’ voorzien, die de gebruiker terug
doorverwijst naar het overzicht. Op die manier bestaat er een duidelijk onderscheid
tussen de verschillende informatieblokken. Het belangrijkste voordeel is dat de gebruiker
altijd de mogelijkheid heeft om terug te keren zonder dat die verplicht wordt helemaal
naar beneden te scrollen (Naramore et al, 2005).
In volgende figuur wordt een voorbeeld gegeven van hoe zo’n gedetailleerde pagina er
precies uitziet.
p. 42
Figuur 10: Het detailoverzicht van een activiteit
p. 43
3.3.1.3 TOEVOEGEN
Door op de knop ‘Toevoegen’ te klikken kan één entiteit per keer worden toegevoegd.
Hierdoor komt men op de toevoegpagina terecht waar een overzicht wordt gegeven van
een aantal inputvelden die kunnen worden ingevuld. Hierbij wordt duidelijk een
onderscheid gemaakt tussen de verplichte en niet-verplichte velden. Verplichte velden
worden met een sterretje aangeduid. Zoals eerder gezegd, heeft het geen nut om lege of
nietszeggende entiteiten toe te voegen aan de database.
Op deze pagina zijn er drie knoppen voorzien: ‘Toevoegen’, ‘Annuleren’ en ‘Reset’. Tijdens
het toevoegingsproces kan altijd worden teruggegaan naar het algemeen overzicht via de
annuleringsknop. De resetknop verwijdert alle informatie binnen de inputvelden. Wanneer
op de toevoegingsknop wordt geklikt, worden alle gegevens binnen de inputvelden
doorgestuurd naar dezelfde pagina. Doordat de knop ‘Toevoegen’ ook een naam heeft kan
— via if-voorwaarden — een onderscheid gemaakt worden tussen de opdrachten die
moeten uitgevoerd worden wanneer op desbetreffende knop werd geklikt en opdrachten
die moeten uitgevoerd worden wanneer dit niet het geval is. Door een naam te geven aan
een knop, kan immers ook de status van de knop worden meegegeven. De functie isset(),
die gebruikt wordt als conditie in de if-voorwaarden, geeft de waarde ‘false’ als de knop niet
werd aangeklikt en in het andere geval de waarde ‘true’ (PHP.NET, 2010).
Nadat op de knop ‘Toevoegen’ werd geklikt, worden eerst alle waarden gepost en in
variabelen gestopt. Daarna wordt er ook een boolean $Test aangemaakt die op ‘true’ wordt
geïnitialiseerd. Vervolgens wordt gecontroleerd of de verplichte velden wel degelijk inhoud
hebben. Indien ten minste één van deze variabele geen waarde heeft, zal de waarde van
$Test naar ‘false’ worden omgezet. Tevens zal per leeg, verplicht veld een specifieke
waarschuwingsboodschap aan een variabele worden toegewezen.
Nu kunnen zich 2 situaties voordoen:
De verplichte velden zijn ingevuld.
De waarde van $Test blijft dus ‘true’. Als gevolg hiervan wordt overgegaan naar een
volgende test. Hierbij wordt opnieuw een boolean aangemaakt en geïnitialiseerd op ‘true’,
namelijk $Test2. Bij deze tweede test wordt nagegaan of één of meerdere entiteiten die
reeds in de database zijn opgeslagen, gelijkaardig zijn aan de nieuw op te slagen waarden.
p. 44
Voor tekstvariabelen gebeurt dit door middel van de functie soundex(), die standaard in php
is ingebouwd. Deze functie gaat na of de twee variabelen hetzelfde klinken, wat de test
hoofdletterongevoelig maakt en ook minder gevoelig is voor spaties (PHP.NET, 2010). Deze
test kan twee gevolgen hebben.
- De test heeft geen gelijkaardige entiteiten gevonden. Dit wil zeggen dat $Test2 de
waarde ‘true’ behoudt. Hierdoor wordt de entiteit toegevoegd aan de database via de
SQL-opdracht ‘INSERT’. De gebruiker krijgt een boodschap dat de entiteit succesvol is
toegevoegd. Door middel van de functie mysqli_insert_id() wordt de ID van de
toevoegde entiteit opgezocht en medegedeeld aan de gebruiker (PHP.NET, 2010).
- De test heeft wel gelijkaardige entiteiten gevonden. Hierdoor wordt de waarde van
$Test2 ‘false’. Er wordt een tabel opgesteld met alle gelijkaardige entiteiten. Deze
tabel wordt op dezelfde manier gemaakt als de tabel bij overzichten met het enige
verschil dat er geen checkboxen voorzien zijn. De tabel wordt afgebeeld op het scherm
en er wordt gevraagd of de gebruiker wel zeker is dat hij of zij de entiteit wilt
toevoegen. Hierbij wordt ook de mogelijkheid gegeven om aan de velden een nieuwe
waarde toe te kennen. De gebruiker kan kiezen tussen neen of ja. Kiest de gebruiker
kiest de optie ‘Neen’ dan wordt de toevoegingspagina gereset en alle waarden worden
verwijderd uit de inputvelden. Wanneer gekozen wordt voor de optie ‘Ja’, wordt
opnieuw gecontroleerd of alle velden daadwerkelijk zijn ingevuld. Dit is nodig doordat
de gebruiker de kans heeft gekregen inhoud van de inputvelden aan te passen. Indien
alle verplichte velden zijn aangepast, zal de entiteit worden toegevoegd. Na het
wijzigen van een aantal velden zal niet nogmaals gecontroleerd worden of de nieuwe
entiteit reeds bestaat. Op die manier wordt vermeden dat de gebruiker gefrustreerd
raakt door de test. Indien niet alle verplichte velden zijn ingevuld, komt men met het
onderstaande scenario terecht.
p. 45
Minstens één verplicht veld is niet ingevuld.
De gebruiker krijgt onder de titel een algemene waarschuwing dat niet alle verplicht in te
vullen velden werden ingevuld. Naast de velden in kwestie komt er een waarschuwing met
specifiekere informatie. Dit wordt gerealiseerd door een derde kolom toe te voegen. De
rijen met de verplichte velden hebben in de derde kolom een specifieke variabele. Deze
variabelen krijgen slechts een inhoud wanneer de overeenkomstige velden niet zijn
ingevuld en de eerste test dus heeft gefaald. Dit scenario herhaalt zich totdat alle verplichte
velden zijn ingevuld. De informatie van de reeds ingevulde velden zal niet verloren gaan.
Deze verschijnen opnieuw in de overeenkomstige inputvelden.
Samengevat zal het programma ervoor zorgen dat alle verplichte velden werden ingevuld
en daardoor het toevoegen van lege of nietszeggende entiteiten voor een groot deel wordt
vermeden. Tevens werd een kleine, doch niet waterdichte test ingevoerd om het opslaan
van dubbele informatie te vermijden.
Het is misschien opgevallen dat slechts één entiteit per keer kan worden aangemaakt,
terwijl de andere manipulaties (verwijderen, detailoverzicht en wijzigen) meerdere
variabelen tegelijkertijd kunnen verwerken. Dit werd gedaan om de code niet nodeloos
complex te maken. Gemakkelijkheidshalve werd een resetknop voorzien. De gebruiker kan
daardoor na het invoegen van een entiteit direct opnieuw een entiteit toevoegen.
Er werd iets minder aandacht besteed aan specifieke inputcontrole. Men zou hierbij de
kritiek kunnen geven dat het even goed mogelijk is in de verplichte velden valse of
nietszeggende informatie neer te typen. Er moet evenwel onthouden worden dat dit deel
van de website enkel toegankelijk is voor de administratie. We gaan er vanuit dat de
medewerkers op de administratie geen kwaadwillige intenties hebben en dus niet
moedwillig verkeerde informatie zouden verspreiden. Met deze test willen we enkel
vermijden dat per vergissing een cruciaal veld zou worden overgeslagen.
Op de volgende pagina kan een voorbeeld gevonden worden van hoe zo’n
toevoegingspagina er precies uitziet.
p. 46
Figuur 11: De webpagina om een jongere toe te voegen
p. 47
3.3.1.4 WIJZIGEN
Net zoals bij detailoverzicht, worden bij ‘Wijzigen’ de unieke IDs van de geselecteerde
entiteiten doorgestuurd en met een for-lus één voor één afgelopen. Ook hier wordt een
overzicht gegeven van de reeds ingevulde velden. Het verschil is dat men nu de informatie
wel degelijk kan wijzigen en niet-ingevulde velden kan aanvullen. De informatie van de
verschillende entiteiten wordt per inputveld opgeslagen in een lijst27
. Daardoor moet niet
aan elk inputveld een unieke naam gegeven worden, maar kunnen overeenkomstige
inputvelden dezelfde naam krijgen. Na het wijzigen, worden deze lijsten doorgestuurd. Via
een session blijft de lijst met IDs echter toegankelijk voor gebruik. Dezelfde for-lus die
gebruikt werd om de verschillende IDs af te gaan, kan ook nu gebruikt worden om de juiste
informatie uit de lijsten te halen. De informatie van de eerste entiteit zit opgeslagen in het
eerste element van elke lijst. Ook hier wordt, op gelijkaardige wijze als bij ‘Toevoegen’,
getest of alle verplichte velden een inhoud bezitten. Is dit het geval, dan zal de entiteit
gewijzigd worden met een UPDATE-opdracht (PHP.NET, 2010). De vernieuwde entiteit
wordt opnieuw afgeprint met de melding dat deze succesvol is gewijzigd. Wanneer per
ongeluk één of meerdere verplichte velden werden gewist, zal er, net zoals bij ‘Toevoegen’,
een melding komen dat het veld moet worden ingevuld. Men bevestigt steeds door op de
knop ‘Wijzigen’ te drukken.
Het enige nadeel is dat de persoon de melding krijgt dat de entiteit gewijzigd zijn zelfs
indien geen enkel attribuutwaarde van de desbetreffende entiteit is gewijzigd. Doordat de
attribuutwaarden van de entiteit steeds worden afgebeeld vormt dit een niet al te groot
probleem, omdat men telkens precies kan zien wat wel of niet is gewijzigd (Naramore et al.,
2005).
Op de volgende pagina is een voorbeeld te vinden van hoe een wijzigingspagina eruit ziet.
27 Een lijstvariabele wordt gekenmerkt door vierkante haakjes [].
p. 48
Figuur 12: Het wijzigen van een transportinfo
p. 49
3.3.1.5 VERWIJDEREN
Het verwijderen van entiteiten werkt volgens hetzelfde principe als het wijzigen ervan of
het geven van een detailoverzicht. Hierbij worden alle geselecteerde entiteiten in een tabel
weergegeven en wordt gevraagd of deze entiteiten al dan niet definitief mogen worden
verwijderd. Bij het indrukken van de knop ‘Ja’ worden de entiteiten één voor één
verwijderd via een DELETE-opdracht. Hierna wordt de melding gegeven dat alle gegevens
succesvol verwijderd zijn en met de knop ‘Terug’ kan men naar het vernieuwde overzicht
gaan. Met de knop ‘Neen’ wordt gewoon teruggekeerd naar het oorspronkelijk overzicht.
Zoals eerder vermeld, werd deze buffer ingebouwd opdat gegevens niet ongewild zouden
verwijderd worden doordat men bijvoorbeeld per ongeluk op ‘Verwijderen’ heeft geklikt in
plaats van ‘Wijzigen’ (Naramore et al., 2005).
In volgende figuur wordt een voorbeeld gegeven van de melding die gegeven wordt
wanneer één of meerdere entiteiten werden geselecteerd om te worden verwijderd.
In wat volgt wordt een overzicht gegeven van de verschillende manipulaties voor elk van de
entiteittypes. Hierbij wordt enkel ingegaan op functionaliteiten die specifiek zijn voor het
entiteittype in kwestie.
p. 50
Figuur 13: De webpagina om activiteiten te verwijderen
p. 51
3.3.2 Voorzieningen
Zoals vermeld, duidt het entiteittype ‘Voorzieningen’ op de instellingen die
verantwoordelijk zijn voor de jongeren. Alle communicatie over de jongeren gebeurt dus via
deze voorzieningen.
Bij voorzieningen werd gevraagd om een attribuut ‘Verborgen’ aan te maken. Wanneer een
bepaalde voorziening verborgen is, mag deze niet worden weergegeven in het algemene
overzicht. Dit werd gevraagd omdat het kan gebeuren dat een voorziening een tijd lang
geen jongeren inschrijft. Hierdoor wordt deze voorziening storend in het overzicht. Toch
kunnen deze voorzieningen niet verwijderd worden, omdat vroegere inschrijvingen van de
jongeren van deze voorzieningen in de database blijvend moeten worden bijgehouden.
Bovendien is deze informatie nog nodig, indien zij in de toekomst wel weer jongeren willen
laten deelnemen aan activiteiten. Het moet dus wel mogelijk zijn om de status van een
voorziening te wijzigen en de verborgen voorzieningen terug zichtbaar te maken. Met deze
mogelijkheid zal dus extra rekening moeten worden gehouden.
3.3.2.2 OVERZICHT
Standaard worden de voorzieningen op het attribuut ‘NaamVoorziening’ geordend door de
SQL-clausule ‘ORDER BY’. Om makkelijk te navigeren door de voorzieningen is er een
mogelijkheid voorzien om de voorzieningen te rangschikken volgens een aantal parameters.
De verschillende parameters waartussen kan gekozen worden, hebben al dan niet een
waarde in hun option-tag. Dit hangt af van het feit of de optienaam dezelfde is als hun
overeenkomstige attribuutnaam. Bijvoorbeeld de optie ‘Verantwoordelijke’ wordt
opgeslagen in de database onder de attribuutnaam ‘NaamVerantwoordelijke’. Hierdoor is
er nood om een waarde te definiëren, opdat de attribuutnaam ‘NaamVerantwoordelijke’ in
plaats van de optienaam ‘Verantwoordelijke’ wordt gestuurd nadat men op rangschikknop
heeft gedrukt. De attribuutnaam wordt na het posten gestoken in de variabele
$Rangschikken, die vervolgens na de ORDER BY wordt gezet. Op die manier wordt eerst
gerangschikt op de zelf gekozen paramater en in tweede instantie op de naam van de
voorzieningen. In het selectieveld van rangschikken wordt standaard ‘Voorziening’
geselecteerd, opdat men gemakkelijk terug kan gaan naar het standaardoverzicht.
p. 52
Er kan ook op een parameter geselecteerd worden die oorspronkelijk niet in het overzicht is
opgenomen. Wanneer dit het geval is, wordt een kolom bijgemaakt met de juiste
kolomtitel, waaronder de overeenkomstige gegevens worden toegevoegd.
Binnen het standaardoverzicht geldt dat enkel voorzieningen worden getoond die niet
verborgen zijn. Dit wordt verzekerd met de if-voorwaarde ‘$Verborgen != "Ja"’. Toch is er
een mogelijkheid voorzien om de verborgen voorzieningen te tonen op het scherm.
Wanneer in het selectieveld van Rangschikken ‘Verborgen’ wordt gekozen, worden de
voorzieningen niet alleen gerangschikt, maar worden ook de verborgen voorzieningen
getoond. Vooraleer de gegevens worden opgenomen in de variabele $gegevens moeten ze
dus aan de volgende voorwaarde voldoen: ‘if ($Verborgen != "Ja" ||
$Rangschikken=="Verborgen")’. Op die manier bestaat er dus de mogelijkheid om toch nog
de verborgen entiteiten te manipuleren zonder dat ze het algemene overzicht storen.
3.3.2.3 DETAIL
Bij het detailoverzicht van voorzieningen is er geen bijzondere code geïmplementeerd die
nog niet werd uitgelegd.
3.3.2.4 TOEVOEGEN
Bij ‘Toevoegen’ werd een handige functie geïmplementeerd om de provincie te berekenen.
veld ‘Land’ verplicht gemaakt. Wanneer het land overeenkomt met ‘Belgie’28
zal de inhoud
van het provincieveld vervangen worden door het resultaat van de functie
bereken_provincie(). Deze functie heeft als paramater een Belgische postcode nodig,
waaruit de provincie wordt berekend via een specifiek algoritme29
. Op die manier moet de
administratie niet telkens opzoeken tot welke provincie een gemeente behoort.
28 Dit is geen schrijffout. Het is blijkbaar moeilijk om de letter e met een trema op te slaan in een SQL-database.
Nadat heel wat tijd werd gespendeerd aan het zoeken van een goede oplossing, werd besloten om het woord
‘België’ als ‘Belgie’ op te slaan. In het detailoverzicht zal dit echter op de juiste manier worden weergegeven,
namelijk als ‘België’ via een if-voorwaarde. 29
Dit algoritme werd reeds eerder besproken op p.25.
p. 53
Men zou de kritiek kunnen geven op het feit dat het hier om een onnodige functie gaat,
omdat de provincie geen noodzakelijk element vormt van de adresgegevens van een
briefcorrespondentie. Zoals eerder vermeld echter, spelen de provinciegegevens een
belangrijker element dan op het eerste zicht lijkt. Afhankelijk van de geografische,
provinciale verspreiding van de deelnemende jongeren krijgt Bizon meer of minder
subsidies.
3.3.2.5 WIJZIGEN
Bij het wijzigen van voorzieningen is er geen bijzondere code geïmplementeerd die nog niet
werd uitgelegd.
3.3.2.6 VERWIJDEREN
Vooraleer men een voorziening kan verwijderen, moeten eerste alle jongeren die gekoppeld
zijn aan deze voorziening worden verwijderd. Deze restrictie werd ingevoegd om fouten
binnen de databank te vermijden. Anders zouden bepaalde jongeren plots niet meer
gekoppeld zijn aan een voorziening, wat in de praktijk niet mogelijk is. Wanneer de
gebruiker dit wel probeert te doen, wordt er een foutmelding gegenereerd die de gebruiker
erop wijst dat de fout mogelijks hieraan te wijten is en wordt er verzocht eerst alle
gekoppelde jongeren te verwijderen.
p. 54
3.3.3 Activiteiten
Dit entiteittype wordt in 3 soorten onderverdeeld: ééndagsactiviteiten, weekends en
kampen. Dit wordt gedaan omdat elk soort activiteit anders wordt afgehandeld. Zo is
bijvoorbeeld een ééndagsactiviteit gratis, terwijl kampen een dagprijs hebben.
Daar activiteiten elk jaar terugkomen, kan men de kampen over de jaren heen moeilijk van
elkaar onderscheiden door enkel naar hun naam te kijken. Om vergissingen te voorkomen
werd daardoor reeds in het oude beheersysteem de annulatiedatum bij elke activiteit
vermeld. Er wordt immers vermeden dat twee kampen tegelijkertijd dezelfde naam alsook
dezelfde annulatiedaum hebben. Deze oplossing wordt ook in dit systeem opgenomen.
3.3.3.2 OVERZICHT
Een eerste probleem dat zich voordoet bij het opstellen van een algemeen overzicht voor
activiteiten, is het weergeven van de data. Doordat SQL een Amerikaans database
management systeem is, worden de data volgens dit systeem opgeslagen. Wanneer deze
data vervolgens worden opgehaald, worden deze data op de Amerikaanse manier
weergegeven. In deze schrijfwijze schrijft men eerst het jaar, dan de maand en eindigt men
met de dag. Om verwarring te voorkomen moeten deze data worden omgezet naar onze
schrijfwijze, waarbij wordt begonnen met de dag en geëindigd met het jaar. Dit gebeurt
binnen de SQL-zoekopdracht door de functie concat(). Deze functie haalt naar wens de dag,
de maand of het jaar uit de datum. Op deze manier kan de datum naar wens worden
weergeven. Voor onze schrijfwijze luidt de opdracht als volgt: ‘concat(day(Datum, '-',
month(Datum),'-', year(Datum))as Datum’. Het laatste stukje van de opdracht ‘as Datum’
definieert aan dit nieuw gegeven een naam, opdat dit gegeven zou kunnen gedestilleerd
worden uit de opdracht. Door deze functie kunnen de vertrek-, aankomst- en
annulatiedatum op een goede manier worden weergegeven (PHP.NET, 2010).
Het tweede probleem is gelijkaardig aan het eerste. Een decimaal getal wordt in SQL
opgeslagen door middel van een punt in plaats van een komma. Opdat ook deze getallen
goed zouden weergegeven worden, werd er gebruik gemaakt van de functie str_replace().
Deze functie zorgt ervoor dat een teken binnen een tekst vervangen wordt door een andere
teken. Nemen we bijvoorbeeld de oorspronkelijke dagprijs van een activiteit. Deze wordt
opgeslagen in de variabele $Dagprijs en wordt op volgende manier aangepast: ‘ $Dagprijs =
str_replace('.', ',', $Dagprijs);’. Hierbij is de eerste paramater van de functie het teken dat
p. 55
moet worden vervangen. De tweede parameter is het teken waardoor het eerste teken
moet worden vervangen. De laatste parameter is de string waarin deze manipulatie moet
gebeuren. Door deze functie kunnen het percentage van de medische annulatiekorting
alsook de dagprijs op een juiste manier worden weergegeven.(PHP.NET, 2010)
Er werd gevraagd om in eerste instantie op type te rangschikken. In tweede en derde
instantie werd gekozen voor het jaar van de annulatiedatum en de naam van het kamp.
Mocht na het rangschikken op ‘Type’ enkel nog worden gerangschikt op ‘Naam’, dan
zouden bijvoorbeeld alle kampen met dezelfde naam bij elkaar staan. Dit zou te verwarrend
zijn omdat men wordt verplicht tegelijkertijd te kijken naar de datum en de naam. Om die
reden werd gekozen om als tweede parameter het jaar van de annulatiedatum te
gebruiken. Na het opzoeken van het jaartal, kan men zich zo volledig concentreren op de
namen van de typeactiviteiten.
Om het overzicht volledig te maken is na de dagprijs een euroteken en na procent medische
annulatie een procentteken toegevoegd. Opdat de tekens ordentelijk zouden worden
weergegeven, zijn deze tekens ingevoerd door middel van escapecode. Voor ‘€’ de
escapecode ‘&euro’ en voor ‘%’ de escapecode ‘%’.
3.3.3.3 DETAIL
Bij het detailoverzicht van activiteiten is er geen bijzondere code geïmplementeerd die nog
niet werd uitgelegd.
3.3.3.4 TOEVOEGEN
De Amerikaanse schrijfwijze van data vormt niet alleen een probleem bij de weergave, maar
ook bij het invoegen van gegevens in de databank. De databank zal immers een fout
genereren, indien geprobeerd wordt een datum up te loaden die niet op Amerikaanse
manier is samengesteld. Om dit probleem te vermijden werd ervoor geopteerd om de dag,
de maand en het jaar apart in te geven door middel van selecteervelden. Op die manier kan
de datum nadien relatief eenvoudig naar gewenste vorm worden samengesteld. De
ingediende annulatiedatum wordt op volgende manier terug samengesteld: ‘$datumADK =
$jaarA.'-'.$maandA.'-'.$dagA;’.
p. 56
Een ander voordeel van deze selecteervelden is dat men geen onmogelijke data kan
invullen en zo wordt vermeden dat de databank frustrerende foutmeldingen zou genereren.
Men kan dus niet per ongeluk een dertiende maand als input geven.
Voor ééndagsactiviteiten geldt een speciale inputcontrole voor het inputveld
‘Annulatiedatum’. Aangezien ééndagsactiviteiten gratis zijn, lijkt het onnodig een
annulatiedatum in te vullen, daar een annulatiedatum alleen betrekking heeft op het al dan
niet terugbetalen van het reeds gestorte inschrijvingsgeld. Omdat de annulatiedatum echter
een cruciale rol speelt in het onderscheiden van activiteiten met dezelfde naam, wordt
gevraagd in het jaarveld van de annulatiedatum het jaar in te vullen dat de activiteit zich
voordoet. Als annulatiedatum wordt dan de laatste dag van dat jaar opgeslagen in de
databank. Daar de annulatiedatum geen betekenis heeft voor een ééndagsactiviteit, zal
deze handeling niet leiden tot fouten en kan annulatiedatum nog steeds worden gebruikt
om een activiteit te identificeren.
Er geldt ook een specifieke inputcontrole voor deze data. De data moeten niet alleen
verplicht ingevuld worden maar moeten ook in de juiste chronologische volgorde
plaatsvinden. Dit wil zeggen dat de annulatiedatum voor de aankomstdatum moet liggen en
de aankomstdatum voor de vertrekdatum. Ook dienen alle data in de toekomst te liggen.
Indien dit niet het geval is, zal een gepaste foutmelding worden gegeven30
.
Voor de inputvelden ‘Dagprijs’ en ‘Procent medische annulatie’ moet een speciale
inputcontrole worden gedaan, omdat een percentage en een dagprijs slechts 2 cijfers na de
komma mogen hebben. Daarbij schrijven wij traditioneel onze decimale getallen met een
komma in plaats van een punt. Om een zeker evenwicht te vinden tussen de noden van de
administratie en de verplichtingen van de databank, werd toegestaan dat het cijfer ofwel
met een komma ofwel met een punt wordt geschreven. Omdat men nogal de neiging heeft
om na een punt of een komma een spatie te schrijven werd ook dit toegestaan. Het getal
wordt gecontroleerd door middel van de zelf geschreven functie ‘decimaalgetal()’31.
30 Uitzondering hierop vormt de ééndagsactiviteit, die geen annulatiedatum heeft. Wel wordt gecontroleerd of de
activiteit plaatsvindt in de toekomst. 31
De functie die hiervoor gebruikt wordt, werd reeds uitgelegd op p.25.
p. 57
Wanneer de input hier niet aan voldoet, krijgt de gebruiker onderaan de pagina een
volledige uitleg welke schrijfwijzen wel zijn toegelaten. Wanneer de input correct is, worden
de spaties verwijderd en de komma vervangen door een punt via de reeds beschreven
‘str_replace()’ (PHP.NET, 2010). Op deze manier zal de input aanvaard worden door de
database.
3.3.3.5 WIJZIGEN
Bij het wijzigen van activiteiten is er geen bijzondere code geïmplementeerd die nog niet
werd uitgelegd.
3.3.3.6 VERWIJDEREN
Activiteiten kunnen niet verwijderd worden indien er inschrijvingen bestaan die nog
gekoppeld zijn aan deze activiteiten. Net zoals bij voorzieningen, zal bij het voordoen van
een fout de gebruiker erop gewezen worden dat hij of zij eerst de gekoppelde inschrijvingen
moet verwijderen en dan pas de activiteit in kwestie kan verwijderen.
p. 58
3.3.4 Jongeren
Vanzelfsprekend duidt het entiteittype ‘Jongeren’ op de kinderen die deelnemen aan de
verschillende activiteiten. Zoals vermeld, zijn deze jongeren steeds gekoppeld aan een reeds
geregistreerde voorziening.
3.3.4.2 OVERZICHT
Om gemakkelijk te kunnen navigeren doorheen de jongeren, werd de mogelijkheid
ontworpen om enkel de jongeren van 1 bepaalde voorziening te tonen. Deze mogelijkheid
werd op een speciale manier samengesteld via de variabele $gegevens. Het selecteerveld
wordt stukje voor stukje opgebouwd, door deeltjes code toe te voegen aan de variabele
$gegevens:
$selecteer .= '<br/><select name="Rangschikken" class="dropdown"
style="width: 120px; position:fixed; left: 7px; top: 215px">';
$selecteer .= "<option value=\"Alle Voorzieningen\" selected=\"yes\">
Alle Voorzieningen</option>";
$Voorzieningen = "SELECT NaamVoorziening, Vid, StraatEnNummer, Gemeente
from Voorzieningen WHERE Verborgen='Neen' order by NaamVoorziening";
$tussen=mysqli_query($connect,$Voorzieningen);
if(!$tussen){
[…]
}
while ($rijvoorzieningen=mysqli_fetch_array($tussen)){
$Vid = $rijvoorzieningen['Vid'];
$NaamVoorziening= stripslashes($rijvoorzieningen['NaamVoorziening']);
$StraatEnNummer = stripslashes($rijvoorzieningen['StraatEnNummer']);
$Gemeente = stripslashes($rijvoorzieningen['Gemeente']);
$selecteer .= "<option value=\"$Vid\" $gekozen>$NaamVoorziening in
$StraatEnNummer $Gemeente</option>";
}
$selecteer .= "</select>";
De optie ‘Alle voorzieningen’ wordt automatisch geselecteerd, opdat gemakkelijk terug zou
kunnen worden gegaan naar het oorspronkelijk overzicht nadat men een selectie heeft
uitgevoerd. Daarna wordt door middel van een SELECT-operatie alle voorzieningen —
weliswaar de niet-verborgen voorzieningen — uit de databank gehaald. Per rij worden alle
gegevens opgehaald en binnen een optieveld op de juiste plaats gezet.
Figuur 14: Een voorbeeld van het ontwikkelen van een selecteermenu om te rangschikken
p. 59
Wanneer nu een specifieke voorziening werd geselecteerd en op de knop ‘Rangschikken’
geklikt, wordt het klantennummer van de voorziening gepost in de variabele $Vid. Deze
variabele dient op zijn beurt als een stukje voor de variabele $Rangschikken. $Rangschikken
heeft als inhoud een vernauwende WHERE-clausule waarbij de IDs van de voorzieningen
gelijk moeten zijn aan $Vid. $Rangschikken wordt op de gepaste plaats binnen de SELECT-
opdracht geplaatst. Deze opdracht is verantwoordelijk voor de inhoud van het algemene
overzicht. Op die manier worden slechts die jongeren geselecteerd die behoren tot een
bepaalde voorziening. Wanneer men vervolgens terug voor ‘Alle voorzieningen’ kiest, zal de
variabele $Rangschikken leeg worden gemaakt, zodat het geen invloed heeft op de SELECT-
opdracht.
3.3.4.3 DETAIL
Bij het detailoverzicht van jongeren is er geen bijzondere code geïmplementeerd die nog
niet werd uitgelegd.
3.3.4.4 TOEVOEGEN
Bij het toevoegen van jongeren is er geen bijzondere code geïmplementeerd die nog niet
werd uitgelegd.
3.3.4.5 WIJZIGEN
Zoals eerder vermeld, kunnen bij wijzigen meerdere entiteiten worden geselecteerd.
Hierdoor worden alle gegevens opgeslagen in lijsten en krijgen overeenkomstige
inputvelden van verschillende entiteiten dezelfde naam. Dit gaf een probleem bij
inputvelden van het type ‘radiobutton’. Doordat deze velden dezelfde naam hadden, kon
het geslacht slechts voor één entiteit gewijzigd worden. Wanneer dus geprobeerd werd bij
de volgende jongere het geslacht te wijzigen of te selecteren, verdween de input voor het
geslacht van de eerste jongere. Het was dus noodzakelijk om per jongere de radiobuttons
een unieke naam te geven. Daarom werd de naam van de radiobuttons niet ‘Geslacht[]’,
zoals gebruikelijk zou zijn geweest bij andere inputtypes. In de plaats daarvan werd er
gekozen voor ‘Geslacht<?php echo $i ?>’. Op die manier krijgen de radiobuttons per jongere
een unieke naam en kan dus de waarde van het geslacht van elke jongere zonder
problemen worden weergegeven en aangepast.
p. 60
De test die nagaat of een jongere reeds in de databank aanwezig is, gebeurt op basis van
voornaam en familienaam. Hierbij wordt de geboortedatum niet gebruikt. Dit kan vreemd
overkomen, omdat dit een goede parameter lijkt om na te gaan of een jongere
daadwerkelijk in de database zit. Toch werd er gekozen om dit niet te doen, omdat soms
niet de werkelijke geboortedatum wordt ingevuld. Dit wordt gedaan om de jongere toch
nog de mogelijkheid te geven om hem/haar te laten meegaan op een bepaalde activiteit.
3.3.4.6 VERWIJDEREN
Bij het verwijderen van jongeren is er geen bijzondere code geïmplementeerd die nog niet
werd uitgelegd.
p. 61
3.3.5 Transportinformatie
De transportinformatie voor een bepaalde activiteit wordt per voorziening bijgehouden.
3.3.5.2 OVERZICHT
Bij het overzicht van transportinfo is er geen bijzondere code geïmplementeerd die nog niet
werd uitgelegd.
3.3.5.3 DETAIL
Bij het detailoverzicht van transportinfo is er geen bijzondere code geïmplementeerd die
nog niet werd uitgelegd.
3.3.5.4 TOEVOEGEN
Als een transportinfo wordt toegevoegd, dan zal de pagina herlaad worden indien een activiteit
wordt geselecteerd. Per activiteit wordt bij het veld ‘Voorziening’ enkel die voorzieningen
getoond die één of meerdere jongeren hebben ingeschreven en waarvan nog geen
transportinfo is gespecificeerd. Dit gebeurt door middel via een script dat na het herladen van
de pagina de ID van de activiteit doorstuurt. Deze waarde wordt door middel van een GET
opgevangen. Deze waarde wordt vervolgens in de WHERE-clausule van de opzoekinstructie van
voorzieningen geplaatst, zodat enkel de deelnemende voorzieningen worden getoond.
3.3.5.5 WIJZIGEN
Bij het wijzigen van transportinfo is er geen bijzondere code geïmplementeerd die nog niet
werd uitgelegd.
3.3.5.6 VERWIJDEREN
Bij het verwijderen van transportinfo is er geen bijzondere code geïmplementeerd die nog
niet werd uitgelegd.
p. 62
3.3.6 Inschrijvingen
Bij dit entiteittype worden jongeren die gekoppeld zijn aan een bepaalde voorziening,
ingeschreven voor een bepaalde activiteit. Dit vormt het hoofddoel van dit systeem,
namelijk het managen van inschrijvingen en annulaties voor de activiteiten.
3.3.6.2 OVERZICHT
Wat misschien opvalt bij het overzicht van inschrijvingen, is dat ook de opmerkingen
worden getoond in het algemeen overzicht. Dit kwam er op vraag van de administratie van
Bizon tijdens het feedbackmoment. Hierbij werd eerst geduid op de mogelijke verstoring
van het algemeen overzicht. Een opmerking kan immers zeer groot zijn (meer als 200
karakters), wat een rudimentair overzicht niet ten goede zou komen. Na overleg werd
besloten slechts de eerste 40 karakters van de opmerking te tonen. Op die manier heeft de
administratie de mogelijkheid om in het begin van de opmerking de meest fundamentele
commentaar te melden en eventueel dit veld nog bij te vullen met bijkomende, langere
commentaar zonder het overzicht overhoop te halen.
3.3.6.3 DETAIL
Het spreekt voor zich dat men in het detailoverzicht de gehele opmerking kan lezen.
3.3.6.4 TOEVOEGEN
Bij het toevoegen van inschrijvingen is er geen bijzondere code geïmplementeerd die nog
niet werd uitgelegd.
3.3.6.5 WIJZIGEN
Bij het wijzigen van inschrijvingen is er geen bijzondere code geïmplementeerd die nog niet
werd uitgelegd.
3.3.6.6 VERWIJDEREN
Bij het verwijderen van inschrijvingen is er geen bijzondere code geïmplementeerd die nog
niet werd uitgelegd.
p. 63
3.3.6.7 PUBLIEKE INSCHRIJVING
Hoewel het niet de belangrijkste doelstelling was voor Bizon vzw, hadden zij graag gehad
dat een voorziening in staat zou zijn om zelf, via de website, jongeren aan te melden voor
een activiteit. Om hieraan tegemoet te komen werd een extra pagina gemaakt waarvoor
geen gebruikersnaam, noch paswoord is vereist32
. Wel is het noodzakelijk dat de
voorziening haar klantennummer opgeeft bij de inschrijving. Op dit ogenblik zijn echter
twee soorten klantennummers in gebruik: één met enkel en alleen cijfers en één dat
bestaat uit een ‘b’ of ‘B’, gevolgd door een aantal cijfers. Aangezien in de databank enkel de
cijfers worden opgeslagen, moest ervoor gezorgd worden dat ook de tweede versie werd
aanvaard. Dit wordt gedaan door de input eerst om te zetten naar een geheel getal.
Wanneer blijkt dat dit niet gaat, wordt gekeken of de eerste letter een ‘b’ of een ‘B’ is.
Indien niet, wordt een foutboodschap gegeven. Indien wel, wordt het eerste karakter
genegeerd en wordt geprobeerd om de rest om te zetten naar een geheel getal. Pas
wanneer dit lukt, wordt gezocht in de database of het klantennummer aanwezig is. Indien
niet, wordt ook hier een foutboodschap weergegeven.
Op deze pagina krijgt de voorziening ook een keuzemenu te zien met alle toekomstige
activiteiten van het gekozen type. Indien er op een bepaald ogenblik geen activiteiten van
het gekozen type beschikbaar zijn, wordt dit medegedeeld. Wanneer een activiteit wordt
gekozen, krijgt de voorziening alle relevante data met betrekking tot de keuze33
. Dit wordt
gerealiseerd aan de hand van een Ajaxscript. Het voordeel hiervan is dat de webpagina niet
volledig moet worden herladen telkens een andere activiteit wordt geselecteerd. De code
hiervoor is gebaseerd op de code te vinden op (W3Schools, 2010) en (Microsoft, 2010).
Telkens wanneer een nieuwe waarde wordt geselecteerd wordt het script opgeroepen en
de selectie meegegeven. Het script zorgt er op zijn beurt voor dat een php-pagina wordt
opgeroepen, waarin de nodige gegevens uit de database worden gehaald en op de juiste
manier worden weergegeven34
. Dit resultaat wordt teruggestuurd naar het Ajaxscript die
het uiteindelijk op de aangegeven plaats in de oorspronkelijke pagina weergeeft.
32 Hoewel op de inlogpagina drie verschillende knoppen werden aangebracht — één voor elk type van activiteit —
wordt de gebruiker telkens doorgestuurd naar dezelfde pagina. De inhoud verschilt echter lichtjes naar gelang de
keuze die werd gemaakt. 33
Voor een ééndagsactiviteit is dit de dag waarop deze doorgaat. Voor een weekend of een kamp wordt telkens de
annulatie-, de aankomst- en vertrekdatum weergegeven. 34
Het probleem om data op de juiste manier weer te geven werd reeds besproken op p.54.
p. 64
De data die via deze weg wordt verkregen van de voorziening, wordt opgeslagen in een
tijdelijke tabel zodanig dat de medewerkers een duidelijk overzicht hebben van de
binnengelopen aanvragen.
Op de webpagina van het algemeen overzicht van inschrijvingen is er een knop ‘Aanvragen’
voorzien die de administratie leidt tot een webpagina met een algemeen overzicht van de
publieke inschrijvingen. In dit overzicht vindt men 2 kolommen met de kolomtitels
‘Werkelijke voorziening’ en ‘Ingetypte voorziening’. Deze onderverdeling lijkt misschien op
het eerste zicht vreemd. In werkelijkheid vormt dit een test om na te gaan of de
inschrijvingen daadwerkelijk door een gekende voorziening is gebeurd of door iemand die
zich voordoet als de voorziening. Tijdens de publieke inschrijving moet de voorziening
immers zowel het klantennummer als hun naam opgeven. Door in het overzicht de in de
database opgeslagen naam van de voorziening weer te geven die overeenkomt met het
ingevulde klantennummer, kan de administratie nagaan of deze overeenkomt met de naam
die opgegeven werd tijdens de inschrijving. Indien dit niet het geval is, kan de administratie
de aanvraag verwijderen. Indien dit wel het geval is kan de administratie de voorziening
aanvaarden. Dit ‘aanvaarden’ houdt 3 handelingen in:
- Het toevoegen van de jongere tot de database.
- Het toevoegen van een inschrijving.
- Het verwijderen van de aanvraag.
Hoewel niet specifiek gevraagd, werden twee testen voorzien binnen het aanvaarden van
inschrijvingen. De eerste gaat op basis van voornaam en familienaam na of de jongere reeds
gekend is binnen de Bizon vzw. Indien dit het geval is, krijgt de administratie een overzicht
waaruit men één optie moet kiezen. De mogelijkheid ‘Nieuwe jongere’ zal de jongere
zonder meer toevoegen en wordt de inschrijving aan deze jongere gekoppeld. Deze optie is
standaard geselecteerd. De andere opties zijn de jongeren die lijken op de ingeschreven
jongere. Wanneer één van deze opties wordt gekozen, zal de jongere niet opnieuw
toegevoegd worden, maar zal de inschrijving aan de geselecteerde jongere worden
gekoppeld.
p. 65
De tweede test gaat na of de inschrijving reeds bestaat. Men krijgt een overzicht van de
inschrijvingen die lijken op de aanvraag, samen met twee opties, namelijk ‘Ja’ en ‘Neen’.
Hierbij wordt de vraag gesteld of één van de onderstaande inschrijvingen overeenkomt met
de aanvraag. Standaard is ‘Neen’ geselecteerd. Hierbij wordt de aanvraag zonder meer
toegevoegd. Als men ‘Ja’ kiest, wordt de aanvraag verwijderd, zonder dat de jongere of de
inschrijving wordt toegevoegd.
Aangezien sommige activiteiten volzet kunnen zijn, werd de mogelijkheid voorzien om een
aanvraag te wijzigen. De administratie kan immers de voorziening contacteren en vragen of
de jongere in kwestie niet geïnteresseerd is in een andere activiteit.
3.3.7 Algemene gegevens
Dit zijn de adresgegevens van Bizon. Omdat deze gegevens een belangrijk element vormen
binnen de briefcorrespondentie werd besloten dat enkel administrators deze gegevens
konden wijzigen. Dit is ook de enige manipulatie die met deze gegevens kan worden
gedaan. Het toevoegen of verwijderen van deze gegevens zou geen nut hebben en/of enkel
slechte gevolgen teweeg brengen.
p. 66
3.4 Beveiliging
Tot slot werden een aantal veiligheidsmaatregelen genomen met als doelstelling te zorgen
voor een blijvend goed functioneren van de website. In wat volgt, worden eerst de
mogelijke gevaren van het werken met inputvelden behandelt. Daarna wordt gekeken het
belang van het paswoord. Verder wordt ingegaan op de maatregelen die werden genomen
om zeker te zijn dat niet om het even wie acties kan ondernemen waarvoor
administratorrechten nodig zijn en om ervoor te zorgen dat niet om het even wie toegang
kan krijgen tot de website. Tot slot wordt kort aangetoond op welke manier mogelijke
fouten worden opgevangen.
3.4.1 Toegang
3.4.1.1 SQL – INJECTIONS
Hoewel er steeds enige vorm van input controle is die er voor zorgt dat vreemde tekens
worden voorzien van escape-code enerzijds, en anderzijds nagaat of de data die werd
opgegeven voldoet aan een aantal opgelegde voorwaarden35
, werd voor de publieke
pagina’s nog een extra voorzorgsmaatregel genomen om er zeker van te zijn dat er geen
SQL-injections kunnen plaatsvinden. Een SQL-injection houdt in dat de gebruiker gevaarlijke
tekens invult in de formuliervelden. Dit kunnen onder andere queries zijn die ervoor zorgen
dat een of meerdere tabellen uit de database worden verwijderd, code die ervoor zorgt dat
men ook zonder gebruikersnaam en paswoord kan inloggen of scripts die vertrouwelijke
informatie doorsturen naar de persoon in kwestie (Valade, Ballad, & Ballad, 2008).
Voor het geval de inputcontrole niet in staat zou zijn om deze gevaarlijke input te weigeren,
werd gebruik gemaakt van mysqli statements. Dit houdt in dat de input die met behulp van
de formulieren wordt opgehaald niet rechtstreeks wordt gebruikt in een query. In plaats
daarvan wordt een query gemaakt, waarin de in te vullen velden open worden gelaten en
aangeduid worden door middel van een vraagteken. Daarna wordt het uitvoeren van de
query ‘voorbereid’. Dit zorgt ervoor dat er maximaal één enkele query kan worden
uitgevoerd: de query die in normale omstandigheden ook zou worden uitgevoerd. Wanneer
in de inputvelden een schadelijke query zou worden ingevuld, wordt deze dus niet
35 Zie 3.1.6.3 Escapen van input en 3.1.7 De input
p. 67
uitgevoerd. De inputwaarden worden gebonden aan de opengelaten plaatsen en de query
kan worden uitgevoerd. Daarna moeten de resultaten worden opgeslagen in variabelen,
voordat ze kunnen worden gebruikt en moet de statement terug worden gesloten.
Wanneer in het proces een fout zou optreden, wordt een foutmelding met bijhorende
foutcode weergegeven. De code hiervoor is grotendeels te vinden op (PHP.NET, 2010) en
werd hieronder weergegeven.
3.4.1.2 PASWOORD
Het paswoord is één van de meest belangrijke elementen, aangezien het — in combinatie
met de juiste gebruikersnaam — toegang verschaft tot het beveiligde gedeelte van de
website, en dus ook tot de database. Wanneer het paswoord niet goed gekozen is, kan dat
betekenen dat men in staat is om het te breken en zich op die manier toegang te
verschaffen tot deze database. Dit kan zeer vergaande gevolgen hebben, gaande van
informatie die wordt gekopieerd en het inconsistent maken van de database, tot een totaal
verlies van de database en alle informatie die erin aanwezig is (De Tré, 2007). Als gevolg
daarvan is het dus noodzakelijk dat de nodige aandacht wordt besteed, zowel aan het
generen van het wachtwoord, als de opslag ervan.
$query = "SELECT Paswoord, Voornaam, Familienaam, Email, Admin FROM LoginGegevens WHERE LoginNaam= ?";
if ($stmt = mysqli_prepare($connect, $query)) {
/* bind parameters for markers */
mysqli_stmt_bind_param($stmt, "s", quote_smart($connect,$login));
/* execute query */
mysqli_stmt_execute($stmt);
if(mysqli_stmt_error($stmt))
printf("<p class=\"fout\">Error: %d - %s.\n </p>", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
/* bind result variables */
mysqli_stmt_bind_result($stmt, $Paswoord, $Voornaam, $Familienaam, $Email, $Admin);
/* fetch value */
$row = mysqli_stmt_fetch($stmt);
/* close statement */
mysqli_stmt_close($stmt);
Figuur 15: Beveiliging tegen SQL-injection
p. 68
Naast het verlenen van toegang tot de afgeschermde website, moet het wachtwoord ook
worden ingegeven telkens wijzigingen worden gemaakt aan de gegevens van gebruikers of
gegevens van Bizon vzw zelf. Administrators moeten ook elke keer hun paswoord ingeven
wanneer ze acties ondernemen die niet kunnen worden uitgevoerd door gewone
gebruikers. Hierop wordt in het volgende puntje ingegaan.
Onder een sterk wachtwoord wordt een wachtwoord verstaan die minstens
- één kleine letter
- één hoofdletter
- één getal
- één speciaal teken
bevat. Daarnaast moet het minimaal acht karakters lang zijn, en kan het geen spaties
bevatten.
Zoals eerder vermeld op p.31, kan het genereren van een paswoord enerzijds automatisch
gebeuren. Het voordeel hiervan is dat het bekomen wachtwoord volledig willekeurig is. Het
nadeel ervan echter is dat de mogelijkheid bestaat dat het wachtwoord moeilijk te
onthouden is, waardoor het ofwel vergeten wordt en een nieuw wachtwoord moet worden
aangemaakt, ofwel ergens opgeschreven wordt en het in verkeerde handen kan
terechtkomen. Anderzijds kan een gebruiker zelf een wachtwoord aanmaken. Voordat het
echter definitief wordt goedgekeurd, wordt er eerst op eerder genoemde criteria
gecontroleerd.
Een ander belangrijk punt is de opslag van de paswoorden in de database. Deze moet
zodanig worden opgeslagen dat iemand die inzage krijgt in de gegevens, niet in staat is de
paswoorden hieruit op te maken. Om dit te realiseren werden alle paswoorden versleuteld
opgeslagen. Het versleutelingalgoritme dat hiervoor werd gebruikt is SHA-1. Dit is een
algoritme — gebruikt onder andere door de Verenigde Staten als “Federal Information
Processing Standard” — die de hash berekent van een bepaalde input. SHA-1 is een heel
veilig algoritme, aangezien het zelfs voor een computer niet doenbaar is om een boodschap
te vinden, gegeven een bepaalde hash, of om twee verschillende inputs te vinden die
eenzelfde 160-bit output als resultaat hebben (IETF).
p. 69
3.4.1.3 AANPASSINGEN ADMINISTRATOR
Bepaalde pagina’s zijn enkel toegankelijk voor administrators, en dan nog moeten zij hun
paswoord opgeven elke keer zij een wijziging willen doorvoeren op één van deze pagina’s.
Ondanks deze maatregelen werd opgemerkt dat er wel degelijk een probleem kan optreden
wanneer er twee of meer administrators tegelijk aan het werk zijn. In het specifieke geval
dat één van deze administrators al dan niet per ongeluk de administratorrechten afneemt
van een andere administrator op het moment dat die nog is ingelogd, behoudt deze laatste
toch zijn/haar rechten totdat die uitlogt en opnieuw inlogt. Om te vermijden dat hij/zij net
in die tijdsspanne wijzigingen zou doorvoeren waarvoor speciale rechten nodig zijn, wordt
ook elke keer opnieuw net vóór de wijziging vanuit de database gecontroleerd of de
persoon nog steeds de noodzakelijke rechten heeft. Wanneer dit niet het geval is, worden
de wijzigingen niet doorgevoerd.
Daarnaast werd een extra beveiliging gecreëerd in het geval een gebruiker wordt
verwijderd. Wanneer dit een administrator is, moeten eerst zijn/haar administratorrechten
worden afgenomen. Dit kan gebeuren door het wijzigen van de gegevens, zoals besproken
op p.29. Tot slot is er als extra veiligheid voor gezorgd dat een administrator zichzelf niet
terugvindt in het keuzemenu. Hoewel andere maatregelen er voor zorgen dat een
administrator niet in staat is zichzelf te verwijderen36
, heeft het geen enkele zin dat
zijn/haar gebruikersnaam in het selectiemenu staat.
3.4.1.4 ONGEOORLOOFDE TOEGANG
Ervan uitgaande dat sommige mensen op eenzelfde computer kunnen werken, is er voor
gezorgd dat bovenaan elke webpagina staat als welke gebruiker men is ingelogd. Dit vormt
een onderdeel van de header. Hoewel dit niet specifiek werd gevraagd en het ook geen
garantie biedt dat de persoon die ingelogd is wel degelijk de rechtmatige gebruiker is, kan
er op die manier wel voor gezorgd worden dat een toevallige vergissing snel kan worden
ontdekt.
36 Namelijk het feit dat een administrator zijn/haar eigen rechten niet kan afnemen in combinatie met het feit dat
enkel een administrator een gebruiker kan verwijderen.
p. 70
Verder is ervoor gezorgd dat geen toegang tot de website kan verkregen worden door
rechtstreeks de URL in te vullen. Bovenaan elke pagina die behoort tot het afgeschermde
gedeelte werd onderstaande code aangebracht. Deze verwijst elke persoon die niet is
ingelogd, rechtstreeks door naar de inlog pagina wanneer die al dan niet toevallig een
afgeschermde pagina zou opvragen zonder te zijn ingelogd.
Daarnaast kan een gewone gebruiker, die wel degelijk is ingelogd, proberen rechtstreeks de
URL op te geven van een pagina die bedoeld is voor de administrator. Wanneer dit gebeurt,
krijgt de gebruiker in kwestie een melding te zien die hem of haar erop wijst dat die geen
recht heeft om de pagina te bekijken, waarna hij of zij terug wordt doorverwezen naar de
home pagina. De code is hieronder te vinden.
3.4.2 Opvangen van fouten
Als gevolg van het feit dat meerdere personen op hetzelfde moment wijzigingen kunnen
aanbrengen aan de database, kunnen tal van fouten optreden. Ook al is de kans dat deze
fouten optreden eerder klein, toch wouden wij voorzorgen nemen om deze op te vangen.
Zo is het bijvoorbeeld mogelijk dat de ene gebruiker een jongere wil toevoegen aan een
voorziening, die enkele ogenblikken daarvoor door een andere medewerker werd
verwijderd of dat een administrator de gegevens van een gebruiker wil veranderen die door
een andere administrator net uit de database werd verwijderd. Een meer voorkomende
if ($_SESSION['login'] == "")
echo "<meta http-equiv='Refresh' content='0; URL=../login.php' />";
Figuur 16: Algemene toegangscontrole
<?php
if(!$_SESSION['admin']){ ?>
<html>
<link rel="stylesheet" type="text/css" href="../bizon.css" />
</html><?php
echo "<center><p class=\"fout\">U heeft geen toelating om deze pagina te bekijken. <br/>
U wordt automatisch doorverwezen. Wanneer dit niet gebeurt,<r /> klik dan
<a href=\"../algemeen/centrale.php\">hier</a>.</p></center>";
echo "<meta http-equiv='Refresh' content='2; URL=../algemeen/centrale.php' />";
exit(0);
} ?>
Figuur 17: Toegangscontrole van administrator
p. 71
$query = "SELECT Voornaam, Familienaam, Email, Admin FROM LoginGegevens WHERE LoginNaam= '".$login."'";
$result = mysqli_query($connect,$query);
if(!$result){ // foutmelding wanneer er geen toegang tot de database kan worden gemaakt
echo "<p class=\"fout\">Er is een fout opgetreden in de toegang tot de database.<br />
Gelieve de administrator te verwittigen.<br />";
if($_SESSION['admin']) echo mysqli_errno($connect).": ".mysqli_error($connect);
echo "</p>";
?><form action=""><input type="submit" class="button" value="Terug"
onclick="action='wijziggegevens.php'"/></form><?php
exit(0);
}
$rij = mysqli_fetch_array($result);
if($rij){ //controle of de gegevens aanwezig zijn in de database
$vnaam = stripslashes($rij['Voornaam']);
$fnaam = stripslashes($rij['Familienaam']);
$email = $rij['Email'];
$admin = $rij['Admin']; // ja of neen
} else echo '<p class=\"fout\" align=\"center\" >De gezochte persoon bevindt zich niet meer in de database.<p>';
Figuur 18: Voorbeeld van foutopvanging
fout is dat een medewerker een gegeven probeert te verwijderen dat nog niet kan
verwijderd worden37
. Opdat het duidelijk zou zijn voor de gebruiker wat er precies fout is
gelopen worden deze fouten — indien ze zich voordoen — opgevangen, en wordt een
aangepaste foutmelding op het scherm weergegeven.
Daarnaast is het mogelijk dat er fouten optreden wanneer toegang wordt verzocht tot de
database. Zo is het bijvoorbeeld mogelijk dat deze niet beschikbaar is omdat de server
uitligt. Wanneer zo’n probleem zich voordoet, zal — op vraag van Bizon vzw —de gewone
gebruiker in de boodschap enkel zien dat er een fout is opgetreden. Een administrator
daarentegen krijgt niet alleen de foutboodschap te zien, maar krijgt daarnaast ook nog een
meer technische uitleg met bijhorende foutencode. Op die manier weet hij/zij wat precies
het probleem is en kunnen stappen worden ondernomen om het probleem op te lossen.
Voor beiden kan hieronder een voorbeeld worden gevonden.
Zoals ook eerder gezegd, wordt elke keer er data moet worden toegevoegd, gewijzigd of
verwijderd een controle gedaan om na te gaan of alle verplichte velden werden ingevuld.
Wanneer dit niet het geval is, wordt ook dit gerapporteerd aan de gebruiker in de vorm van
een foutmelding.
37 Zo is het bijvoorbeeld niet mogelijk om een activiteit te verwijderen, wanneer hiervoor nog inschrijvingen
bestaan. Wanneer een gebruiker dit toch zo proberen, krijgt deze een foutmelding die hem/haar hierop wijst.
p. 72
4 Besluit
Bizon vzw gaf de opdracht hun databank te vernieuwen en deze te koppelen aan een
webapplicatie. Deze opdracht werd onderverdeeld in een aantal deelopdrachten:
- Een databankstructuur te ontwikkelen en deze structuur te implementeren.
- Een webapplicatie te ontwikkelen die enkel toegankelijk is voor de administratie,
waarin ze gegevens kunnen toevoegen aan de databank en deze gegevens kunnen
manipuleren.
- Een webapplicatie te ontwikkelen waarin ook voorzieningen de mogelijkheid hebben
jongeren in te schrijven.
- Een beveiliging te implementeren die ervoor zorgt dat de private gegevens worden
afgeschermd.
Via een nauwgezet stappenplan, feedback van de begeleiders en specifieke vragen aan de
administratie, werd een databankstructuur ontwikkeld en vervolgens geïmplementeerd in
een SQL database managementsysteem. Deze structuur verhindert zoveel mogelijk het
opslaan van dubbele informatie en contradicties binnen de database.
Vervolgens werd een webapplicatie ontwikkeld. Dit gebeurde door middel van screenshots
van het verouderde systeem, regelmatige feedbackmomenten met de begeleiders en
specifieke eisen van de administratie.
Op basis van deze informatie werd er enerzijds een publiek deel en anderzijds een privaat
deel ontwikkeld. In het publiek deel krijgen de voorzieningen een duidelijk overzicht van de
toekomstige activiteiten en hebben de mogelijkheid jongeren in te schrijven. In het private
deel kan enkel de administratie gegevens toevoegen en manipuleren.
Tegelijkertijd werd een beveiliging geïmplementeerd. Deze beveiliging zorgt ervoor dat het
private gedeelte van de website enkel toegankelijk is voor de administratie door middel van
een inlogsysteem. In de beveiliging werd ook een managementsysteem voor de
inloggegevens geïmplementeerd met een duidelijk onderscheid tussen gebruiker en
administrator.
p. 73
Na het afronden van de ontwikkeling van de webapplicatie kreeg de administratie een
demonstratie. De administratie gaf de indruk zeer tevreden te zijn met het nieuwe systeem.
Na het implementeren van kleine aanpassingen, werd de opdracht dan ook als volbracht
beschouwd.
p. 74
5 Bibliografie
5.1 Boeken
De Tré, G. (2007). Principes van databases. Amsterdam: Pearson Education Benelux.
Naramore, E., Gerner, J., Le Scouarnec, Y., Stolz, J., & Glass, M. K. (2005). Beginning PHP5,
Apache and MySQL Web Development. Indianapolis, Indiana: Wiley Publishing Inc.
Valade, J., Ballad, T., & Ballad, B. (2008). PHP & MySQL Web Development All-in-one desk
reference for Dummies. Hoboken, NJ: Wiley Publishing Inc.
5.2 Rapporten
De Coninck, D., & Verhamme, W. (2009). Een webgebaseerd systeem voor het uitwisselen van.
Gent: Vakgroep Telecommunicatie en informatieverwerking.
5.3 Websites
Opgeroepen op mei 2010, van IETF: http://www.ietf.org/rfc/rfc3174.txt
Opgeroepen op mei 2010, van My SQL: http://www.mysql.com/
Opgeroepen op mei 2010, van phpMyAdmin:
http://www.phpmyadmin.net/home_page/index.php
(2008, 07 10). Opgeroepen op april 2010, van Jumba:
http://wiki.jumba.com.au/wiki/PHP_Generate_random_password
(2010). Opgeroepen op april 2010, van Microsoft: http://msdn.microsoft.com/en-
us/library/ms537505(v=VS.85).aspx
(2010). Opgeroepen op maart 2010, van PHP.NET: http://www.php.net/
p. 75
Mortimer, S. (2007, juli 14). Opgeroepen op mei 2010, van ezine:
http://ezinearticles.com/?JavaScript-for-Web-Design---Advantages-and-
Disadvantages&id=645013
PHP development 5. (2010). Opgeroepen op mei 2010, van http://forums.devshed.com/php-
development-5/validating-decimal-numbers-493154.html
Stewart, C. (2006, 1 3). Opgeroepen op mei 2010, van designerplayground:
http://www.designersplayground.com/articles/118/1/The-Advantages-of-PHP/Page1.html
W3Schools. (2010). Opgeroepen op mei 2010, van http://validator.w3.org/