Pagination class review?
Hoe gebruik je de class:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
echo new Pagination(array(
'current' => 1, // De currente pagina (default = 1)
'total' => 25, // Het aantal items (default = 0)
'count' => 5, // Het aantal items per pagina (default = 5)
'pages' => 3, // Het aantal pagina's in de pagination (default = 3)
));
// Output
// <ul class="pagination">
// <li class="prev"><span>« Vorige</span></li>
// <li class="active"><span>1</span></li>
// <li><a href="test.html" title="2">2</a></li>
// <li><a href="test.html" title="3">3</a></li>
// <li class="next"><a href="test.html" title="Volgende »">Volgende »</a></li>
//</ul>
?>
echo new Pagination(array(
'current' => 1, // De currente pagina (default = 1)
'total' => 25, // Het aantal items (default = 0)
'count' => 5, // Het aantal items per pagina (default = 5)
'pages' => 3, // Het aantal pagina's in de pagination (default = 3)
));
// Output
// <ul class="pagination">
// <li class="prev"><span>« Vorige</span></li>
// <li class="active"><span>1</span></li>
// <li><a href="test.html" title="2">2</a></li>
// <li><a href="test.html" title="3">3</a></li>
// <li class="next"><a href="test.html" title="Volgende »">Volgende »</a></li>
//</ul>
?>
De 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
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
189
190
191
192
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
189
190
191
192
<?php
namespace Library\Framework\Pagination;
class Pagination {
/**
* @acces protected.
* @var integer.
*/
protected $template = array(
'wrapper' => '<ul class="pagination">{$pagination}</ul>',
'prev' => '<li class="prev"><a href="{$link}" title="« Vorige">« Vorige</a></li>',
'prevDisabled' => '<li class="prev"><span>« Vorige</span></li>',
'next' => '<li class="next"><a href="{$link}" title="Volgende »">Volgende »</a></li>',
'nextDisabled' => '<li class="next"><span>Volgende »</span></li>',
'page' => '<li><a href="{$link}" title="{$title}">{$title}</a></li>',
'pageActive' => '<li class="active"><span>{$title}</span></li>'
);
/**
* @acces protected.
* @var integer.
*/
protected $current = 1;
/**
* @acces protected.
* @var integer.
*/
protected $total = 0;
/**
* @acces protected.
* @var integer.
*/
protected $count = 5;
/**
* @acces protected.
* @var integer.
*/
protected $pages = 3;
/**
* @acces public.
* @param null|array $configuration.
*/
public function __construct($configuration = null) {
$this->setConfiguration($configuration);
}
/**
* @acces public.
* @param null|array $configuration.
* @throws InvalidArgumentException.
* @return self.
*/
protected function setConfiguration($configuration) {
if (!is_array($configuration)) {
throw new Exception\InvalidArgumentException(sprintf('Failed to initialize %s, configuration is not an array; recieved "%s".', __CLASS__, gettype($configuration)));
} else {
foreach ($configuration as $name => $config) {
switch (strtolower($name)) {
case 'template':
unset($configuration[$name]);
$this->setTemplate($config, $configuration);
break;
case 'current':
unset($configuration[$name]);
$this->setCurrent($config, $configuration);
break;
case 'total':
unset($configuration[$name]);
$this->setTotal($config, $configuration);
break;
case 'count':
unset($configuration[$name]);
$this->setCount($config, $configuration);
break;
case 'pages':
unset($configuration[$name]);
$this->setPages($config, $configuration);
break;
}
}
}
}
/**
* @acces protected.
* @param array $template.
* @reutrn self.
*/
public function setTemplate($template) {
$this->template = array_merge($this->template, $template);
}
/**
* @acces protected.
* @param integer|string $current.
* @return self.
*/
public function setCurrent($current) {
$this->current = $current;
return $this;
}
/**
* @acces protected.
* @param integer|string $total.
* @return self.
*/
public function setTotal($total) {
$this->total = $total;
return $this;
}
/**
* @acces protected.
* @param integer|string $count.
* @return self.
*/
public function setCount($count) {
$this->count = $count;
return $this;
}
/**
* @acces protected.
* @param integer|string $pages.
* @return self.
*/
public function setPages($pages) {
$this->pages = $pages;
return $this;
}
/**
* @acces protected.
* @return array.
*/
protected function calculatePages() {
if (0 >= $this->current - (($this->pages - 1) / 2)) {
$start = 0;
$end = $this->pages;
} else if (ceil($this->total / $this->count) <= $this->current + (($this->pages - 1) / 2)) {
$start = ceil($this->total / $this->count) - $this->pages;
$end = ceil($this->total / $this->count);
} else {
$start = $this->current - (($this->pages - 1) / 2);
$end = $this->current + (($this->pages - 1) / 2);
}
if ($end > ceil($this->total / $this->count)) {
$end = ceil($this->total / $this->count);
}
return array($start, $end);
}
/**
* @acces protected.
* @return string.
*/
protected function generate() {
list($start, $end) = $this->calculatePages();
$pagination = array();
$pagination[] = str_replace('{$link}', 'test.html', 0 === $start ? $this->template['prevDisabled'] : $this->template['prev']);
for ($i = $start + 1; $i <= $end; $i++) {
$pagination[] = str_replace(array('{$link}', '{$title}'), array('test.html', $i), $i == $this->current ? $this->template['pageActive'] : $this->template['page']);
}
$pagination[] = str_replace('{$link}', 'test.html', ceil($this->total / $this->count) === $end ? $this->template['nextDisabled'] : $this->template['next']);
return str_replace('{$pagination}', implode(PHP_EOL, $pagination), $this->template['wrapper']);
}
/**
* @acces public.
* @return string.
*/
public function __toString() {
return $this->generate();
}
}
?>
namespace Library\Framework\Pagination;
class Pagination {
/**
* @acces protected.
* @var integer.
*/
protected $template = array(
'wrapper' => '<ul class="pagination">{$pagination}</ul>',
'prev' => '<li class="prev"><a href="{$link}" title="« Vorige">« Vorige</a></li>',
'prevDisabled' => '<li class="prev"><span>« Vorige</span></li>',
'next' => '<li class="next"><a href="{$link}" title="Volgende »">Volgende »</a></li>',
'nextDisabled' => '<li class="next"><span>Volgende »</span></li>',
'page' => '<li><a href="{$link}" title="{$title}">{$title}</a></li>',
'pageActive' => '<li class="active"><span>{$title}</span></li>'
);
/**
* @acces protected.
* @var integer.
*/
protected $current = 1;
/**
* @acces protected.
* @var integer.
*/
protected $total = 0;
/**
* @acces protected.
* @var integer.
*/
protected $count = 5;
/**
* @acces protected.
* @var integer.
*/
protected $pages = 3;
/**
* @acces public.
* @param null|array $configuration.
*/
public function __construct($configuration = null) {
$this->setConfiguration($configuration);
}
/**
* @acces public.
* @param null|array $configuration.
* @throws InvalidArgumentException.
* @return self.
*/
protected function setConfiguration($configuration) {
if (!is_array($configuration)) {
throw new Exception\InvalidArgumentException(sprintf('Failed to initialize %s, configuration is not an array; recieved "%s".', __CLASS__, gettype($configuration)));
} else {
foreach ($configuration as $name => $config) {
switch (strtolower($name)) {
case 'template':
unset($configuration[$name]);
$this->setTemplate($config, $configuration);
break;
case 'current':
unset($configuration[$name]);
$this->setCurrent($config, $configuration);
break;
case 'total':
unset($configuration[$name]);
$this->setTotal($config, $configuration);
break;
case 'count':
unset($configuration[$name]);
$this->setCount($config, $configuration);
break;
case 'pages':
unset($configuration[$name]);
$this->setPages($config, $configuration);
break;
}
}
}
}
/**
* @acces protected.
* @param array $template.
* @reutrn self.
*/
public function setTemplate($template) {
$this->template = array_merge($this->template, $template);
}
/**
* @acces protected.
* @param integer|string $current.
* @return self.
*/
public function setCurrent($current) {
$this->current = $current;
return $this;
}
/**
* @acces protected.
* @param integer|string $total.
* @return self.
*/
public function setTotal($total) {
$this->total = $total;
return $this;
}
/**
* @acces protected.
* @param integer|string $count.
* @return self.
*/
public function setCount($count) {
$this->count = $count;
return $this;
}
/**
* @acces protected.
* @param integer|string $pages.
* @return self.
*/
public function setPages($pages) {
$this->pages = $pages;
return $this;
}
/**
* @acces protected.
* @return array.
*/
protected function calculatePages() {
if (0 >= $this->current - (($this->pages - 1) / 2)) {
$start = 0;
$end = $this->pages;
} else if (ceil($this->total / $this->count) <= $this->current + (($this->pages - 1) / 2)) {
$start = ceil($this->total / $this->count) - $this->pages;
$end = ceil($this->total / $this->count);
} else {
$start = $this->current - (($this->pages - 1) / 2);
$end = $this->current + (($this->pages - 1) / 2);
}
if ($end > ceil($this->total / $this->count)) {
$end = ceil($this->total / $this->count);
}
return array($start, $end);
}
/**
* @acces protected.
* @return string.
*/
protected function generate() {
list($start, $end) = $this->calculatePages();
$pagination = array();
$pagination[] = str_replace('{$link}', 'test.html', 0 === $start ? $this->template['prevDisabled'] : $this->template['prev']);
for ($i = $start + 1; $i <= $end; $i++) {
$pagination[] = str_replace(array('{$link}', '{$title}'), array('test.html', $i), $i == $this->current ? $this->template['pageActive'] : $this->template['page']);
}
$pagination[] = str_replace('{$link}', 'test.html', ceil($this->total / $this->count) === $end ? $this->template['nextDisabled'] : $this->template['next']);
return str_replace('{$pagination}', implode(PHP_EOL, $pagination), $this->template['wrapper']);
}
/**
* @acces public.
* @return string.
*/
public function __toString() {
return $this->generate();
}
}
?>
Hoe zou deze class het beste te gebruiken zijn dan?
Nou dat spreekt toch voor zich of ligt dat aan mij?
Op L59 zie ik 'Exception\InvalidArgumentException', als het goed is zit die exception al standaard bij PHP of SPL, dan hoef je enkel \InvalidArgumentException te gebruiken. (correct me if i'm wrong).
Dus:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
+ Library
+ Pagination
+ Exception
ExceptionInterface
InvalidArgumentException.php
Pagination.php
+ Pagination
+ Exception
ExceptionInterface
InvalidArgumentException.php
Pagination.php
Gewijzigd op 08/02/2013 22:55:41 door Joakim Broden
Ja, maar wat ik probeer duidelijk maken is dat SPL of PHP die exception al standaard heeft ingebouwd waardoor je die exception niet opnieuw moet maken. Dus gewoon callen met \InvalidArgumentException.
Raoul, dit wordt juist wel vaak gedaan. Wat je vaak ziet is dat mensen de exceptions gaan vervangen door specifiekere exceptions, of gewoon de exceptions overplaatsen. Dit wordt gezien als een best practise. In Symfony2 is er zelfs een bundle, JmsCommandsBundle, welke dit automatisch voor je doet.
Ah, dat wist ik nog niet. Maar waarom zou zo'n aparte class betere practice zijn terwijl PHP dit al ingebouwd heeft?
Aangezien je dan specifiek weet in welk deel van je applicatie een bepaalde exception optreedt.
- Doe geen configuratie settings doormiddel van arrays. Gebruik hiervoor setters/getters en eventueel maak je in de constructor gebruik van parameters die deze instellen.
- Kijken of een parameter een array is zou ik eerder doen met setConfiguration(array $configuration) dan met zo'n if die jij nu hebt
- Je herhaalt telkens dezelfde code voor elke case in setConfiguration. Je kunt deze dus beter uit de cases halen, om code duplication te voorkomen.
- Je klasse heeft nu veel te veel verantwoordelijkheden. Schrijf ze eens allemaal op een papiertje, knip vervolgens dat papiertje in stukken zodat op elk stuk 1 verantwoordelijkheid staat en zie nu elk stuk papier als 1 klasse. Ga dan verder uitdenken hoe je die klasse het beste kunt indelen.
- Behalve werken met magics zou ik ook altijd een method beschikbaar maken.
- Even een grote contradictie de wereld uithelpen: Library\Framework Een library is een set met functies en een framework is meerdere libraries gekoppeld waardoor je al een enorme basis voor elke website hebt.
Ik raad je aan je te houden aan de PSR-0 standaard en dus <vendor>\<project>\<component...>\<class> te gebruiken.