]> git.imager.perl.org - bse.git/blame - site/cgi-bin/modules/DevHelp/Tags/Iterate.pm
Wishlists for BSE
[bse.git] / site / cgi-bin / modules / DevHelp / Tags / Iterate.pm
CommitLineData
9063386f
TC
1package DevHelp::Tags::Iterate;
2use strict;
3use Carp qw(confess);
4
5sub new {
6 my ($class, %opts) = @_;
7
8 return bless \%opts, $class;
9}
10
11sub escape {
12 return $_[1];
13}
14
d49667a2
TC
15sub next_item {
16}
17
9063386f 18sub _iter_reset_paged {
d7538448 19 my ($self, $rdata, $rindex, $rstore) = @_;
9063386f
TC
20
21 $$rindex = -1;
d7538448 22 undef $$rstore if $rstore;
9063386f
TC
23
24 1;
25}
26
27sub _iter_iterate {
d49667a2 28 my ($self, $rdata, $rindex, $rstore, $single) = @_;
9063386f 29
d7538448
TC
30 if (++$$rindex < @$rdata) {
31 $$rstore = $rdata->[$$rindex] if $rstore;
d49667a2 32 $self->next_item($rdata->[$$rindex], $single, $rdata, $$rindex);
d7538448
TC
33 return 1;
34 }
d49667a2
TC
35 else {
36 $self->next_item(undef, $single);
37 }
d7538448 38 return;
9063386f
TC
39}
40
c76e86ea
TC
41sub item {
42 my ($self, $entry, $args) = @_;
43
44 my $value = $entry->{$args};
45 defined $value or return '';
46
47 return $self->escape($value);
48}
49
9063386f
TC
50sub _iter_item {
51 my ($self, $rdata, $rindex, $single, $plural, $args) = @_;
52
53 $$rindex >= 0 && $$rindex < @$rdata
54 or return "** $single should only be used inside iterator $plural **";
af74f0b4 55
c76e86ea 56 return $self->item($rdata->[$$rindex], $args);
9063386f
TC
57}
58
59sub _iter_number_paged {
60 my ($self, $rindex, $baseindex) = @_;
61
62 $$rindex + $baseindex + 1;
63}
64
65sub _iter_reset_page_counter {
66 my ($self, $rpage) = @_;
67
68 $$rpage = 1;
69}
70
71sub _iter_iterate_page_counter {
72 my ($self, $rpage, $page_count) = @_;
73
74 ++$$rpage <= $page_count;
75}
76
77sub _iter_page_counter {
78 my ($self, $rpage) = @_;
79
80 $$rpage;
81}
82
83sub _iter_index {
84 my ($self, $rindex) = @_;
85
86 $$rindex;
87}
88
89sub _iter_if_first {
90 my ($self, $rindex) = @_;
91
92 $$rindex == 0;
93}
94
95sub _iter_if_last {
96 my ($self, $rdata, $rindex) = @_;
97
98 $$rindex == $#$rdata;
99}
100
70789617
TC
101sub _get_values {
102 my ($code, $args, $acts, $name, $templater) = @_;
103
104 my @args;
105 if (ref $code eq 'ARRAY') {
106 ($code, @args) = @$code;
107 }
108
109 if (ref $code) {
110 return $code->(@args, $args, $acts, $name, $templater);
111 }
112 else {
113 my $object = shift @args;
114 return $object->$code(@args, $args, $acts, $name, $templater);
115 }
116}
117
9063386f
TC
118sub make_paged_iterator {
119 my ($self, $single, $plural, $rdata, $rindex, $cgi, $pagename,
d7538448 120 $perpage_parm, $save, $get, $rstore) = @_;
9063386f 121
505456b1
TC
122 my ($def_per_page, $def_page_num);
123 if ($get) {
124 my ($code, @parms) = @$get;
125 ($def_per_page, $def_page_num) =
126 $code->(@parms);
127 }
9063386f
TC
128 my $index;
129 defined $rindex or $rindex = \$index;
130 $$rindex = -1;
131 $rdata or die;
132 my $loaded = 0;
133 my $max;
505456b1 134 my $perpage = ref $perpage_parm ? $$perpage_parm : $perpage_parm;
9063386f
TC
135 unless ($perpage =~ /^\d+$/) {
136 my ($name, $count) = $perpage =~ /^(\w+)=(\d+)$/
137 or confess "Invalid perpage '$perpage'";
138 $name ||= 'pp';
139 $count ||= 10;
140 my $work = $cgi->param($name);
dc040d12
TC
141 if (defined $work && $work =~ /^-?\d+$/ &&
142 (($work >= 1 && $work <= 1000) || $work == -1)) {
9063386f
TC
143 $perpage = $work;
144 }
145 else {
505456b1 146 $perpage = defined $def_per_page ? $def_per_page : $count;
9063386f 147 }
505456b1 148 $$perpage_parm =~ s/\d+/$perpage/ if ref $perpage_parm;
9063386f 149 }
dc040d12 150 my $page_count = $perpage == -1 ? 1 : int((@$rdata + $perpage - 1) / $perpage);
9063386f
TC
151 $page_count = 1 unless $page_count;
152 $pagename ||= 'p';
153 my $page_num = $cgi->param($pagename);
505456b1 154 defined $page_num or $page_num = $def_page_num;
9063386f
TC
155 unless (defined($page_num) && $page_num =~ /^\d+$/
156 && $page_num >= 1 && $page_num <= $page_count) {
157 $page_num = 1;
158 }
dc040d12
TC
159 my ($base_index, $end_index);
160 if ($perpage != -1) {
161 $base_index = $perpage * ($page_num - 1);
162 $end_index = $base_index + $perpage - 1;
163 $end_index <= $#$rdata or $end_index = $#$rdata;
164 }
165 else {
166 $base_index = 0;
167 $end_index = $#$rdata;
168 }
9063386f
TC
169 my @data;
170 @data = @$rdata[$base_index .. $end_index] if @$rdata;
171
505456b1
TC
172 if ($save) {
173 my ($code, @parms) = @$save;
174 $code->(@parms, $perpage, $page_num);
175 }
176
9063386f
TC
177 my $page_counter;
178
179 return
180 (
181 "iterate_${plural}_reset" =>
d7538448 182 [ _iter_reset_paged=>$self, \@data, $rindex, $rstore ],
9063386f 183 "iterate_${plural}" =>
d49667a2 184 [ _iter_iterate=>$self, \@data, $rindex, $rstore, $single ],
9063386f
TC
185 $single => [ _iter_item => $self, \@data, $rindex, $single, $plural ],
186 "if\u$plural" => scalar(@data),
187 "${single}_index" => [ _iter_index=>$self, $rindex ],
188 "${single}_number" => [ _iter_number_paged=>$self, $rindex, $base_index ],
189 "ifLast\u$single" => [ _iter_if_last=>$self, \@data, $rindex ],
190 "ifFirst\u$single" => [ _iter_if_first=>$self, $rindex ],
191 "ifNext\u${plural}\EPage" => $page_num < $page_count,
192 "ifPrev\u${plural}\EPage" => $page_num > 1,
193 "ifFirst\u${plural}\EPage" => $page_num == 1,
194 "ifLast\u${plural}\EPage" => $page_num == $page_count,
195 "next\u${plural}\EPage" =>
196 ( $page_num < $page_count ? $page_num + 1 : $page_num ),
197 "prev\u${plural}\EPage" =>
198 ( $page_num > 1 ? $page_num - 1 : 1 ),
199 "${single}_count" => scalar(@data),
200 "${plural}_pagenum" => $page_num,
201 "${plural}_pagecount" => $page_count,
202 "${single}_totalcount" => scalar(@$rdata),
203 "${plural}_firstnumber" => $base_index + 1,
204 "${plural}_lastnumber" => $end_index + 1,
205 "iterate_${single}_pages_reset" =>
206 [ _iter_reset_page_counter=>$self, \$page_counter ],
207 "iterate_${single}_pages" =>
208 [ _iter_iterate_page_counter=>$self, \$page_counter, $page_count ],
209 "${single}_pagecounter" =>
210 [ _iter_page_counter=>$self, \$page_counter ],
211 "${plural}_perpage" => $perpage,
62533efa
TC
212# "${plural}_pagelist" =>
213# [ _iter_pagelist => $self, $page_num, $page_count, $pagename ],
214# "${plural}_firstpage" =>
215# [ _iter_firstpage => $self, $page_num, $page_count, $pagename ],
216# "${plural}_backonepage" =>
217# [ _iter_backonepage => $self, $page_num, $page_count, $pagename ],
9063386f
TC
218 );
219}
220
221sub _iter_reset {
d7538448 222 my ($self, $rdata, $rindex, $code, $loaded, $nocache, $rstore,
9063386f
TC
223 $args, $acts, $name, $templater) = @_;
224
225 if (!$$loaded && !@$rdata && $code || $args || $nocache) {
70789617 226 @$rdata = _get_values($code, $args, $acts, $name, $templater);
9063386f
TC
227 ++$$loaded unless $args;
228 }
229
230 $$rindex = -1;
d7538448 231 undef $$rstore if $rstore;
9063386f
TC
232
233 1;
234}
235
236sub _iter_number {
237 my ($self, $rindex) = @_;
238
239 1+$$rindex;
240}
241
d49f56a6
TC
242sub _iter_count {
243 my ($self, $rdata, $code, $loaded, $nocache,
244 $args, $acts, $name, $templater) = @_;
245
246 if (!$$loaded && !@$rdata && $code || $args || $nocache) {
70789617 247 @$rdata = _get_values($code, $args, $acts, $name, $templater);
d49f56a6
TC
248 ++$$loaded unless $args;
249 }
250
251 scalar(@$rdata);
252}
253
9063386f 254sub make_iterator {
d7538448 255 my ($self, $code, $single, $plural, $rdata, $rindex, $nocache, $rstore) = @_;
9063386f
TC
256
257 my $index;
258 defined $rindex or $rindex = \$index;
259 $$rindex = -1;
260 $rdata ||= [];
261 my $loaded = 0;
262 return
263 (
264 "iterate_${plural}_reset" =>
d7538448 265 [ _iter_reset=>$self, $rdata, $rindex, $code, \$loaded, $nocache, $rstore ],
9063386f 266 "iterate_${plural}" =>
d49667a2 267 [ _iter_iterate=>$self, $rdata, $rindex, $rstore, $single ],
9063386f
TC
268 $single =>
269 [ _iter_item=>$self, $rdata, $rindex, $single, $plural ],
270 "${single}_index" => [ _iter_index=>$self, $rindex ],
271 "${single}_number" => [ _iter_number =>$self, $rindex ],
272 "if\u$plural" =>
273 [ _iter_count=>$self, $rdata, $code, \$loaded, $nocache ],
274 "${single}_count" =>
275 [ _iter_count=>$self, $rdata, $code, \$loaded, $nocache ],
276 "ifLast\u$single" => [ _iter_if_last=>$self, $rdata, $rindex ],
277 "ifFirst\u$single" => [ _iter_if_first=>$self, $rindex ],
278 );
279}
280
2811;