Pagination script
Vandaag heb ik mijn eerste OOP script geschreven.
Zouden jullie mij feedback kunnen geven op de code? Is het misschien iets voor in het script library?
Hier is het script
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
<?php
class Pagination {
/*
usage:
$pagination = new Pagination($qry, "index.php?page=overzicht", $itemsPerPage, $numbersLeftNav);
options
$pagination->firstLabel = '<< eerste';
$pagination->prevLabel = '< vorige';
$pagination->nextLabel = 'volgende >';
$pagination->lastLabel = 'laatste >>';
render each item
echo $pagination->renderFirst().' ';
echo $pagination->renderPrev().' ';
foreach($pagination->renderLeftNav() as $key => $val) {
echo $val.' ';
}
echo $pagination->renderCurrentNav().' ';
foreach($pagination->renderRightNav() as $key => $val) {
echo $val.' ';
}
echo $pagination->renderNext().' ';
echo $pagination->renderLast();
or render all items
echo $pagination->render();
foreach ($pagination->getRecords() as $key => $row) {
echo strip($row["naam"]);
}
*/
public $firstLabel = '<< first';
public $lastLabel = 'last >>';
public $nextLabel = 'volgende >';
public $prevLabel = '< vorige';
protected $_sql = '';
protected $_itemsPerPage = '';
protected $_allRecords = '';
protected $_allPages = '';
protected $_append = ''; // items in the nav on the left and right from the current
protected $_currentPage = '';
public function __construct($_sql, $_self, $_items_per_page = 10, $_append = 3) {
$this->_sql = $_sql;
$this->_self = $_self;
$this->_itemsPerPage = $_items_per_page;
$this->_append = $_append;
if (!isset($_GET["pagination"]) || (isset($_GET["pagination"]) && !is_numeric($_GET["pagination"]))) {
if (preg_match("/\?/", $this->_self)) {
header("Location: ".$this->_self."&pagination=1&limit=".$this->_itemsPerPage);
}
else {
header("Location: ".$this->_self."?pagination=1&limit=".$this->_itemsPerPage);
}
}
else {
$this->_currentPage = $_GET["pagination"];
}
}
protected function database() {
include '../inc/connect.php';
$output = array();
$sql = $this->_sql;
$all_records = $db->query($sql);
if ($all_records == TRUE) {
$this->_allRecords = $all_records->num_rows;
$this->_allPages = ceil($this->_allRecords / $this->_itemsPerPage);
}
else {
return 'Error: '.$db->error;
}
$start = $this->_currentPage * $this->_itemsPerPage - $this->_itemsPerPage;
$sql .= "LIMIT ".$start.", ".$this->_itemsPerPage;
$sql = $db->query($sql);
if ($sql == TRUE) {
while ($row = mysqli_fetch_assoc($sql)) {
$output[] = $row;
}
return $output;
}
else {
return 'Error: '.$db->error;
}
}
public function renderFirst() {
if ($this->_currentPage != 1) {
return '<a href="'.$this->_self.'&pagination=1&limit='.$this->_itemsPerPage.'">'.$this->firstLabel.'</a>';
}
}
public function renderPrev() {
$prev = $this->_currentPage - 1;
if ($prev != 0) {
return '<a href="'.$this->_self.'&pagination='.$prev.'&limit='.$this->_itemsPerPage.'">'.$this->prevLabel.'</a>';
}
}
public function renderLeftNav() {
$this->database();
$current = $this->_currentPage;
$navLeft = array();
if ($this->_currentPage > 1) {
$i = 0;
while($i != $this->_append) {
$i++;
$current--;
if ($current >= 1) {
$navLeft[] = '<a href="'.$this->_self.'&pagination='.$current.'&limit='.$this->_itemsPerPage.'">'.$current.'</a>';
}
}
asort($navLeft);
}
return $navLeft;
}
public function renderCurrentNav() {
return $this->_currentPage; // output current page
}
public function renderRightNav() {
$this->database();
$current = $this->_currentPage;
$navRight = array();
if ($this->_currentPage < $this->_allPages) {
$i = 0;
while($i != $this->_append) {
$i++;
$current++;
if (($current -1) != $this->_allPages && ($current -1) < $this->_allPages) {
$navRight[] = '<a href="'.$this->_self.'&pagination='.$current.'&limit='.$this->_itemsPerPage.'">'.$current.'</a>';
}
}
}
return $navRight;
}
public function renderNext() {
$next = $this->_currentPage + 1;
if (($next - 1) != $this->_allPages) {
return '<a href="'.$this->_self.'&pagination='.$next.'&limit='.$this->_itemsPerPage.'">'.$this->nextLabel.'</a>';
}
}
public function renderLast() {
if ($this->_currentPage != $this->_allPages) {
return '<a href="'.$this->_self.'&pagination='.$this->_allPages.'&limit='.$this->_itemsPerPage.'">'.$this->lastLabel.'</a>';
}
}
public function getRecords() {
return $this->database();
}
public function render() {
$output = '';
$output .= $this->renderFirst().' ';
$output .= $this->renderPrev().' ';
foreach($this->renderLeftNav() as $key => $val) {
if ($val <= $this->_allPages) {
$output .= $val.' ';
}
}
$output .= $this->renderCurrentNav();
foreach($this->renderRightNav() as $key => $val) {
if ($val <= $this->_allPages) {
$output .= ' '.$val;
}
}
$output .= ' '.$this->renderNext().' ';
$output .= $this->renderLast();
return $output;
}
}
?>
class Pagination {
/*
usage:
$pagination = new Pagination($qry, "index.php?page=overzicht", $itemsPerPage, $numbersLeftNav);
options
$pagination->firstLabel = '<< eerste';
$pagination->prevLabel = '< vorige';
$pagination->nextLabel = 'volgende >';
$pagination->lastLabel = 'laatste >>';
render each item
echo $pagination->renderFirst().' ';
echo $pagination->renderPrev().' ';
foreach($pagination->renderLeftNav() as $key => $val) {
echo $val.' ';
}
echo $pagination->renderCurrentNav().' ';
foreach($pagination->renderRightNav() as $key => $val) {
echo $val.' ';
}
echo $pagination->renderNext().' ';
echo $pagination->renderLast();
or render all items
echo $pagination->render();
foreach ($pagination->getRecords() as $key => $row) {
echo strip($row["naam"]);
}
*/
public $firstLabel = '<< first';
public $lastLabel = 'last >>';
public $nextLabel = 'volgende >';
public $prevLabel = '< vorige';
protected $_sql = '';
protected $_itemsPerPage = '';
protected $_allRecords = '';
protected $_allPages = '';
protected $_append = ''; // items in the nav on the left and right from the current
protected $_currentPage = '';
public function __construct($_sql, $_self, $_items_per_page = 10, $_append = 3) {
$this->_sql = $_sql;
$this->_self = $_self;
$this->_itemsPerPage = $_items_per_page;
$this->_append = $_append;
if (!isset($_GET["pagination"]) || (isset($_GET["pagination"]) && !is_numeric($_GET["pagination"]))) {
if (preg_match("/\?/", $this->_self)) {
header("Location: ".$this->_self."&pagination=1&limit=".$this->_itemsPerPage);
}
else {
header("Location: ".$this->_self."?pagination=1&limit=".$this->_itemsPerPage);
}
}
else {
$this->_currentPage = $_GET["pagination"];
}
}
protected function database() {
include '../inc/connect.php';
$output = array();
$sql = $this->_sql;
$all_records = $db->query($sql);
if ($all_records == TRUE) {
$this->_allRecords = $all_records->num_rows;
$this->_allPages = ceil($this->_allRecords / $this->_itemsPerPage);
}
else {
return 'Error: '.$db->error;
}
$start = $this->_currentPage * $this->_itemsPerPage - $this->_itemsPerPage;
$sql .= "LIMIT ".$start.", ".$this->_itemsPerPage;
$sql = $db->query($sql);
if ($sql == TRUE) {
while ($row = mysqli_fetch_assoc($sql)) {
$output[] = $row;
}
return $output;
}
else {
return 'Error: '.$db->error;
}
}
public function renderFirst() {
if ($this->_currentPage != 1) {
return '<a href="'.$this->_self.'&pagination=1&limit='.$this->_itemsPerPage.'">'.$this->firstLabel.'</a>';
}
}
public function renderPrev() {
$prev = $this->_currentPage - 1;
if ($prev != 0) {
return '<a href="'.$this->_self.'&pagination='.$prev.'&limit='.$this->_itemsPerPage.'">'.$this->prevLabel.'</a>';
}
}
public function renderLeftNav() {
$this->database();
$current = $this->_currentPage;
$navLeft = array();
if ($this->_currentPage > 1) {
$i = 0;
while($i != $this->_append) {
$i++;
$current--;
if ($current >= 1) {
$navLeft[] = '<a href="'.$this->_self.'&pagination='.$current.'&limit='.$this->_itemsPerPage.'">'.$current.'</a>';
}
}
asort($navLeft);
}
return $navLeft;
}
public function renderCurrentNav() {
return $this->_currentPage; // output current page
}
public function renderRightNav() {
$this->database();
$current = $this->_currentPage;
$navRight = array();
if ($this->_currentPage < $this->_allPages) {
$i = 0;
while($i != $this->_append) {
$i++;
$current++;
if (($current -1) != $this->_allPages && ($current -1) < $this->_allPages) {
$navRight[] = '<a href="'.$this->_self.'&pagination='.$current.'&limit='.$this->_itemsPerPage.'">'.$current.'</a>';
}
}
}
return $navRight;
}
public function renderNext() {
$next = $this->_currentPage + 1;
if (($next - 1) != $this->_allPages) {
return '<a href="'.$this->_self.'&pagination='.$next.'&limit='.$this->_itemsPerPage.'">'.$this->nextLabel.'</a>';
}
}
public function renderLast() {
if ($this->_currentPage != $this->_allPages) {
return '<a href="'.$this->_self.'&pagination='.$this->_allPages.'&limit='.$this->_itemsPerPage.'">'.$this->lastLabel.'</a>';
}
}
public function getRecords() {
return $this->database();
}
public function render() {
$output = '';
$output .= $this->renderFirst().' ';
$output .= $this->renderPrev().' ';
foreach($this->renderLeftNav() as $key => $val) {
if ($val <= $this->_allPages) {
$output .= $val.' ';
}
}
$output .= $this->renderCurrentNav();
foreach($this->renderRightNav() as $key => $val) {
if ($val <= $this->_allPages) {
$output .= ' '.$val;
}
}
$output .= ' '.$this->renderNext().' ';
$output .= $this->renderLast();
return $output;
}
}
?>
Bedankt alvast!
Gewijzigd op 10/11/2012 01:12:40 door Joost van der Meijden
Script: https://github.com/EllisLab/CodeIgniter/blob/develop/system/libraries/Pagination.php
Uitleg: http://codeigniter.com/user_guide/libraries/pagination.html
http://framework.zend.com/manual/2.0/en/modules/zend.paginator.introduction.html En YII, Lithium, ect. zullen ze ook wel hebben.
Hij vraagt of zijn script goed is, niet of je een andere Paginator weet...
Joost, het is een leuke klasse, maar heeft nu nog niks met OO te maken. In OO is er 1 belangrijke regel waarin je je altijd moet houden: Elke klasse en elke method heeft maar 1 verantwoordelijkheid, zijn er meerdere dan splits je hem op. Je Paginator klasse heeft nu enorm veel verantwoordelijkheden: Hij maakt connectie met database, houdt items vast, zorgt voor het renderen, zorgt voor de pagination, ect. Dat moet allemaal in een eigen klasse gedaan worden.
Nu heeft Pim een tijdje geleden een erg mooi opzetje gemaakt voor een Paginator in OO. Kijk eens naar dat opzetje, of je het begrijpt en of je hem af kunt maken: http://www.phphulp.nl/php/forum/topic/paginering-oop/84869/#605327 (eventuele uitleg)
Maar ook Zend Framework heeft een paginator: Hij vraagt of zijn script goed is, niet of je een andere Paginator weet...
Joost, het is een leuke klasse, maar heeft nu nog niks met OO te maken. In OO is er 1 belangrijke regel waarin je je altijd moet houden: Elke klasse en elke method heeft maar 1 verantwoordelijkheid, zijn er meerdere dan splits je hem op. Je Paginator klasse heeft nu enorm veel verantwoordelijkheden: Hij maakt connectie met database, houdt items vast, zorgt voor het renderen, zorgt voor de pagination, ect. Dat moet allemaal in een eigen klasse gedaan worden.
Nu heeft Pim een tijdje geleden een erg mooi opzetje gemaakt voor een Paginator in OO. Kijk eens naar dat opzetje, of je het begrijpt en of je hem af kunt maken: http://www.phphulp.nl/php/forum/topic/paginering-oop/84869/#605327 (eventuele uitleg)
@Wouter, ik kan wel kijken naar het script, maar ik snap dat abastract en implements nog niet helemaal.
Ik zal er nog wat op door moeten leren voordat ik het OOP goed begrijp, het is allemaal nog een beetje onduidelijk voor me, vind het ook best moeilijk om te snappen moet ik eerlijk zeggen.
Maargoed, komt vast goed, blijven oefenen en lezen :D
Iemand misschien nog wat goed materiaal? Boek, tutorials of wat dan ook?
Gewijzigd op 10/11/2012 13:18:45 door Joost van der Meijden
http://net.tutsplus.com/tutorials/php/object-oriented-php-for-beginners/
http://net.tutsplus.com/tutorials/php/oop-in-php/
http://net.tutsplus.com/tutorials/php/real-world-oop-with-php-and-mysql/
Ondertussen ben ik een boek aan het doornemen wat ik van een collega heb gekregen. Het boek gaat over het object georiënteerd programmeren in de taal Java.
Dit is de code die ik tot nu toe heb voor het maken van de Database class:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php
class Database {
private $_db;
private $_host;
private $_user;
private $_password;
private $_dbName;
protected $_result;
protected $_qry;
protected $_qryArray = array();
/*
Construct and optionally connect to database
*/
public function __construct($_CONFIG) {
if (isset($_CONFIG["db"]["connect"]) && extract($_CONFIG["db"]["connect"])) {
$this->_host = $host;
$this->_user = $user;
$this->_password = $password;
$this->_dbName = $db;
}
$this->_connect();
}
/*
connect to database and use parameters from class
*/
private function _connect() {
$this->_db = mysqli_connect($this->_host, $this->_user, $this->_password, $this->_dbName);
if (!$db->connect_errno) {
return TRUE;
}
}
/*
escapes string if magic quotes = off
@return string escaped string
*/
private function _add($string) {
if (get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
if (!is_numeric($string) && !preg_match("/{(.*?)}/", $string)) {
$string = "'".mysqli_real_escape_string($this->_db, $string)."'";
}
if (preg_match("/{(.*?)}/", $string)) {
$string = mysqli_real_escape_string($this->_db, $string);
}
return $string;
}
/*
Sets Query parameters
@param $qry SQL
@sets var qry
@sets array qryArray
*/
public function setQry($qry) {
$this->_qryArray = array();
$arg_list = func_get_args();
for ($i = 0; $i < func_num_args(); $i++) {
if ($i == 0) {
$this->_qry = $arg_list[$i];
}
else {
$this->_qryArray[] = $this->_add($arg_list[$i]);
}
}
$this->_query();
}
/*
Gets parameters and make nice Query
@sets var qry
*/
private function getQry() {
foreach ($this->_qryArray as $name => $val) {
$this->_qry = preg_replace("/\?/", $val, $this->_qry, 1);
}
$this->_qry = preg_replace("/{(.*?)}/", "\$1", $this->_qry, -1);
}
/*
excecutes query
*/
private function _query() {
$this->getQry();
$this->_result = $this->_db->query($this->_qry);
if ($this->_result == FALSE) {
trigger_error("Error: ".$this->_db->error);
}
}
/*
Get single result [SQL: LIMIT 0, 1]
@param $qry SQL
@return string $rows => all rows
*/
public function getRow() {
return mysqli_fetch_assoc($this->_result);
}
/*
Get several rows from database
@param $qry SQL
@return array $rows => all rows
*/
public function getRows() {
while ($rows = mysqli_fetch_assoc($this->_result)) {
$row[] = $rows;
}
return $row;
}
/*
Get num rows from last query
@return int num_rows
*/
public function numRows() {
return $this->_result->num_rows;
}
/*
Get num rows from last query
@return int num_rows
*/
public function affectedRows() {
return $this->_db->affected_rows;
}
}
?>
class Database {
private $_db;
private $_host;
private $_user;
private $_password;
private $_dbName;
protected $_result;
protected $_qry;
protected $_qryArray = array();
/*
Construct and optionally connect to database
*/
public function __construct($_CONFIG) {
if (isset($_CONFIG["db"]["connect"]) && extract($_CONFIG["db"]["connect"])) {
$this->_host = $host;
$this->_user = $user;
$this->_password = $password;
$this->_dbName = $db;
}
$this->_connect();
}
/*
connect to database and use parameters from class
*/
private function _connect() {
$this->_db = mysqli_connect($this->_host, $this->_user, $this->_password, $this->_dbName);
if (!$db->connect_errno) {
return TRUE;
}
}
/*
escapes string if magic quotes = off
@return string escaped string
*/
private function _add($string) {
if (get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
if (!is_numeric($string) && !preg_match("/{(.*?)}/", $string)) {
$string = "'".mysqli_real_escape_string($this->_db, $string)."'";
}
if (preg_match("/{(.*?)}/", $string)) {
$string = mysqli_real_escape_string($this->_db, $string);
}
return $string;
}
/*
Sets Query parameters
@param $qry SQL
@sets var qry
@sets array qryArray
*/
public function setQry($qry) {
$this->_qryArray = array();
$arg_list = func_get_args();
for ($i = 0; $i < func_num_args(); $i++) {
if ($i == 0) {
$this->_qry = $arg_list[$i];
}
else {
$this->_qryArray[] = $this->_add($arg_list[$i]);
}
}
$this->_query();
}
/*
Gets parameters and make nice Query
@sets var qry
*/
private function getQry() {
foreach ($this->_qryArray as $name => $val) {
$this->_qry = preg_replace("/\?/", $val, $this->_qry, 1);
}
$this->_qry = preg_replace("/{(.*?)}/", "\$1", $this->_qry, -1);
}
/*
excecutes query
*/
private function _query() {
$this->getQry();
$this->_result = $this->_db->query($this->_qry);
if ($this->_result == FALSE) {
trigger_error("Error: ".$this->_db->error);
}
}
/*
Get single result [SQL: LIMIT 0, 1]
@param $qry SQL
@return string $rows => all rows
*/
public function getRow() {
return mysqli_fetch_assoc($this->_result);
}
/*
Get several rows from database
@param $qry SQL
@return array $rows => all rows
*/
public function getRows() {
while ($rows = mysqli_fetch_assoc($this->_result)) {
$row[] = $rows;
}
return $row;
}
/*
Get num rows from last query
@return int num_rows
*/
public function numRows() {
return $this->_result->num_rows;
}
/*
Get num rows from last query
@return int num_rows
*/
public function affectedRows() {
return $this->_db->affected_rows;
}
}
?>
en dan uiteraard het index.php bestand
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
include 'class/config.php';
include 'class/database.class.php';
?>
<h1>Home</h1>
<?php
$db = new Database($_CONFIG);
$db->setQry("SELECT * FROM gebruikers ORDER BY ? ASC", "{voornaam}");
$rows = $db->getRows();
echo 'Aantal records: '.$db->numRows().'<br />';
foreach ($rows as $row) {
echo $row["voornaam"].' '.$row["achternaam"].' - '.$row["email"].'<br />';
}
echo '<hr />';
$sql = "SELECT * FROM gebruikers WHERE id = ? AND achternaam = ?";
$id = 4;
$achternaam = "van der Test";
$db->setQry($sql, $id, $achternaam);
$row = $db->getRow();
echo $row["voornaam"];
echo '<hr />';
$test = "test van der Test";
$db->setQry("UPDATE gebruikers SET naam = 'test van der Test' WHERE naam = ?", $test);
echo 'Affected rows: '.$db->affectedRows();
?>
include 'class/config.php';
include 'class/database.class.php';
?>
<h1>Home</h1>
<?php
$db = new Database($_CONFIG);
$db->setQry("SELECT * FROM gebruikers ORDER BY ? ASC", "{voornaam}");
$rows = $db->getRows();
echo 'Aantal records: '.$db->numRows().'<br />';
foreach ($rows as $row) {
echo $row["voornaam"].' '.$row["achternaam"].' - '.$row["email"].'<br />';
}
echo '<hr />';
$sql = "SELECT * FROM gebruikers WHERE id = ? AND achternaam = ?";
$id = 4;
$achternaam = "van der Test";
$db->setQry($sql, $id, $achternaam);
$row = $db->getRow();
echo $row["voornaam"];
echo '<hr />';
$test = "test van der Test";
$db->setQry("UPDATE gebruikers SET naam = 'test van der Test' WHERE naam = ?", $test);
echo 'Affected rows: '.$db->affectedRows();
?>
Ik hoop dat het er nu al wat meer op lijkt, het ziet er misschien simpel uit maar ben er best lang mee bezig geweest.
Hopelijk hebben jullie weer wat feedback waarmee ik mezelf kan verbeteren :)
Gewijzigd op 19/11/2012 18:55:46 door Joost van der Meijden
Gewijzigd op 19/11/2012 18:54:14 door Joost van der Meijden